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
(boolean) (optional)
-callback
(defaults to "apm_dummy_callback") (optional)
-load_data_model
(boolean) (optional)
-install_from_repository
(boolean) (optional)
-data_model_files
(defaults to "0") (optional)
-package_path
(optional)
-mount_path
(optional)
Parameters:
spec_file_path - 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):
%3 test_upgrade upgrade (test acs-lang) apm_package_install apm_package_install test_upgrade->apm_package_install acs::try_cache acs::try_cache (private) apm_package_install->acs::try_cache acs_package_root_dir acs_package_root_dir (public) apm_package_install->acs_package_root_dir ad_file ad_file (public) apm_package_install->ad_file ad_try ad_try (public) apm_package_install->ad_try apm::process_install_xml apm::process_install_xml (public) apm_package_install->apm::process_install_xml apm_packages_full_install apm_packages_full_install (private) apm_packages_full_install->apm_package_install lang::test::setup_test_package lang::test::setup_test_package (private) lang::test::setup_test_package->apm_package_install packages/acs-admin/www/apm/packages-install-4.tcl packages/acs-admin/ www/apm/packages-install-4.tcl packages/acs-admin/www/apm/packages-install-4.tcl->apm_package_install packages/acs-admin/www/install/install-3.tcl packages/acs-admin/ www/install/install-3.tcl packages/acs-admin/www/install/install-3.tcl->apm_package_install

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_id
Generic 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

[ hide source ] | [ make this the default ]
Show another procedure: