apm_package_install (public)
apm_package_install [ -enable ] [ -callback callback ] \ [ -load_data_model ] [ -install_from_repository ] \ [ -data_model_files data_model_files ] \ [ -package_path package_path ] [ -mount_path mount_path ] \ spec_file_path
Defined in packages/acs-tcl/tcl/apm-install-procs.tcl
Registers a new package and/or version in the database, returning the version_id. If $callback is provided, periodically invokes this procedure with a single argument containing a human-readable (English) status message.
- Switches:
- -enable (optional, boolean)
- -callback (optional, defaults to
"apm_dummy_callback"
)- -load_data_model (optional, boolean)
- -install_from_repository (optional, boolean)
- -data_model_files (optional, defaults to
"0"
)- -package_path (optional)
- -mount_path (optional)
- Parameters:
- spec_file_path (required)
- The path to an XML .info file relative to
- Returns:
- The version_id if successfully installed, 0 otherwise.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- upgrade
Source code: set version_id 0 array set version [apm_read_package_info_file $spec_file_path] set package_key $version(package.key) set version_name $version(name) # Determine if we are upgrading or installing. set upgrade_from_version_name [apm_package_upgrade_from $package_key $version(name)] if {$upgrade_from_version_name ne "" && $upgrade_from_version_name eq $version_name} { # # nothing to do. # ns_log notice "apm_package_install package $package_key already installed in version $version_name" return [apm_version_id_from_package_key $package_key] } set upgrade_p [expr {$upgrade_from_version_name ne ""}] if {$upgrade_p} { set operations {Upgrading Upgraded} } else { set operations {Installing Installed} } apm_callback_and_log $callback "<h3>[lindex $operations 0] $version(package-name) $version(name)</h3>" if { [string match "[apm_workspace_install_dir]*" $package_path] } { # Package is being installed from the apm_workspace dir (expanded from .apm file) # Backup any existing (old) package in packages dir first set old_package_path [acs_package_root_dir $package_key] if { [ad_file exists $old_package_path] } { util::backup_file -file_path $old_package_path } # Move the package into the packages dir file rename -- $package_path $::acs::rootdir/packages # We moved the spec file, so update its path set package_path $old_package_path set spec_file_path [apm_package_info_file_path -path [ad_file dirname $package_path] $package_key] } ad_try { set package_uri $version(package.url) set package_type $version(package.type) set package_name $version(package-name) set pretty_plural $version(pretty-plural) set initial_install_p $version(initial-install-p) set singleton_p $version(singleton-p) set implements_subsite_p $version(implements-subsite-p) set inherit_templates_p $version(inherit-templates-p) set auto_mount $version(auto-mount) set version_uri $version(url) set summary $version(summary) set description_format $version(description.format) set description $version(description) set release_date $version(release-date) set vendor $version(vendor) set vendor_uri $version(vendor.url) set split_path [split $spec_file_path /] set relative_path [join [lreplace $split_path 0 [lsearch -exact $package_key $split_path]] /] # Register the package if it is not already registered. if { ![apm_package_registered_p $package_key] } { apm_package_register -spec_file_path $relative_path $package_key $package_name $pretty_plural $package_uri $package_type $initial_install_p $singleton_p $implements_subsite_p $inherit_templates_p } # Source Tcl procs and queries to be able # to invoke any Tcl callbacks after mounting and instantiation. Note that this reloading # is only done in the Tcl interpreter of this particular request. # Note that acs-tcl is a special case as its procs are always sourced on startup from bootstrap.tcl if { 1 || $package_key ne "acs-tcl" } { apm_load_libraries -procs -force_reload -packages $package_key apm_load_queries -packages $package_key } # Get the callbacks in an array, since we can't rely on the # before-upgrade being in the db (since it might have changed) # and the before-install definitely won't be there since # it's not added until later here. array set callbacks $version(callbacks) if {$upgrade_p} { # Run before-upgrade if {[info exists callbacks(before-upgrade)]} { apm_invoke_callback_proc -proc_name $callbacks(before-upgrade) -version_id $version_id -type before-upgrade -arg_list [list from_version_name $upgrade_from_version_name to_version_name $version(name)] } } else { # Run before-install if {[info exists callbacks(before-install)]} { apm_invoke_callback_proc -proc_name $callbacks(before-install) -version_id $version_id -type before-install } } if { $load_data_model_p } { apm_package_install_data_model -callback $callback -data_model_files $data_model_files $spec_file_path } # If an older version already exists in apm_package_versions, update it; # otherwise, insert a new version. if { $upgrade_p } { # We are upgrading a package # Load catalog files with upgrade switch before package version is changed in db apm_load_catalog_files -upgrade $package_key set version_id [apm_package_install_version -callback $callback -array version $package_key $version_name $version_uri $summary $description $description_format $vendor $vendor_uri $auto_mount $release_date] apm_version_upgrade $version_id apm_package_install_dependencies -callback $callback $version(embeds) $version(extends) $version(provides) $version(requires) $version_id apm_build_one_package_relationships $package_key apm_package_upgrade_parameters -callback $callback $version(parameters) $package_key } else { # We are installing a new package set version_id [apm_package_install_version -callback $callback -array version $package_key $version_name $version_uri $summary $description $description_format $vendor $vendor_uri $auto_mount $release_date] if { !$version_id } { # There was an error. ns_log Error "apm_package_install: Package $package_key could not be installed. Received version_id $version_id" apm_callback_and_log $callback "The package version could not be created." } apm_load_catalog_files $package_key apm_package_install_dependencies -callback $callback $version(embeds) $version(extends) $version(provides) $version(requires) $version_id apm_build_one_package_relationships $package_key apm_copy_inherited_params $package_key [concat $version(embeds) $version(extends)] # Install the parameters for the version. apm_package_install_parameters -callback $callback $version(parameters) $package_key } # Update all other package information. apm_package_install_owners -callback $callback $version(owners) $version_id apm_package_install_callbacks -callback $callback $version(callbacks) $version_id apm_build_subsite_packages_list apm_callback_and_log $callback "<p>[lindex $operations 1] $version(package-name), version $version(name).</p>" } on error {errmsg} { ns_log Error "apm_package_install: Error installing $version(package-name) version $version(name): $errmsg\n$::errorInfo" apm_callback_and_log -severity Error $callback [subst {<p>Failed to install $version(package-name), version $version(name). The following error was generated: <pre><blockquote> [ns_quotehtml $errmsg] </blockquote></pre> <p> <b><font color="red">NOTE:</font></b> If the error comes from a SQL script you may try to source it manually. When you are done with that you should revisit the APM and try again but remember to leave the manually sourced SQL scripts unchecked on the previous page. </p> }] return 0 } # Enable the package if { $enable_p } { nsv_set apm_enabled_package $package_key 1 apm_version_enable -callback $callback $version_id } # Instantiating, mounting, and after-install callback only invoked on initial install if { ! $upgrade_p } { # After install Tcl proc callback apm_invoke_callback_proc -version_id $version_id -type after-install set priority_mount_path [expr {$version(auto-mount) eq "" ? $mount_path : $version(auto-mount)}] if { $priority_mount_path ne "" } { # This is a package that should be auto mounted set parent_id [site_node::get_node_id -url "/"] if { [catch { db_transaction { set node_id [site_node::new -name $priority_mount_path -parent_id $parent_id] } } error] } { # There is already a node with that path, check if there is a package mounted there array set node [site_node::get -url "/${priority_mount_path}"] if { $node(object_id) eq "" } { # There is no package mounted there so go ahead and mount the new package set node_id $node(node_id) } else { # Don't unmount already mounted packages set node_id "" } } if { $node_id ne "" } { site_node::instantiate_and_mount -node_id $node_id -node_name $priority_mount_path -package_name $version(package-name) -package_key $package_key apm_callback_and_log $callback "<p> Mounted an instance of the package at /${priority_mount_path} </p>" } { # Another package is mounted at the path so we cannot mount set error_text "Package $version(package-name) could not be mounted at /$version(auto-mount) , there may already be a package mounted there, the error is: $error" ns_log Error "apm_package_install: $error_text \n\n$::errorInfo" apm_callback_and_log $callback "<p> $error_text </p>" } } elseif { $package_type eq "apm_service" && $singleton_p == "t" } { # This is a singleton package. Instantiate it automatically, but don't mount. # Using empty context_id apm_package_instance_new -instance_name $version(package-name) -package_key $package_key } if {[ad_file exists $::acs::rootdir/packages/$package_key/install.xml]} { # # Run install.xml only for new installs # ns_log notice "===== RUN /packages/$package_key/install.xml" apm::process_install_xml -install_from_repository=$install_from_repository_p /packages/$package_key/install.xml "" } } else { # After upgrade Tcl proc callback apm_invoke_callback_proc -version_id $version_id -type after-upgrade -arg_list [list from_version_name $upgrade_from_version_name to_version_name $version(name)] } # Flush the installed_p cache acs::try_cache acs::misc_cache flush apm_package_installed-$package_key return $version_idGeneric XQL file: packages/acs-tcl/tcl/apm-install-procs.xql
PostgreSQL XQL file: packages/acs-tcl/tcl/apm-install-procs-postgresql.xql
Oracle XQL file: packages/acs-tcl/tcl/apm-install-procs-oracle.xql