Index: openacs-4/packages/acs-admin/www/apm/build-repository.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/apm/Attic/build-repository.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/apm/build-repository.tcl 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,68 @@
+ad_page_contract {
+ Build package repository.
+}
+
+# TODO: anonymous cvs export the packages with a given CVS tag corresponding to the channel
+# (channel-5-0-oracle, channel-5-1-postgresql, etc.)
+
+
+
+#####
+#
+# Read all package .info files, building manifest file
+#
+#####
+set channel "[db_type]-5-0"
+
+set repository_dir "/web/lars/www/repository/$channel/"
+set repository_url "http://lars.cph02.collaboraid.net/repository/$channel/"
+
+append manifest {} \n
+
+foreach spec_file [apm_scan_packages "[acs_root_dir]/packages"] {
+ with_catch errmsg {
+ array set version [apm_read_package_info_file $spec_file]
+
+ append manifest { } {} \n
+
+ append manifest { } {} [ad_quotehtml $version(package.key)] {} \n
+ append manifest { } {} [ad_quotehtml $version(name)] {} \n
+ append manifest { } {} [ad_quotehtml $version(package-name)] {} \n
+ append manifest { } {} [ad_quotehtml $version(package.type)] {} \n
+
+ set apm_file "${repository_dir}${version(package.key)}-${version(name)}.apm"
+
+ set cmd [list exec [apm_tar_cmd] cf - 2>/dev/null]
+ foreach file [apm_get_package_files -all_db_types -package_key $version(package.key)] {
+ lappend cmd -C "[acs_root_dir]/packages"
+ lappend cmd "$version(package.key)/$file"
+ }
+
+ lappend cmd "|" [apm_gzip_cmd] -c ">" $apm_file
+ eval $cmd
+
+ set apm_url "${repository_url}${version(package.key)}-${version(name)}.apm"
+
+ append manifest { } {} $apm_url {} \n
+ foreach elm $version(provides) {
+ append manifest { } "" \n
+ }
+
+ foreach elm $version(requires) {
+ append manifest { } "" \n
+ }
+
+ append manifest { } {} \n
+ } {
+ global errorInfo
+ ns_log Error "Error while checking package info file $spec_file: $errmsg\n$errorInfo"
+ }
+}
+append manifest {} \n
+
+set fw [open "${repository_dir}manifest.xml" w]
+puts $fw $manifest
+close $fw
+
+ns_return 200 text/html "OK"
+
Index: openacs-4/packages/acs-admin/www/install/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/index.adp,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/acs-admin/www/install/index.adp 2 Oct 2003 20:26:38 -0000 1.2
+++ openacs-4/packages/acs-admin/www/install/index.adp 4 Oct 2003 03:03:29 -0000 1.3
@@ -2,6 +2,20 @@
@page_title;noquote@
@context;noquote@
+
Install from OpenACS Repository
+
+
+ » Install new application
+
+
+
+ » Install new service
+
+
+
+ » Upgrade your system
+
+
Install from local file system
@@ -16,6 +30,8 @@
» Upgrade your system
+
+
Already Installed Packages
Index: openacs-4/packages/acs-admin/www/install/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/index.tcl,v
diff -u -r1.4 -r1.5
--- openacs-4/packages/acs-admin/www/install/index.tcl 2 Oct 2003 20:28:22 -0000 1.4
+++ openacs-4/packages/acs-admin/www/install/index.tcl 4 Oct 2003 03:03:29 -0000 1.5
@@ -55,8 +55,19 @@
}
-set local_install_url "local-install"
+set local_install_url "install"
-set local_service_install_url [export_vars -base "local-install" { { package_type apm_service } }]
+set local_service_install_url [export_vars -base "install" { { package_type apm_service } }]
-set local_upgrade_url [export_vars -base "local-install" { { package_type all } { upgrade_p 1 } }]
+set local_upgrade_url [export_vars -base "install" { { package_type all } { upgrade_p 1 } }]
+
+
+
+set channel "[db_type]-5-0"
+set repository_url "http://lars.cph02.collaboraid.net/repository/$channel/"
+
+set remote_install_url [export_vars -base "install" { repository_url }]
+
+set remote_service_install_url [export_vars -base "install" { { package_type apm_service } repository_url }]
+
+set remote_upgrade_url [export_vars -base "install" { { package_type all } { upgrade_p 1 } repository_url }]
Index: openacs-4/packages/acs-admin/www/install/install-2.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install-2.adp,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install-2.adp 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,34 @@
+
+ @page_title;noquote@
+ @context;noquote@
+
+
+
+ We're sorry. Some packages which are required in order to
+ install the packages you want could not be found.
+
+
+
+
+ The packages you want to install require some other
+ packages. These have been added to the list, and are marked
+ below.
+
+
+ This is the packagelist of packages we are going to install.
+
+ Please click the link below to begin installation.
+
+
+
+
+
+
+ » Install above packagepackages
+
+
+
+
+ Please hit the Back button in your browser and go back and remove the packages we cannot install.
+
+
Index: openacs-4/packages/acs-admin/www/install/install-2.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install-2.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install-2.tcl 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,114 @@
+ad_page_contract {
+ Install packages - dependency check
+} {
+ package_key:multiple
+ {repository_url ""}
+}
+
+if { [llength $package_key] == 0 } {
+ ad_returnredirct .
+ ad_script_abort
+}
+
+
+#####
+#
+# Check dependencies
+#
+#####
+
+apm_get_package_repository -repository_url $repository_url -array repository
+
+array set result [apm_dependency_check_new \
+ -repository_array repository \
+ -package_keys $package_key]
+
+switch $result(status) {
+ ok {
+ set continue_url [export_vars -base "install-3" { repository_url }]
+ ad_set_client_property acs-admin install $result(install)
+ set page_title "Confirm"
+ }
+ failed {
+ set page_title "Missing Required Packages"
+ }
+ default {
+ error "Bad status returned from apm_depdendency_check_new: '$result(status)'"
+ }
+}
+
+if { ![empty_string_p $repository_url] } {
+ set parent_page_title "Install From OpenACS Repository"
+} else {
+ set parent_page_title "Install From Local File System"
+}
+
+
+set context [list [list "." "Install Software"] [list "install" $parent_page_title] $page_title]
+
+
+
+#####
+#
+# Build list to display to user
+#
+#####
+
+# Tells us whether there are any added or problematic packages in the list
+set problems_p 0
+set extras_p 0
+
+array set failed $result(failed)
+
+multirow create install package_key version_name package_name comment extra_p
+
+foreach key $result(packages) {
+ set extra_p [expr [lsearch $package_key $key] == -1]
+ if { $extra_p } {
+ set extras_p 1
+ }
+
+ if { [info exists failed($key)] } {
+ set problems_p 1
+ set comments {}
+ foreach elm $failed($key) {
+ lappend comments "[lindex $elm 0] [lindex $elm 1]"
+ }
+ set comment "Requires [join $comments "; "]"
+ } else {
+ set comment {}
+ }
+
+ array unset version
+ array set version $repository($key)
+
+ multirow append install \
+ $key \
+ $version(name) \
+ $version(package-name) \
+ $comment \
+ $extra_p
+}
+
+template::list::create \
+ -name install \
+ -multirow install \
+ -elements {
+ package_name {
+ label "Package"
+ }
+ version_name {
+ label "Version"
+ }
+ comment {
+ label "Error Message"
+ hide_p {[ad_decode $problems_p 1 0 1]}
+ }
+ extra_p {
+ label "Added"
+ display_eval {[ad_decode $extra_p 1 "*" ""]}
+ hide_p {[ad_decode $extras_p 1 0 1]}
+ html { align center }
+ }
+ }
+
Index: openacs-4/packages/acs-admin/www/install/install-3.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install-3.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install-3.tcl 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,123 @@
+ad_page_contract {
+ Install packages -- actual installation
+
+ @param install Tcl list of packages to install in the order in which they should be installed
+} {
+ {repository_url ""}
+}
+
+
+#####
+#
+# Display progress bar
+#
+#####
+
+
+ad_progress_bar_begin \
+ -title "Installing packages..." \
+ -message_1 "Installing packages, please wait ..." \
+ -message_2 "We will continue automatically when installation is complete."
+
+
+#####
+#
+# Get packages to install
+#
+#####
+
+apm_get_package_repository -repository_url $repository_url -array repository
+
+set install [ad_get_client_property acs-admin install]
+
+if { [llength $install] == 0 } {
+ ns_log Notice "install-3.tcl: Nothing to install. Is this a double-click?"
+}
+
+# We unset the client property so we won't install these packages twice
+ad_set_client_property acs-admin install {}
+
+
+
+
+#####
+#
+# Install packages
+#
+#####
+
+set success_p 1
+
+foreach package_key $install {
+ ns_log Notice "Installing $package_key"
+
+ array unset version
+ array set version $repository($package_key)
+
+ if { [exists_and_not_null version(download_url)] } {
+ set spec_file [apm_load_apm_file -url $version(download_url)]
+ set package_path "[apm_workspace_install_dir]/$package_key"
+ } else {
+ set spec_file $version(path)
+ set package_path "[acs_root_dir]/packages"
+ }
+
+ set final_version_name $version(name)
+
+ if { [apm_package_version_installed_p $version(package.key) $version(name)] } {
+ # Already installed.
+
+ # Enable this version, in case it's not already enabled
+ if { ![apm_package_enabled_p $version(package.key)] } {
+ ns_log Notice "Package $version(package.key) $version(name) is already installed but not enabled, enabling"
+ apm_version_enable -callback apm_dummy_callback [apm_highest_version $version(package.key)]
+ } else {
+ ns_log Notice "Package $version(package.key) $version(name) is already installed and enabled, skipping"
+ }
+ continue
+ }
+
+ # Determine if we are upgrading or installing.
+ if { [apm_package_upgrade_p $package_key $final_version_name] == 1} {
+ ns_log Debug "Upgrading package [string totitle $version(package-name)] to $final_version_name."
+ set upgrade_p 1
+ set initial_version_name [apm_highest_version $package_key]
+ } else {
+ set upgrade_p 0
+ set initial_version_name ""
+ }
+
+ # Find out which script is appropriate to be run.
+ set data_model_files [concat \
+ [apm_data_model_scripts_find \
+ -upgrade_from_version_name $initial_version_name \
+ -upgrade_to_version_name $final_version_name \
+ -package_path $package_path \
+ $package_key] \
+ [apm_ctl_files_find -package_path $package_path $package_key]]
+
+ # Install the packages -- this actually copies the files into the right place in the file system and backs up any old files
+ set version_id [apm_package_install \
+ -enable \
+ -package_path $package_path \
+ -load_data_model \
+ -data_model_files $data_model_files \
+ $spec_file]
+
+ if { $version_id == 0 } {
+ # Installation of the package failed and we shouldn't continue with installation
+ # as there might be packages depending on the failed package. Ideally we should
+ # probably check for such dependencies and continue if there are none.
+ set success_p 0
+ }
+}
+
+#####
+#
+# Done
+#
+#####
+
+ad_progress_bar_end -url [export_vars -base install-4 { repository_url success_p }]
+
+
Index: openacs-4/packages/acs-admin/www/install/install-4.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install-4.adp,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install-4.adp 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,15 @@
+
+ @page_title;noquote@
+ @context;noquote@
+
+ Done installing packages.
+
+
+ Unfortunately, we had some errors. Please check your server error log or contact your system administrator.
+
+
+
+ » Please restart your server
+
+
+
Index: openacs-4/packages/acs-admin/www/install/install-4.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install-4.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install-4.tcl 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,16 @@
+ad_page_contract {
+ Install from local file system
+} {
+ {repository_url ""}
+ {success_p 0}
+}
+
+if { ![empty_string_p $repository_url] } {
+ set parent_page_title "Install From OpenACS Repository"
+} else {
+ set parent_page_title "Install From Local File System"
+}
+set page_title "Installation Complete"
+
+set context [list [list "." "Install Software"] [list "install" $parent_page_title] $page_title]
+
Index: openacs-4/packages/acs-admin/www/install/install.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install.adp,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install.adp 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,21 @@
+
+ @page_title;noquote@
+ @context;noquote@
+
+
+
+ No packages on your system need upgrading.
+
+
+
+ There are no un-installed applications in your file system.
+
+
+ There are no un-installed applications in the OpenACS repository.
+
+
+ » Go back to software installation
+
+
+
+
Index: openacs-4/packages/acs-admin/www/install/install.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/install/install.tcl,v
diff -u
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/install/install.tcl 4 Oct 2003 03:03:29 -0000 1.1
@@ -0,0 +1,107 @@
+ad_page_contract {
+ Install from local file system
+} {
+ {package_type "apm_application"}
+ {upgrade_p 0}
+ {repository_url ""}
+}
+
+
+if { ![empty_string_p $repository_url] } {
+ set page_title "Install From OpenACS Repository"
+} else {
+ set page_title "Install From Local File System"
+}
+
+set context [list [list "." "Install Software"] $page_title]
+
+
+#####
+#
+# Get list of packages available for install/upgrade
+#
+#####
+
+apm_get_installed_versions -array installed_versions
+set upgrades_p 0
+array set package [list]
+
+apm_get_package_repository -repository_url $repository_url -array repository
+
+foreach package_key [array names repository] {
+ array unset version
+ array set version $repository($package_key)
+
+ if { [string equal $package_type "all"] || [string equal $version(package.type) $package_type] } {
+ set package_key $version(package.key)
+
+ # If in upgrade mode, only add to list if it's an upgrade
+ if { !$upgrade_p || [string $version(install_type) upgrade] } {
+ set package([string toupper $version(package-name)]) \
+ [list \
+ $version(package.key) \
+ $version(package-name) \
+ $version(name) \
+ $version(package.type) \
+ $version(install_type)]
+ }
+ }
+}
+
+
+#####
+#
+# Output the list
+#
+#####
+
+# Sort the list alphabetically (in case package_name and package_key doesn't sort the same)
+multirow create packages package_key package_name version_name package_type install_type
+foreach name [lsort -ascii [array names package]] {
+ set row $package($name)
+ multirow append packages \
+ [lindex $row 0] \
+ [lindex $row 1] \
+ [lindex $row 2] \
+ [lindex $row 3] \
+ [lindex $row 4]
+}
+
+multirow extend packages install_url
+multirow foreach packages {
+ set install_url [export_vars -base install-2 { package_key repository_url }]
+}
+
+# Build the list-builder list
+template::list::create \
+ -name packages \
+ -multirow packages \
+ -key package_key \
+ -bulk_actions {
+ "Install checked applications" "install-2" "Install checked applications"
+ } \
+ -bulk_action_export_vars {
+ repository_url
+ } \
+ -elements {
+ package_name {
+ label "Application"
+ }
+ version_name {
+ label "Version"
+ }
+ upgrade {
+ label "Upgrade"
+ hide_p {[ad_decode $upgrades_p 1 0 1]}
+ display_eval {[ad_decode $install_type "upgrade" "Upgrade" ""]}
+ }
+ install {
+ label "Install"
+ link_url_col install_url
+ link_html { title "Install single application" }
+ display_template {Install}
+ }
+ }
+
+
+
Fisheye: Tag 1.4 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install-2.adp'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.5 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install-2.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.9 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install-3.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install-4.adp'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install-4.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install.adp'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.5 refers to a dead (removed) revision in file `openacs-4/packages/acs-admin/www/install/local-install.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/acs-tcl/tcl/apm-file-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-file-procs.tcl,v
diff -u -r1.27 -r1.28
--- openacs-4/packages/acs-tcl/tcl/apm-file-procs.tcl 25 Sep 2003 10:47:56 -0000 1.27
+++ openacs-4/packages/acs-tcl/tcl/apm-file-procs.tcl 4 Oct 2003 03:04:04 -0000 1.28
@@ -504,14 +504,40 @@
}
ad_proc -private apm_load_apm_file {
- {
- -callback apm_dummy_callback
- } file_path
+ {-callback apm_dummy_callback}
+ {-url {}}
+ {file_path {}}
} {
Uncompresses and loads an APM file into the filesystem.
+ @param url If specified, will download the APM file first.
+
+ @return If successful, a path to the .info file of the package uncompressed
+ into the apm-workspace directory
+
} {
+ apm_callback_and_log $callback "Downloading $url..."
+ if { [catch {
+ # Open a destination file.
+ set file_path [ns_tmpnam].apm
+ set fileChan [open $file_path w+ 0600]
+ # Open the channel to the server.
+ set httpChan [lindex [ns_httpopen GET $url] 0]
+ ns_log Debug "APM: Copying data from $url"
+ # Copy the data
+ fcopy $httpChan $fileChan
+ # Clean up.
+ ns_log Debug "APM: Done copying data."
+ close $httpChan
+ close $fileChan
+ } errmsg] } {
+ apm_callback_and_log $callback "Unable to download. Please check your URL..
+ The following error was returned: [ad_quotehtml $errmsg]
+
[ad_footer]"
+ return
+ }
+
if {![file exists $file_path]} {
apm_callback_and_log $callback "
The file cannot be found. Your URL or your file name is incorrect. Please verify that the file name
@@ -597,10 +623,15 @@
apm_callback_and_log $callback "Extracting files into the filesytem."
apm_callback_and_log $callback "$pretty_name $version_name ready for installation."
+
+ # LARS: This looks odd -- package_key is not a directory
# Remove the directory if it exists.
- if {[file exists $package_key]} {
- file delete -force $package_key
- }
+ #if {[file exists $package_key]} {
+ # file delete -force $package_key
+ #}
+
exec sh -c "cd $install_path ; [apm_gunzip_cmd] -q -c $file_path | [apm_tar_cmd] xf -" 2>/dev/null
+
+ return "${install_path}/${package_key}/${package_key}.info"
}
}
Index: openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl,v
diff -u -r1.58 -r1.59
--- openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl 3 Oct 2003 15:17:27 -0000 1.58
+++ openacs-4/packages/acs-tcl/tcl/apm-install-procs.tcl 4 Oct 2003 03:04:04 -0000 1.59
@@ -208,16 +208,20 @@
spec_files
} {
Check dependencies of all the packages provided.
- @param spec_files A list of spec files to be processed.
+
+ @param spec_files A list of spec files to be processed.
+
@param initial_install Only process spec files with the initial install attribute.
- @param pkg_info_all If you supply this argument, when a
- requirement goes unsatisfied, instead of failing, this proc will
- try to add whatever other packages are needed to the install set. The list of package keys to
- add will be the third element in the list returned.
+
+ @param pkg_info_all If you supply this argument, when a
+ requirement goes unsatisfied, instead of failing, this proc will
+ try to add whatever other packages are needed to the install set. The list of package keys to
+ add will be the third element in the list returned.
+
@return A list whose first element indicates whether dependencies were satisfied (1 if so, 0 otherwise).\
- The second element is the package info list with the packages ordered according to dependencies.\
- Packages that can be installed come first. Any packages that failed the dependency check come last.
- The third element is a list of package keys on additional packages to install, in order to satisfy dependencies.
+ The second element is the package info list with the packages ordered according to dependencies.\
+ Packages that can be installed come first. Any packages that failed the dependency check come last.
+ The third element is a list of package keys on additional packages to install, in order to satisfy dependencies.
} {
#### Iterate over the list of info files.
## Every time we satisfy another package, remove it from install_pend, and loop again.
@@ -362,6 +366,245 @@
return [list 1 $install_in $extra_package_keys]
}
+ad_proc -private apm_dependency_check_new {
+ {-repository_array:required}
+ {-package_keys:required}
+} {
+ Checks dependencies and finds out which packages are required to install the requested packages.
+ In case some packages cannot be installed due to failed dependencies, it returns which packages out
+ of the requested can be installed, and which packages, either originally requested or required by those,
+ could not be installed, and why.
+
+ @param package_keys The list of package_keys of the packages requested to be installed.
+
+ @param repository_array Name of an array in the caller's namespace containing the repository of
+ available packages as returned by apm_get_package_repository.
+
+ @return An array list with the following elements:
+
+
+
+ - status: 'ok' or 'failed'.
+
+
- install: If status is 'ok', this is the complete list of packages that need to be installed,
+ in the order in which they need to be installed.
+ If status is 'failed', the list of packages that can be installed.
+
+
- failed: If status is 'failed', an array list keyed by package_key of 2-tuples of
+ (required-uri, required-version) of requirements that could not be satisfied.
+
+
- packages: The list of package_keys of the packages touched upon, either because they
+ were originally requested, or because they were required. If status is 'ok',
+ will be identical to 'install'.
+
+
+
+
+ @see apm_get_package_repository
+} {
+ upvar 1 $repository_array repository
+
+ array set result {
+ status failed
+ install {}
+ failed {}
+ packages {}
+ }
+
+ # 'pending_packages' is an array keyed by package_key with a value of 1 for each package pending installation
+ # When dependencies have been met, the entry will be unset
+ array set pending_packages [list]
+ foreach package_key $package_keys {
+ set pending_packages($package_key) 1
+ }
+
+ # 'installed_packages' is an array keyed by package_key with a value of 1 for each package
+ # whose dependencies have been met and is ready to be installed
+ array set installed_packages [list]
+
+ # 'provided' will keep track of what we've provided with the currently installed packages
+ # combined with the packages which we're already able to install
+ apm_get_installed_provides -array provided
+
+ # 'required' will keep track of unsatisfied dependencies
+ # keyed by (service-uri) and will contain the largest version number required
+ array set required [list]
+
+ # 'required_by' will keep track of unsatisfied dependencies
+ # keyed by (service-uri) and will contain the largest version number required
+ array set required_by [list]
+
+ # Just to get us started
+ set updated_p 1
+
+ ns_log Notice "LARS: STARTING DEPENDENCY CHECK"
+
+ # Outer loop tries to find a package from the repository to add if
+ # we're stuck because of unsatisfied dependencies
+ while { $updated_p } {
+
+ # Keep looping over pending_package_keys, trying to add packages
+ # So long as we've added another, try looping again, as there may be cross-dependencies
+ while { $updated_p && [llength [array names pending_packages]] > 0 } {
+ set updated_p 0
+
+ # Try to add a package from
+ foreach package_key [array names pending_packages] {
+
+ array unset version
+ array set version $repository($package_key)
+
+ set satisfied_p 1
+ foreach req $version(requires) {
+ set req_uri [lindex $req 0]
+ set req_version [lindex $req 1]
+
+ if { ![info exists provided($req_uri)] || \
+ [apm_version_names_compare $provided($req_uri) $req_version]== -1 } {
+
+ ns_log Notice "LARS: $package_key requires $req_uri $req_version => failed"
+
+ set satisfied_p 0
+
+ # Mark this as a requirement
+ if { ![info exists required($req_uri)] || \
+ [apm_version_names_compare $required($req_uri) $req_version] == -1 } {
+ set required($req_uri) $req_version
+ }
+ } else {
+ ns_log Notice "LARS: $package_key requires $req_uri $req_version => OK"
+ }
+ }
+
+ if { $satisfied_p } {
+ # Record as set to go
+ set installed_packages($package_key) 1
+
+ # Remove from pending list
+ unset pending_packages($package_key)
+
+ # Add to install-list, as this is important for ordering the installation of packages correctly
+ lappend result(install) $package_key
+
+ # Add to list of packages touched
+ lappend result(packages) $package_key
+
+ # Record what this package provides, and remove it from the required list, if appropriate
+ foreach prov $version(provides) {
+ set prov_uri [lindex $prov 0]
+ set prov_version [lindex $prov 1]
+ # If what we provide is not already provided, or the alredady provided version is
+ # less than what we provide, record this new provision
+ if { ![info exists provided($prov_uri)] || \
+ [apm_version_names_compare $provided($prov_uri) $prov_version] == -1 } {
+ set provided($prov_uri) $prov_version
+ }
+ # If what we provide is required, and the required version is less than what we provide,
+ # drop the requirement
+ if { [info exists required($prov_uri)] && \
+ [apm_version_names_compare $required($prov_uri) $prov_version] <= 0 } {
+ array unset required($prov_uri)
+ }
+ }
+
+ # Another package has been added, so repeat
+ set updated_p 1
+ }
+ }
+ }
+
+ # Inner loop completed. Either we're done, or there are packages that have dependencies
+ # not currently on the pending_package_keys list.
+
+ set updated_p 0
+
+ if { [llength [array names pending_packages]] > 0 } {
+ # There are packages that have unsatisfied dependencies
+ # Those unmet requirements will be registered in the 'required' array
+
+ # Let's find a package which satisfies at least one of the requirements in 'required'
+
+ foreach package_key [array names repository] {
+ if { [info exists pending_packages($package_key)] || \
+ [info exists installed_packages($package_key)] } {
+ # Packages already on the pending list, or already verified ok won't help us any
+ continue
+ }
+
+ array unset version
+ array set version $repository($package_key)
+
+ ns_log Notice "LARS: Considering $package_key: [array get version]"
+
+ # Let's see if this package provides anything we need
+ foreach prov $version(provides) {
+ set prov_uri [lindex $prov 0]
+ set prov_version [lindex $prov 1]
+
+ if { [info exists required($prov_uri)] && \
+ [apm_version_names_compare $required($prov_uri) $prov_version] <= 0 } {
+
+ ns_log Notice "LARS: Adding $package_key, as it provides $prov_uri $prov_version"
+
+ # If this package provides something that's required in a version high enough
+ # add it to the pending list
+ set pending_packages($package_key) 1
+
+ # We've changed something
+ set updated_p 1
+
+ # Let's try for another go at installing packages
+ break
+ }
+ }
+
+ # Break all the way back to installing pending packages again
+ if { $updated_p } {
+ break
+ }
+ }
+ }
+ }
+
+ if { [llength [array names pending_packages]] == 0 } {
+ set result(status) ok
+ } else {
+ set result(status) failed
+
+ array set failed [list]
+
+ # There were problems, now be helpful
+
+ # Find out which packages couldn't be installed and why
+ foreach package_key [array names pending_packages] {
+ array unset version
+ array set version $repository($package_key)
+
+ # Add to touched upon packages
+ lappend result(packages) $package_key
+
+ # Find unsatisfied requirements
+ foreach req $version(requires) {
+ set req_uri [lindex $req 0]
+ set req_version [lindex $req 1]
+ if { ![info exists provided($req_uri)] || \
+ [apm_version_names_compare $provided($req_uri) $req_version] == -1 } {
+ lappend failed($package_key) [list $req_uri $req_version]
+ if { [info exists provided($req_uri)] } {
+ ns_log Notice "LARS: Failed dependency: $package_key requires $req_uri $req_version, but we only provide $provided($req_uri)"
+ } else {
+ ns_log Notice "LARS: Failed dependency: $package_key requires $req_uri $req_version, but we don't have it"
+ }
+ }
+ }
+ }
+
+ set result(failed) [array get failed]
+ }
+
+ return [array get result]
+}
+
ad_proc -private apm_load_catalog_files {
-upgrade:boolean
package_key
@@ -1191,6 +1434,7 @@
}
ad_proc -private apm_ctl_files_find {
+ {-package_path ""}
package_key
} {
@@ -1203,7 +1447,7 @@
} {
- set file_list [apm_get_package_files -file_types [list ctl_file] -package_key $package_key]
+ set file_list [apm_get_package_files -file_types [list ctl_file] -package_path $package_path -package_key $package_key]
set files [list]
foreach path $file_list {
@@ -1365,29 +1609,40 @@
ns_log Notice "Finished mounting of core packages"
}
-ad_proc -private apm_version_name_compare {
- version_name_1
- version_name_2
-} {
- Compare two version names (e.g. '1.2d3' and '3.5b') as for which comes before which. The example here would return -1.
- @param version_name_1 the first version name
- @param version_name_2 the second version name
- @return 1 if version_name_1 comes after version_name_2, 0 if they are the same, -1 if version_name_1 comes before version_name_2.
- @author Lars Pind
-} {
- db_1row select_sortable_versions {}
- return [string compare $sortable_version_1 $sortable_version_2]
-}
-
ad_proc -public apm_version_names_compare {
version_name_1
version_name_2
} {
- Compare two version names (e.g. '1.2d3' and '3.5b') as for which comes before which. The example here would return -1.
+ Compare two version names for which is earlier than the other.
+
+ Example:
+
+
+
+ - apm_version_names_compare "1.2d3" "3.5b" => -1
+
+
- apm_version_names_compare "3.5b" "3.5b" => 0
+
+
- apm_version_names_compare "3.5b" "1.2d3" => 1
+
+
+
@param version_name_1 the first version name
+
@param version_name_2 the second version name
- @return 1 if version_name_1 comes after version_name_2, 0 if they are the same, -1 if version_name_1 comes before version_name_2.
+ @return
+
+
+
+ - -1: the first version is smallest
+
+
- 0: they're identical
+
+
- 1: the second version is smallest
+
+
+
@author Lars Pind
} {
db_1row select_sortable_versions {}
@@ -1481,6 +1736,129 @@
}
+ad_proc -private apm_get_package_repository {
+ {-repository_url ""}
+ {-array:required}
+} {
+ Gets a list of packages available for install from either a remote package repository
+ or the local file system.
+
+ @param repository_url The URL for the repository channel to get from, or the empty string to
+ seach the local file system instead.
+
+ @param array Name of an array where you want the repository stored. It will be keyed by package-key,
+ and each entry will be an array list list what's returned by apm_read_package_info_file.
+
+ @see apm_read_package_info_file
+
+ @author Lars Pind (lars@collaboraid.biz)
+} {
+ # This will be a list of array-lists of packages available for install
+ upvar 1 $array repository
+
+ apm_get_installed_versions -array installed_version
+
+ if { ![empty_string_p $repository_url] } {
+ set manifest_url "${repository_url}manifest.xml"
+
+ # See if we already have it in a client property
+ set manifest [ad_get_client_property acs-admin [string range $manifest_url end-49 end]]
+
+ if { [empty_string_p $manifest] } {
+ # Nope, get it now
+ array set result [ad_httpget -url $manifest_url]
+
+ if { ![string equal $result(status) 200] } {
+ error "Couldn't get the package list. Please try again later."
+ }
+
+ set manifest $result(page)
+
+ # Store for subsequent requests
+ ad_set_client_property acs-admin [string range $manifest_url end-49 end] $manifest
+ }
+
+ # Parse manifest
+
+ set tree [xml_parse -persist $manifest]
+ set root_node [xml_doc_get_first_node $tree]
+
+ foreach package_node [xml_node_get_children_by_name $root_node "package"] {
+ array unset version
+ set version(package.key) [xml_node_get_content [xml_node_get_first_child_by_name $package_node "package-key"]]
+ set version(name) [xml_node_get_content [xml_node_get_first_child_by_name $package_node "version"]]
+ set version(package-name) [xml_node_get_content [xml_node_get_first_child_by_name $package_node "pretty-name"]]
+ set version(package.type) [xml_node_get_content [xml_node_get_first_child_by_name $package_node "package-type"]]
+ set version(download_url) [xml_node_get_content [xml_node_get_first_child_by_name $package_node "download-url"]]
+
+ foreach dependency_type { provides requires } {
+ set version($dependency_type) {}
+ foreach dependency_node [xml_node_get_children_by_name $package_node "$dependency_type"] {
+ lappend version($dependency_type) \
+ [list [xml_node_get_attribute $dependency_node "url"] \
+ [xml_node_get_attribute $dependency_node "version"]]
+ }
+ }
+
+ if { ![info exists installed_version($version(package.key))] } {
+ # Package is not installed
+ set version(install_type) install
+ } elseif { [string equal $version(name) $installed_version($version(package.key))] || \
+ [apm_higher_version_installed_p $version(package.key) $version(name)] != 1 } {
+ # This version or a higher version already installed
+ set version(install_type) already_installed
+ } else {
+ # Earlier version installed, this is an upgrade
+ set version(install_type) upgrade
+ }
+
+ ns_log Notice "LARS: $version(package.key) = $version(install_type) -- [array get installed_version]"
+
+ if { ![string equal $version(install_type) already_installed] } {
+ set repository($version(package.key)) [array get version]
+ }
+ }
+ } else {
+ # Parse spec files
+ foreach spec_file [apm_scan_packages "[acs_root_dir]/packages"] {
+ with_catch errmsg {
+ array unset version
+ array set version [apm_read_package_info_file $spec_file]
+
+ # If the package doesn't support this RDBMS, it's not really available for install
+ if { [apm_package_supports_rdbms_p -package_key $version(package.key)] } {
+
+ if { ![info exists installed_version($version(package.key))] } {
+ # Package is not installed
+ set version(install_type) install
+ } elseif { [string equal $version(name) $installed_version($version(package.key))] || \
+ [apm_higher_version_installed_p $version(package.key) $version(name)] != 1 } {
+ # This version or a higher version already installed
+ set version(install_type) already_installed
+ } else {
+ # Earlier version installed, this is an upgrade
+ set version(install_type) upgrade
+ }
+
+ if { ![string equal $version(install_type) already_installed] } {
+ set repository($version(package.key)) [array get version]
+ }
+ }
+ } {
+ # We don't error hard here, because we don't want the whole process to fail if there's just one
+ # package with a bad .info file
+ global errorInfo
+ ns_log Error "Error while checking package info file $spec_file: $errmsg\n$errorInfo"
+ }
+ }
+ }
+}
+
+
+
+
+
+
##############
#
# Deprecated Procedures
Index: openacs-4/packages/acs-tcl/tcl/apm-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/apm-procs.tcl,v
diff -u -r1.57 -r1.58
--- openacs-4/packages/acs-tcl/tcl/apm-procs.tcl 3 Oct 2003 10:13:43 -0000 1.57
+++ openacs-4/packages/acs-tcl/tcl/apm-procs.tcl 4 Oct 2003 03:04:04 -0000 1.58
@@ -1504,6 +1504,56 @@
db_exec_plsql apm_package_instance_delete {}
}
+ad_proc -public apm_get_installed_versions {
+ -array:required
+} {
+ Sets the current installed version of packages installed on this system
+ in an array keyed by package_key.
+
+ @param array Name of array in caller's namespace where you want this set
+} {
+ upvar 1 $array installed_version
+
+ db_foreach installed_packages {
+ select package_key, version_name
+ from apm_package_versions
+ where enabled_p = 't'
+ } {
+ set installed_version($package_key) $version_name
+ }
+}
+
+ad_proc -public apm_get_installed_provides {
+ -array:required
+} {
+ Sets the dependencies provided by the packages installed on this system
+ in an array keyed by dependency service-uri.
+
+ @param array Name of array in caller's namespace where you want this set
+} {
+ upvar 1 $array installed_provides
+
+ # All packages provides themselves
+ apm_get_installed_versions -array installed_provides
+
+ # Now check what the provides clauses say
+ db_foreach installed_provides {
+ select service_uri,
+ service_version
+ from apm_package_dependencies d,
+ apm_package_versions v
+ where d.dependency_type = 'provides'
+ and d.version_id = v.version_id
+ and v.enabled_p = 't'
+ } {
+ if { ![info exists installed_provides($service_uri)] || \
+ [apm_version_names_compare $installed_provides($service_uri) $service_version] == -1 } {
+ set installed_provides($service_uri) $service_version
+ }
+ }
+}
+
+
##
## Logging
##