summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Gervais2013-03-05 23:41:54 -0500
committerChristopher Gervais2013-03-05 23:41:54 -0500
commit8255bf491a80930b73e995d43b5fa3225f0c2e61 (patch)
tree2f0514085a46eb8740bfdd8fa61152836b9d5361
parent98039d0bb82782cba1b30545ff2bf405c7aa7c03 (diff)
parent228f169b0693962e95017c95f2dd601e0a1897df (diff)
Merge branch '6.x-2.x' into move_sitesdev-1205458-move_sites_out_of_platforms
Conflicts: platform/provision_drupal.drush.inc provision-tests/provision_tests.drush.inc
-rw-r--r--Provision/Config.php25
-rw-r--r--Provision/Service.php6
-rw-r--r--debian/aegir-cluster-slave2.config (renamed from debian/aegir-cluster-slave.config)0
-rw-r--r--debian/aegir-cluster-slave2.dirs (renamed from debian/aegir-cluster-slave.dirs)0
-rw-r--r--debian/aegir-cluster-slave2.examples (renamed from debian/aegir-cluster-slave.examples)0
-rw-r--r--debian/aegir-cluster-slave2.postinst (renamed from debian/aegir-cluster-slave.postinst)2
-rw-r--r--debian/aegir-cluster-slave2.postrm (renamed from debian/aegir-cluster-slave.postrm)0
-rw-r--r--debian/aegir-cluster-slave2.prerm (renamed from debian/aegir-cluster-slave.prerm)0
-rw-r--r--debian/aegir-cluster-slave2.templates (renamed from debian/aegir-cluster-slave.templates)0
-rw-r--r--debian/aegir-hostmaster2.config (renamed from debian/aegir-hostmaster.config)2
-rwxr-xr-xdebian/aegir-hostmaster2.hosting-queued.init (renamed from debian/aegir-hostmaster.hosting-queued.init)4
-rw-r--r--debian/aegir-hostmaster2.postinst (renamed from debian/aegir-hostmaster.postinst)15
-rw-r--r--debian/aegir-hostmaster2.templates (renamed from debian/aegir-hostmaster.templates)0
-rw-r--r--debian/aegir-provision2.dirs (renamed from debian/aegir-provision.dirs)0
-rw-r--r--debian/aegir-provision2.docs (renamed from debian/aegir-provision.docs)0
-rw-r--r--debian/aegir-provision2.examples (renamed from debian/aegir-provision.examples)0
-rw-r--r--debian/aegir-provision2.lintian (renamed from debian/aegir-provision.lintian)0
-rw-r--r--debian/aegir-provision2.postinst (renamed from debian/aegir-provision.postinst)6
-rw-r--r--debian/aegir-provision2.postrm (renamed from debian/aegir-provision.postrm)2
-rw-r--r--debian/aegir-provision2.preinst (renamed from debian/aegir-provision.preinst)2
-rw-r--r--debian/changelog7
-rw-r--r--debian/control24
-rwxr-xr-xdebian/rules24
-rw-r--r--dns/Provision/Config/Dns.php3
-rw-r--r--dns/Provision/Config/Dnsmasq/host.tpl.php2
-rw-r--r--dns/Provision/Service/dns.php17
-rw-r--r--http/Provision/Config/Http/Site.php26
-rw-r--r--http/Provision/Config/Http/Ssl/Site.php51
-rw-r--r--http/Provision/Service/http/ssl.php114
-rw-r--r--http/delete.provision.inc8
-rw-r--r--install.hostmaster.inc2
-rw-r--r--migrate.hostmaster.inc2
-rw-r--r--platform/backup.provision.inc3
-rw-r--r--platform/delete.provision.inc6
-rw-r--r--platform/drupal/install_5.inc4
-rw-r--r--platform/drupal/install_6.inc4
-rw-r--r--platform/drupal/install_7.inc4
-rw-r--r--platform/install.provision.inc1
-rw-r--r--platform/provision_drupal.drush.inc34
-rw-r--r--platform/reset.login.provision.inc2
-rw-r--r--provision-tests/provision_tests.drush.inc1
-rw-r--r--provision.api.php33
-rw-r--r--provision.drush.inc12
-rw-r--r--provision.inc293
-rwxr-xr-x[-rw-r--r--]release.sh11
-rw-r--r--uninstall.hostmaster.inc86
46 files changed, 368 insertions, 470 deletions
diff --git a/Provision/Config.php b/Provision/Config.php
index 4264f6c..d2b6353 100644
--- a/Provision/Config.php
+++ b/Provision/Config.php
@@ -110,11 +110,33 @@ class Provision_Config {
/**
* Load template from filename().
+ *
+ * @see hook_provision_config_load_templates()
+ * @see hook_provision_config_load_templates_alter()
*/
private function load_template() {
- $class_name = get_class($this);
+ // Allow other Drush commands to change the template used first.
+ $templates = drush_command_invoke_all('provision_config_load_templates', $this);
+ // Ensure that templates is at least an array.
+ if (!is_array($templates)) {
+ $templates = array();
+ }
+ // Allow other Drush commands to alter the templates from other commands.
+ drush_command_invoke_all_ref('provision_config_load_templates_alter', $templates, $this);
+ if (!empty($templates) && is_array($templates)) {
+ foreach ($templates as $file) {
+ if (file_exists($file) && is_readable($file)) {
+ drush_log("Template loaded: $file");
+ return file_get_contents($file);
+ }
+ }
+ }
+
+ // If we've got this far, then try to find a template from this class or
+ // one of its parents.
if (isset($this->template)) {
+ $class_name = get_class($this);
while ($class_name) {
// Iterate through the config file's parent classes until we
// find the template file to use.
@@ -131,6 +153,7 @@ class Provision_Config {
}
}
+ // We've failed to find a template if we've reached this far.
return FALSE;
}
diff --git a/Provision/Service.php b/Provision/Service.php
index b8c2398..d0278e1 100644
--- a/Provision/Service.php
+++ b/Provision/Service.php
@@ -238,13 +238,15 @@ class Provision_Service extends Provision_ChainedState {
*
* This method will fetch the class to instantiate from the internal
* $this->configs control array.
+ *
+ * @return the return value of unlink(), which is usually the file object
*/
function delete_config($config, $data = array()) {
- $this->config($config, $data)->unlink();
+ return $this->config($config, $data)->unlink();
}
/**
- * Fetch extra information the service wants to pass to he config file classes.
+ * Fetch extra information the service wants to pass to the config file classes.
*/
function config_data($config = NULL, $class = NULL) {
$data = array();
diff --git a/debian/aegir-cluster-slave.config b/debian/aegir-cluster-slave2.config
index ea846dc..ea846dc 100644
--- a/debian/aegir-cluster-slave.config
+++ b/debian/aegir-cluster-slave2.config
diff --git a/debian/aegir-cluster-slave.dirs b/debian/aegir-cluster-slave2.dirs
index 02b28dc..02b28dc 100644
--- a/debian/aegir-cluster-slave.dirs
+++ b/debian/aegir-cluster-slave2.dirs
diff --git a/debian/aegir-cluster-slave.examples b/debian/aegir-cluster-slave2.examples
index c614b37..c614b37 100644
--- a/debian/aegir-cluster-slave.examples
+++ b/debian/aegir-cluster-slave2.examples
diff --git a/debian/aegir-cluster-slave.postinst b/debian/aegir-cluster-slave2.postinst
index e4700b0..448e31a 100644
--- a/debian/aegir-cluster-slave.postinst
+++ b/debian/aegir-cluster-slave2.postinst
@@ -41,7 +41,7 @@ case "$1" in
adduser --quiet aegir www-data
if [ -d /etc/sudoers.d ]; then
- ucf --debconf-ok /usr/share/doc/aegir-cluster-slave/examples/example.sudoers /etc/sudoers.d/aegir
+ ucf --debconf-ok /usr/share/doc/aegir-cluster-slave2/examples/example.sudoers /etc/sudoers.d/aegir
ucfr aegir-provision /etc/sudoers.d/aegir
chmod 440 /etc/sudoers.d/aegir
else
diff --git a/debian/aegir-cluster-slave.postrm b/debian/aegir-cluster-slave2.postrm
index 78efa5e..78efa5e 100644
--- a/debian/aegir-cluster-slave.postrm
+++ b/debian/aegir-cluster-slave2.postrm
diff --git a/debian/aegir-cluster-slave.prerm b/debian/aegir-cluster-slave2.prerm
index 88544c2..88544c2 100644
--- a/debian/aegir-cluster-slave.prerm
+++ b/debian/aegir-cluster-slave2.prerm
diff --git a/debian/aegir-cluster-slave.templates b/debian/aegir-cluster-slave2.templates
index d0bc7b9..d0bc7b9 100644
--- a/debian/aegir-cluster-slave.templates
+++ b/debian/aegir-cluster-slave2.templates
diff --git a/debian/aegir-hostmaster.config b/debian/aegir-hostmaster2.config
index 3989ff7..cc8b7e8 100644
--- a/debian/aegir-hostmaster.config
+++ b/debian/aegir-hostmaster2.config
@@ -5,7 +5,7 @@ set -e
# Source debconf library.
. /usr/share/debconf/confmodule
-if [ "$DPKG_DEBUG" = "developer" ] || [ ! -z "$DEBUG" ]; then
+if [ "$DPKG_DEBUG" = "developer" ]; then
set -x
fi
diff --git a/debian/aegir-hostmaster.hosting-queued.init b/debian/aegir-hostmaster2.hosting-queued.init
index 38be240..cc0eaf4 100755
--- a/debian/aegir-hostmaster.hosting-queued.init
+++ b/debian/aegir-hostmaster2.hosting-queued.init
@@ -1,8 +1,8 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: hosting-queued
-# Required-Start: $network $local_fs
-# Required-Stop:
+# Required-Start: $network $remote_fs
+# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Queue runner daemon for Aegir
diff --git a/debian/aegir-hostmaster.postinst b/debian/aegir-hostmaster2.postinst
index a726ae9..0b79c3a 100644
--- a/debian/aegir-hostmaster.postinst
+++ b/debian/aegir-hostmaster2.postinst
@@ -20,7 +20,7 @@ set -e
# Source debconf library.
. /usr/share/debconf/confmodule
-if [ "$DPKG_DEBUG" = "developer" ] || [ ! -z "$DEBUG" ]; then
+if [ "$DPKG_DEBUG" = "developer" ]; then
set -x
fi
@@ -34,7 +34,7 @@ case "$1" in
VERSION=`sed -n '/^version/{s/^.*= *//;p}' /usr/share/drush/commands/provision/provision.info`
FLAGS="--yes"
- if [ "$DPKG_DEBUG" = "developer" ] || [ ! -z "$DEBUG" ]; then
+ if [ "$DPKG_DEBUG" = "developer" ]; then
FLAGS="$FLAGS --debug"
fi
db_get "aegir/makefile"
@@ -65,9 +65,16 @@ case "$1" in
echo "it seems to be the same version as the one we're trying to install, not upgrading"
else
echo "upgrading the frontend from $drupal_root to $NEW_PLATFORM"
+ if su -s /bin/sh aegir -c 'drush @hostmaster pm-list --status=enabled --pipe' | grep -q hosting_queued; then
+ service hosting-queued stop
+ fi
cd "$drupal_root"
su -s /bin/sh aegir -c "drush hostmaster-migrate $FLAGS '$site_uri' '$NEW_PLATFORM'"
echo "upgrade finished, old platform left in $drupal_root"
+ # restart daemon if enabled
+ if su -s /bin/sh aegir -c 'drush @hostmaster pm-list --status=enabled --pipe' | grep -q hosting_queued; then
+ service hosting-queued start
+ fi
fi
else
# fresh install
@@ -106,6 +113,10 @@ case "$1" in
"client_email": "$EMAIL"
}
EOF
+ # on new installs, we default to having the daemon enabled
+ echo 'Enabling hosting-queued daemon'
+ su aegir -c 'drush @hostmaster pm-enable hosting-queued'
+ service hosting-queued start
fi
rm -f $TEMPFILE
# this will ensure that this script aborts if the site can't be bootstrapped
diff --git a/debian/aegir-hostmaster.templates b/debian/aegir-hostmaster2.templates
index 47131ea..47131ea 100644
--- a/debian/aegir-hostmaster.templates
+++ b/debian/aegir-hostmaster2.templates
diff --git a/debian/aegir-provision.dirs b/debian/aegir-provision2.dirs
index 1eea454..1eea454 100644
--- a/debian/aegir-provision.dirs
+++ b/debian/aegir-provision2.dirs
diff --git a/debian/aegir-provision.docs b/debian/aegir-provision2.docs
index 71dfd5b..71dfd5b 100644
--- a/debian/aegir-provision.docs
+++ b/debian/aegir-provision2.docs
diff --git a/debian/aegir-provision.examples b/debian/aegir-provision2.examples
index c614b37..c614b37 100644
--- a/debian/aegir-provision.examples
+++ b/debian/aegir-provision2.examples
diff --git a/debian/aegir-provision.lintian b/debian/aegir-provision2.lintian
index 6ffc6d5..6ffc6d5 100644
--- a/debian/aegir-provision.lintian
+++ b/debian/aegir-provision2.lintian
diff --git a/debian/aegir-provision.postinst b/debian/aegir-provision2.postinst
index b5fda07..fb224a6 100644
--- a/debian/aegir-provision.postinst
+++ b/debian/aegir-provision2.postinst
@@ -20,7 +20,7 @@ set -e
# Source debconf library.
. /usr/share/debconf/confmodule
-if [ "$DPKG_DEBUG" = "developer" ] || [ ! -z "$DEBUG" ]; then
+if [ "$DPKG_DEBUG" = "developer" ]; then
set -x
fi
@@ -40,12 +40,12 @@ case "$1" in
adduser --quiet aegir www-data
if [ -d /etc/sudoers.d ]; then
- ucf --debconf-ok /usr/share/doc/aegir-provision/examples/example.sudoers /etc/sudoers.d/aegir
+ ucf --debconf-ok /usr/share/doc/aegir-provision2/examples/example.sudoers /etc/sudoers.d/aegir
ucfr aegir-provision /etc/sudoers.d/aegir
chmod 440 /etc/sudoers.d/aegir
else
echo "running an older version of sudo"
- echo "copy content of /usr/share/doc/aegir-provision/examples/example.sudoers into /etc/sudoers for aegir to run properly"
+ echo "copy content of /usr/share/doc/aegir-provision2/examples/example.sudoers into /etc/sudoers for aegir to run properly"
fi
# fix permissions on installed directories
diff --git a/debian/aegir-provision.postrm b/debian/aegir-provision2.postrm
index e63a85f..8f46306 100644
--- a/debian/aegir-provision.postrm
+++ b/debian/aegir-provision2.postrm
@@ -18,7 +18,7 @@ set -e
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
-if [ "$DPKG_DEBUG" = "developer" ] || [ ! -z "$DEBUG" ]; then
+if [ "$DPKG_DEBUG" = "developer" ]; then
set -x
fi
diff --git a/debian/aegir-provision.preinst b/debian/aegir-provision2.preinst
index fffb20f..457f88e 100644
--- a/debian/aegir-provision.preinst
+++ b/debian/aegir-provision2.preinst
@@ -26,7 +26,7 @@ case "$1" in
exit 1
fi
if [ -d $VARLIB/.drush/provision ]; then
- echo "existing provision install in $VARLIB/.drush/drush_make detected"
+ echo "existing provision install in $VARLIB/.drush/provision detected"
echo "this needs to be removed or moved away for the install to be completed"
echo "try: rm -rf $VARLIB/.drush/provision"
exit 1
diff --git a/debian/changelog b/debian/changelog
index 043fbac..ed3a2a8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+aegir-provision2 (2.0~alpha1) unstable; urgency=low
+
+ * first alpha release of the 2.x branch, release notes too long to
+ document here: http://community.aegirproject.org/2.0-alpha1
+
+ -- Antoine Beaupré <anarcat@debian.org> Thu, 07 Feb 2013 16:52:49 -0500
+
aegir-provision (2.0~0.0alpha0) UNRELEASED; urgency=low
* switch to a native package
diff --git a/debian/control b/debian/control
index 5d95dfa..72345c3 100644
--- a/debian/control
+++ b/debian/control
@@ -1,4 +1,4 @@
-Source: aegir-provision
+Source: aegir-provision2
Section: admin
Priority: optional
Maintainer: Antoine Beaupré <anarcat@debian.org>
@@ -9,11 +9,13 @@ Homepage: http://aegirproject.org/
Vcs-git: http://git.drupal.org/project/provision.git
Vcs-browser: http://drupalcode.org/project/provision.git
-Package: aegir-provision
+Package: aegir-provision2
Architecture: all
-Depends: ${misc:Depends}, drush (>= 5.5), php5-mysql, mysql-client, sudo, mail-transport-agent, apache2 | nginx, adduser, ucf
+Depends: ${misc:Depends}, drush (>= 5.5), php5-mysql, mysql-client, sudo, postfix | mail-transport-agent, apache2 | nginx, adduser, ucf
Recommends: mysql-server, rsync
Suggests: drush-make
+Conflicts: aegir-provision
+Replaces: aegir-provision
Description: mass Drupal hosting system - backend
A set of contributed modules for Drupal that aims to solve the
problem of managing a large number of Drupal sites. It does this by
@@ -27,10 +29,12 @@ Description: mass Drupal hosting system - backend
files. It can be installed standalone although it is usually
installed with the hostmaster frontend.
-Package: aegir-hostmaster
+Package: aegir-hostmaster2
Architecture: all
-Depends: ${misc:Depends}, drush (>= 5.5), php5-mysql, apache2 | nginx, libapache2-mod-php5 | php5-fpm, aegir-provision (>= ${source:Version}), git-core, unzip, lsb-base (>= 3.0-6)
+Depends: ${misc:Depends}, drush (>= 5.5), php5-mysql, apache2 | nginx, libapache2-mod-php5 | php5-fpm, aegir-provision2 (>= ${source:Version}), git-core, unzip, lsb-base (>= 3.0-6)
Recommends: php5-gd, php5
+Conflicts: aegir-hostmaster
+Replaces: aegir-hostmaster
Description: mass Drupal hosting system - frontend
A set of contributed modules for Drupal that aims to solve the
problem of managing a large number of Drupal sites. It does this by
@@ -47,9 +51,11 @@ Description: mass Drupal hosting system - frontend
and provision and as such doesn't bundle any files itself. Everything
is downloaded on the fly during the install.
-Package: aegir
+Package: aegir2
Architecture: all
-Depends: ${misc:Depends}, aegir-provision (>= ${source:Version}), aegir-hostmaster (>= ${source:Version})
+Depends: ${misc:Depends}, aegir-provision2 (>= ${source:Version}), aegir-hostmaster2 (>= ${source:Version})
+Conflicts: aegir
+Replaces: aegir
Description: mass Drupal hosting system
A set of contributed modules for Drupal that aims to solve the
problem of managing a large number of Drupal sites. It does this by
@@ -61,10 +67,12 @@ Description: mass Drupal hosting system
This meta-package will install both the frontend (aegir-hostmaster)
and the backend (aegir-provision).
-Package: aegir-cluster-slave
+Package: aegir-cluster-slave2
Architecture: all
Depends: ${misc:Depends}, php5-mysql, sudo, apache2, adduser, ucf, libapache2-mod-php5, rsync, nfs-client, mysql-client
Recommends: php5-gd, php5
+Conflicts: aegir-cluster-slave
+Replaces: aegir-cluster-slave
Description: web frontend for the Aegir hosting system
Configuration of lightweight slave servers for the Aegir "pack"
clustering system.
diff --git a/debian/rules b/debian/rules
index dd5fe27..dfe4012 100755
--- a/debian/rules
+++ b/debian/rules
@@ -8,13 +8,13 @@
dh $@
override_dh_install:
- cp -r "$(CURDIR)/db/" "$(CURDIR)/dns/" "$(CURDIR)/http/" "$(CURDIR)/aegir.make" "$(CURDIR)/platform/" "$(CURDIR)/Provision/" "$(CURDIR)/Symfony/" "$(CURDIR)"/*.inc "$(CURDIR)"/*.php "$(CURDIR)"/*.info "$(CURDIR)/debian/aegir-provision/usr/share/drush/commands/provision/"
+ cp -r "$(CURDIR)/db/" "$(CURDIR)/dns/" "$(CURDIR)/http/" "$(CURDIR)/aegir.make" "$(CURDIR)/platform/" "$(CURDIR)/Provision/" "$(CURDIR)/Symfony/" "$(CURDIR)"/*.inc "$(CURDIR)"/*.php "$(CURDIR)"/*.info "$(CURDIR)/debian/aegir-provision2/usr/share/drush/commands/provision/"
# We need this nasty hack, because we added a directory.
# TODO: this is really lame, there must be a better way to do this?
- if [ -d "$(CURDIR)/provision-tests" ]; then cp -r "$(CURDIR)/provision-tests/" "$(CURDIR)/debian/aegir-provision/usr/share/drush/commands/provision/"; fi
+ if [ -d "$(CURDIR)/provision-tests" ]; then cp -r "$(CURDIR)/provision-tests/" "$(CURDIR)/debian/aegir-provision2/usr/share/drush/commands/provision/"; fi
- cp "$(CURDIR)/debian/aegir-provision.lintian" "$(CURDIR)/debian/aegir-provision/usr/share/lintian/overrides/aegir-provision"
+ cp "$(CURDIR)/debian/aegir-provision2.lintian" "$(CURDIR)/debian/aegir-provision2/usr/share/lintian/overrides/aegir-provision"
override_dh_installinit:
dh_installinit --name=hosting-queued
@@ -27,14 +27,24 @@ KEY?="-kjenkins@$(DOMAIN)"
jenkins-build-official:
git-buildpackage -b --git-upstream-branch=origin/upstream --git-debian-branch=origin/debian --git-ignore-branch -kjenkins@ci.aegirproject.org
-version=2.0~$(shell git log -n 1 --oneline | sed 's/ .*$$//')
+# the version from the changelog, add the git hash
+version=$(shell sed -ne 's/^[^(]*(\([^)]*\)).*/\1/;1p' debian/changelog)
+commit=$(shell git log -n 1 --oneline | sed 's/ .*$$//')
+
+# the version we're building with jenkins
+jenkins_version=${version}+${BUILD_NUMBER}.${commit}
+
+# debug for the above
+show-version:
+ @echo ${version}
# this builds a debian package but first updates the branches to follow the latest 2.x branch
# this assumes you are on a "debian" branch (of course)
jenkins-build-auto:
- dch -D unstable -v ${version} "automatic jenkins build ${BUILD_TAG}"
+ dch -D unstable -v ${jenkins_version} "automatic jenkins build ${BUILD_TAG} for commit ${commit}"
git commit -m"dummy commit for jenkins ${BUILD_TAG} autobuild" debian/changelog
git-buildpackage -b ${KEY}
-show-version:
- @echo ${version}
+# helper to debug the above
+show-jenkins-build-auto:
+ @echo would build version ${jenkins_version} with key ${KEY}
diff --git a/dns/Provision/Config/Dns.php b/dns/Provision/Config/Dns.php
index 83cd3ae..7608139 100644
--- a/dns/Provision/Config/Dns.php
+++ b/dns/Provision/Config/Dns.php
@@ -11,7 +11,8 @@ class Provision_Config_Dns extends Provision_Config {
}
function unlink() {
- parent::unlink();
+ $result = parent::unlink();
$this->data['server']->sync($this->filename());
+ return $result;
}
}
diff --git a/dns/Provision/Config/Dnsmasq/host.tpl.php b/dns/Provision/Config/Dnsmasq/host.tpl.php
index 93effe3..f9004d1 100644
--- a/dns/Provision/Config/Dnsmasq/host.tpl.php
+++ b/dns/Provision/Config/Dnsmasq/host.tpl.php
@@ -1,5 +1,5 @@
<?php
-foreach ($site_ip_addresses as $server => $ip) {
+foreach ($ip_addresses as $server => $ip) {
print "{$ip}\t {$this->uri}\n";
}
?>
diff --git a/dns/Provision/Service/dns.php b/dns/Provision/Service/dns.php
index 8567a6b..b95f2e5 100644
--- a/dns/Provision/Service/dns.php
+++ b/dns/Provision/Service/dns.php
@@ -136,7 +136,13 @@ class Provision_Service_dns extends Provision_Service {
}
if ($config == 'host') {
- $data['site_ip_addresses'] = drush_get_option('site_ip_addresses', array(), 'site');
+ // get the IP explicitely allocate to this site
+ $ips = drush_get_option('ip_address', array(), 'site');
+ // .. or the server IPs if none is allocated
+ if (count($ips) < 1) {
+ $ips = $this->server->ip_addresses;
+ }
+ $data['ip_address'] = $ips;
}
return $data;
@@ -244,7 +250,7 @@ class Provision_Service_dns extends Provision_Service {
return $status;
}
- /**
+ /**
* Create a host in DNS.
*
* This can do a lot of things, create a zonefile, add a record to a
@@ -270,18 +276,13 @@ class Provision_Service_dns extends Provision_Service {
return drush_set_error('DRUSH_DNS_NO_ZONE', "Could not determine the zone to create");
}
- $ips = drush_get_option('site_ip_addresses', array(), 'site');
+ $ips = drush_get_option('ip_address', array(), 'site');
if (!$ips && count($ips) < 1) {
drush_log(dt("no IP found for server, trying loopback"));
$ips = array('127.0.0.1');
}
- // XXX: kill me?
- if (!is_array($ips)) {
- $ips = array($ips); // backward compatibility?
- }
-
$this->config('zone', $zone)->record_set($sub, array('A' => $ips));
foreach ($aliases as $alias) {
if ($this->guess_zone($alias) == $zone) {
diff --git a/http/Provision/Config/Http/Site.php b/http/Provision/Config/Http/Site.php
index cd992a9..3b59ad1 100644
--- a/http/Provision/Config/Http/Site.php
+++ b/http/Provision/Config/Http/Site.php
@@ -14,32 +14,6 @@ class Provision_Config_Http_Site extends Provision_Config_Http {
return $this->data['http_vhostd_path'] . '/' . $this->uri;
}
- function write() {
- parent::write();
-
- // We also leave a record of this IP in the site's drushrc.php
- // This way we can pass the info back to the front end.
- $ip_addresses = drush_get_option('site_ip_addresses', array(), 'site');
-
- if ($this->data['ip_address'] != '*') {
- $ip_addresses[$this->data['server']->name] = $this->data['ip_address'];
- }
- elseif (isset($context['site_ip_addresses'][$this->data['server']->name])) {
- unset($ip_addresses[$this->data['server']->name]);
- }
- drush_set_option('site_ip_addresses', $ip_addresses, 'site');
- }
-
- function unlink() {
- parent::unlink();
-
- // We also remove the record of this IP in the site's drushrc.php
- // This way we can pass the info back to the front end.
- $ip_addresses = drush_get_option('site_ip_addresses', array(), 'site');
- unset($ip_addresses[$this->data['server']->name]);
- drush_set_option('site_ip_addresses', $ip_addresses, 'site');
- }
-
function process() {
parent::process();
diff --git a/http/Provision/Config/Http/Ssl/Site.php b/http/Provision/Config/Http/Ssl/Site.php
index 13086bc..7d4aa98 100644
--- a/http/Provision/Config/Http/Ssl/Site.php
+++ b/http/Provision/Config/Http/Ssl/Site.php
@@ -15,7 +15,6 @@ class Provision_Config_Http_Ssl_Site extends Provision_Config_Http_Site {
function write() {
parent::write();
- $ip_addresses = drush_get_option('site_ip_addresses', array(), 'site');
if ($this->ssl_enabled && $this->ssl_key) {
$path = dirname($this->data['ssl_cert']);
// Make sure the ssl.d directory in the server ssl.d exists.
@@ -26,7 +25,9 @@ class Provision_Config_Http_Ssl_Site extends Provision_Config_Http_Site {
)), 0700);
// Touch a file in the server's copy of this key, so that it knows the key is in use.
- touch("{$path}/{$this->uri}.receipt");
+ // XXX: test. data structure may not be sound. try d($this->uri)
+ // if $this fails
+ Provision_Service_http_ssl::assign_certificate_site($this->ssl_key, $this);
// Copy the certificates to the server's ssl.d directory.
provision_file()->copy(
@@ -49,10 +50,9 @@ class Provision_Config_Http_Ssl_Site extends Provision_Config_Http_Site {
'exclude' => "{$path}/*.receipt", // Don't need to synch the receipts
));
}
- elseif ($ip = $ip_addresses[$this->data['server']->name]) {
- if ($ssl_key = Provision_Service_http_ssl::get_ip_certificate($ip, $this->data['server'])) {
- $this->clear_certs($ssl_key);
- }
+ else {
+ // XXX: to be tested, not sure the data structure is sound
+ Provision_Service_http_ssl::free_certificate_site($this->ssl_key, $this);
}
}
@@ -62,45 +62,18 @@ class Provision_Config_Http_Ssl_Site extends Provision_Config_Http_Site {
function unlink() {
parent::unlink();
- $ip_addresses = drush_get_option('site_ip_addresses', array(), 'site');
-
- if ($this->ssl_enabled && $this->ssl_key) {
- $this->clear_certs($this->ssl_key);
- }
- elseif ($ip = $ip_addresses[$this->data['server']->name]) {
- if ($ssl_key = Provision_Service_http_ssl::get_ip_certificate($ip, $this->data['server'])) {
- $this->clear_certs($ssl_key);
- }
- }
-
+ // XXX: to be tested, not sure the data structure is sound
+ Provision_Service_http_ssl::free_certificate_site($this->ssl_key, $this);
}
/**
* Small utility function to stop code duplication.
+ *
+ * @deprecated unused
+ * @see Provision_Service_http_ssl::free_certificate_site()
*/
-
private function clear_certs($ssl_key) {
- $path = $this->data['server']->http_ssld_path . "/$ssl_key";
-
- // Remove the file system reciept we left for this file
- provision_file()->unlink("{$path}/{$this->uri}.receipt")->
- succeed(dt("Deleted SSL Certificate association stub for %site on %server", array(
- '%site' => $this->uri,
- '%server' => $this->data['server']->remote_host)));
-
- $used = Provision_Service_http_ssl::certificate_in_use($ssl_key, $this->data['server']);
-
- if (!$used) {
- // we can remove the certificate from the server ssl.d directory.
- _provision_recursive_delete($path);
- // remove the file from the remote server too.
- $this->data['server']->sync($path);
-
- // Most importantly, we remove the hold this cert had on the IP address.
- Provision_Service_http_ssl::free_certificate_ip($ssl_key, $this->data['server']);
- }
+ return FALSE;
}
-
-
}
diff --git a/http/Provision/Service/http/ssl.php b/http/Provision/Service/http/ssl.php
index 61f9371..03f3977 100644
--- a/http/Provision/Service/http/ssl.php
+++ b/http/Provision/Service/http/ssl.php
@@ -38,6 +38,7 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
$this->context->setProperty('ssl_enabled', 0);
$this->context->setProperty('ssl_key', NULL);
+ $this->context->setProperty('ip_address', '*');
}
@@ -55,23 +56,8 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
if ($ssl_key = $this->context->ssl_key) {
// Retrieve the paths to the cert and key files.
// they are generated if not found.
-
$certs = $this->get_certificates($ssl_key);
$data = array_merge($data, $certs);
-
- // assign ip address based on ssl_key
- $ip = Provision_Service_http_ssl::assign_certificate_ip($ssl_key, $this->server);
-
- if (!$ip) {
- drush_set_error("SSL_IP_FAILURE", dt("There are no more IP addresses available on %server for the %ssl_key certificate.", array(
- "%server" => $this->server->remote_host,
- "%ssl_key" => $ssl_key,
- )));
- }
- else {
- $data['ip_address'] = $ip;
-
- }
}
}
@@ -149,6 +135,51 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
}
/**
+ * Assign the given site to a certificate to mark its usage.
+ *
+ * This is necessary for the backend to figure out when it's okay to
+ * remove certificates.
+ *
+ * Should never fail unless the receipt file cannot be created.
+ *
+ * @return the path to the receipt file if allocation succeeded
+ */
+ static function assign_certificate_site($ssl_key, $site) {
+ $path = $site->platform->server->http_ssld_path . "/" . $ssl_key . "/" . $site->uri . ".receipt";
+ drush_log(dt("registering site %site with SSL certificate %key with receipt file %path", array("%site" => $site->uri, "%key" => $ssl_key, "%path" => $path)));
+ if (touch($path)) {
+ return $path;
+ }
+ else {
+ return FALSE;
+ }
+ }
+
+ /**
+ * Unallocate this certificate from that site.
+ *
+ * @return the path to the receipt file if removal was successful
+ */
+ static function free_certificate_site($ssl_key, $site) {
+ $ssl_dir = $site->platform->server->http_ssld_path . "/" . $ssl_key . "/";
+ // Remove the file system reciept we left for this file
+ if (provision_file()->unlink($ssl_dir . $site->uri . ".receipt")->
+ succeed(dt("Deleted SSL Certificate association receipt for %site on %server", array(
+ '%site' => $site->uri,
+ '%server' => $site->server->remote_host)))->status()) {
+ if (!Provision_Service_http_ssl::certificate_in_use($ssl_key, $site->server)) {
+ drush_log(dt("Deleting unused SSL directory: %dir", array('%dir' => $ssl_dir)));
+ _provision_recursive_delete($ssl_dir);
+ $site->server->sync($path);
+ }
+ return $path;
+ }
+ else {
+ return FALSE;
+ }
+ }
+
+ /**
* Assign the certificate it's own distinct IP address for this server.
*
* Each certificate needs a unique IP address on each server in order
@@ -156,51 +187,26 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
*
* This code uses the filesystem by touching a reciept file in the
* server's ssl.d directory.
+ *
+ * @deprecated this is now based the site URI
+ * @see assign_certificate_site()
*/
static function assign_certificate_ip($ssl_key, $server) {
- $path = $server->http_ssld_path;
-
- $pattern = "{$path}/{$ssl_key}__*.receipt";
- $files = glob($pattern);
- if (sizeof($files) == 1) {
- $pattern = "/^{$ssl_key}__(.*)\.receipt$/";
- preg_match($pattern, basename($files[0]), $matches);
- if (in_array($matches[1], $server->ip_addresses)) {
- // Return an existing match.
- return $matches[1];
- }
-
- // This is a stale match, remove it.
- // Any sites using it will either find a new
- // IP on the next verify task, or fail.
- unlink($files[0]);
- }
-
- // try to assign one
- foreach ($server->ip_addresses as $ip) {
- if (!Provision_Service_http_ssl::get_ip_certificate($ip, $server)) {
- touch("{$path}/{$ssl_key}__{$ip}.receipt");
- return $ip;
- }
- }
-
- return FALSE; // generate error
+ return FALSE;
}
-
/**
* Remove the certificate's lock on the server's public IP.
*
* This function will delete the receipt file left behind by
* the assign_certificate_ip script, allowing the IP to be used
* by other certificates.
+ *
+ * @deprecated this is now based on the site URI
+ * @see free_certificate_site()
*/
static function free_certificate_ip($ssl_key, $server) {
- $ip = Provision_Service_http_ssl::assign_certificate_ip($ssl_key, $server);
- $file = "{$server->http_ssld_path}/{$ssl_key}__{$ip}.receipt";
- if (file_exists($file)) {
- unlink($file);
- }
+ return FALSE;
}
@@ -222,18 +228,10 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
/**
* Check for an existing record for this IP address.
+ *
+ * @deprecated we only use the URI-based allocation now
*/
static function get_ip_certificate($ip, $server) {
- $path = $server->http_ssld_path;
-
- $pattern = "{$path}/*__{$ip}.receipt";
- $files = glob($pattern);
- if (sizeof($files) == 1) {
- $pattern = "/^(.*)__{$ip}\.receipt$/";
- preg_match($pattern, basename($files[0]), $matches);
- return $matches[1];
- }
-
return FALSE;
}
diff --git a/http/delete.provision.inc b/http/delete.provision.inc
index 22260ee..c5b5f1d 100644
--- a/http/delete.provision.inc
+++ b/http/delete.provision.inc
@@ -2,14 +2,18 @@
function drush_http_provision_delete() {
if (d()->type === 'site') {
- d()->service('http')->delete_config('site');
+ d()->service('http')->delete_config('site')
+ ->succeed('Deleted platform configuration file', 'success')
+ ->fail('Failed to delete platform configuration file', 'DRUSH_PERM_ERROR');
}
if (d()->type === 'platform') {
if (!drush_get_option('force', FALSE) && drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_ROOT) && provision_drupal_find_sites()) {
drush_set_error(dt('Existing sites were found on this platform. These sites will need to be deleted before this platform can be deleted.'));
}
else {
- d()->service('http')->delete_config('platform');
+ d()->service('http')->delete_config('platform')
+ ->succeed('Deleted platform configuration file', 'success')
+ ->fail('Failed to delete platform configuration file', 'DRUSH_PERM_ERROR');
}
}
d()->service('http')->parse_configs();
diff --git a/install.hostmaster.inc b/install.hostmaster.inc
index b5b81ba..e349b71 100644
--- a/install.hostmaster.inc
+++ b/install.hostmaster.inc
@@ -98,7 +98,7 @@ The following settings will be used:
)));
if (!drush_confirm(dt('Do you really want to proceed with the install'))) {
- return drush_set_error('PROVISION_CANCEL_INSTALL', dt('Installation aborted by user'));
+ return drush_set_error('PROVISION_CANCEL_INSTALL', dt('Installation aborted'));
}
return TRUE;
diff --git a/migrate.hostmaster.inc b/migrate.hostmaster.inc
index 5628cbd..13a5393 100644
--- a/migrate.hostmaster.inc
+++ b/migrate.hostmaster.inc
@@ -148,8 +148,6 @@ We are making the following assumptions:
function drush_provision_pre_hostmaster_migrate($site, $platform) {
// wipe out cron entry
exec('crontab -r');
- // we can't rely on update.php to run that because it will run too late. this can be removed in 0.5 and above
- provision_backend_invoke(drush_get_option('site_name'), 'sqlq', array("UPDATE {system} SET weight = 0 WHERE type='module' AND name='hosting';"));
}
function drush_provision_hostmaster_migrate($site, $platform) {
diff --git a/platform/backup.provision.inc b/platform/backup.provision.inc
index 2e94eb0..1698f0e 100644
--- a/platform/backup.provision.inc
+++ b/platform/backup.provision.inc
@@ -39,6 +39,7 @@ function drush_provision_drupal_provision_backup_validate($backup_file = NULL) {
$suggested = d()->platform->server->backup_path . '/' . d()->uri . '-' . date("Ymd.His", time()) . '.tar.gz';
// Use format of mysite.com-2008-01-02, if already existing, add number.
+ $count = 0;
while (is_file($suggested)) {
$count++;
$suggested = d()->platform->server->backup_path . '/' . d()->uri . '-' . date('Ymd.His', time()) . '_' . $count . '.tar.gz';
@@ -87,7 +88,7 @@ function drush_provision_drupal_provision_backup() {
}
if (substr($backup_file, -2) == 'gz') {
// same as above: some do not support -z
- $command = 'tar cpf - . | gzip --rsyncable -c > %s';
+ $command = 'tar cpf - . | gzip -c > %s';
} else {
$command = 'tar cpf %s .';
}
diff --git a/platform/delete.provision.inc b/platform/delete.provision.inc
index 4bdbc2e..b6f24b5 100644
--- a/platform/delete.provision.inc
+++ b/platform/delete.provision.inc
@@ -19,6 +19,12 @@ function drush_provision_drupal_pre_provision_delete($backup_file = NULL) {
function drush_provision_drupal_provision_delete() {
if (d()->type === 'site') {
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_ROOT);
+
+ drush_invoke_process('@none', 'provision-save', array(d()->name), array('delete' => TRUE));
+
+ // Do not automatically save the drushrc at the end of the command.
+ drush_set_option('provision_save_config', false);
+
_provision_recursive_delete(d()->site_path);
// we remove the aliases even if redirection is enabled as a precaution
// if redirection is enabled, keep silent about errors
diff --git a/platform/drupal/install_5.inc b/platform/drupal/install_5.inc
index fd61573..cb5989a 100644
--- a/platform/drupal/install_5.inc
+++ b/platform/drupal/install_5.inc
@@ -192,8 +192,8 @@ function install_main() {
$account = install_create_admin_user($client_email);
$onetime = user_pass_reset_url($account);
// Store the one time login link in an option so the front end can direct the user to their new site.
- drush_set_option('login_link', $onetime);
- drush_log(t('Login url: !onetime', array('!onetime' => $onetime)), 'message');
+ drush_set_option('login_link', $onetime . '/login');
+ drush_log(t('Login url: !onetime', array('!onetime' => $onetime . '/login')), 'message');
if ($client_email) {
install_send_welcome_mail($url, $account, $profile, $install_locale, $client_email, $onetime);
diff --git a/platform/drupal/install_6.inc b/platform/drupal/install_6.inc
index 06e0db9..c2d90b8 100644
--- a/platform/drupal/install_6.inc
+++ b/platform/drupal/install_6.inc
@@ -353,8 +353,8 @@ function install_main() {
$account = install_create_admin_user($client_email);
$onetime = user_pass_reset_url($account);
// Store the one time login link in an option so the front end can direct the user to their new site.
- drush_set_option('login_link', $onetime);
- drush_log(t('Login url: !onetime', array('!onetime' => $onetime)), 'message');
+ drush_set_option('login_link', $onetime . '/login');
+ drush_log(t('Login url: !onetime', array('!onetime' => $onetime . '/login')), 'message');
if ($client_email) {
install_send_welcome_mail($url, $account, $profile, $install_locale, $client_email, $onetime);
diff --git a/platform/drupal/install_7.inc b/platform/drupal/install_7.inc
index 9c49c78..26da8a8 100644
--- a/platform/drupal/install_7.inc
+++ b/platform/drupal/install_7.inc
@@ -157,8 +157,8 @@ function install_main() {
$onetime = user_pass_reset_url($account);
// Store the one time login link in an option so the front end can direct the user to their new site.
- drush_set_option('login_link', $onetime);
- drush_log(t('Login url: !onetime', array('!onetime' => $onetime)), 'message');
+ drush_set_option('login_link', $onetime . '/login');
+ drush_log(t('Login url: !onetime', array('!onetime' => $onetime . '/login')), 'message');
if ($client_email) {
install_send_welcome_mail($url, $account, $install_locale, $client_email, $onetime);
diff --git a/platform/install.provision.inc b/platform/install.provision.inc
index b084901..e0f56ae 100644
--- a/platform/install.provision.inc
+++ b/platform/install.provision.inc
@@ -36,6 +36,7 @@ function drush_provision_drupal_pre_provision_install() {
*/
function drush_provision_drupal_pre_provision_install_rollback() {
_provision_recursive_delete( d()->site_path );
+ drush_invoke_process('@none', 'provision-save', array(d()->name), array('delete' => TRUE));
}
diff --git a/platform/provision_drupal.drush.inc b/platform/provision_drupal.drush.inc
index c506774..9828545 100644
--- a/platform/provision_drupal.drush.inc
+++ b/platform/provision_drupal.drush.inc
@@ -788,6 +788,7 @@ function provision_reload_config($context, $file = NULL) {
if (file_exists($file)) {
drush_log("Reloading $context drushrc.php from $file");
include($file);
+ // $options will be defined by the config file included above.
if (sizeof($options)) {
$options = array_merge(drush_get_context($context, array()), $options);
drush_set_context($context, $options);
@@ -809,7 +810,7 @@ function _provision_client_create_symlink() {
if (d()->client_name) {
$sites_dir = d()->server->clients_path . '/' . d()->client_name;
provision_file()->create_dir($sites_dir, dt('Client home directory for @client', array('@client' => d()->client_name)), 0751);
- provision_file()->unlink($sites_dir . '/' . d()->uri); // deliberatly ignore errors
+ _provision_client_delete_old_symlink();
provision_file()->symlink(d()->site_path, $sites_dir . '/' . d()->uri)
->succeed('Created symlink @path to @target')
->fail('Could not create symlink @path to @target: @reason');
@@ -817,6 +818,37 @@ function _provision_client_create_symlink() {
}
/**
+ * Delete dangling symlinks for this site.
+ *
+ * This is a crude implementation, as we do not have the old client name so we
+ * need to iterate over the directories. We only remove the first entry we
+ * find to save some I/O.
+ */
+function _provision_client_delete_old_symlink() {
+ $previous = d()->server->clients_path . '/' . d()->client_name . '/' . d()->uri;
+ // this is necessary because unlink doesn't fail on missing files (!)
+ $found = (file_exists($previous) || is_link($previous));
+ provision_file()->unlink($previous);
+ if (!$found) {
+ drush_log(dt("couldn't find previous client symlink, iterating through all sites"));
+ // only iterate if the symlink location changed
+ if ($dh = @opendir(d()->server->clients_path)) {
+ while (($file = readdir($dh)) !== false) {
+ if ($file != '.' && $file != '..') {
+ $path = d()->server->clients_path . '/' . $file . '/' . d()->uri;
+ if (file_exists($path) || is_link($path)) {
+ provision_file()->unlink($path);
+ drush_log(dt("removed previous symlink in @path", array("@path" => $path)), 'success');
+ break; // found it
+ }
+ }
+ }
+ closedir($dh);
+ }
+ }
+}
+
+/**
* Delete the site symlink within the client directory
*
* This deletes the site symlink created on verify/install
diff --git a/platform/reset.login.provision.inc b/platform/reset.login.provision.inc
index d1b31e8..910b7c1 100644
--- a/platform/reset.login.provision.inc
+++ b/platform/reset.login.provision.inc
@@ -26,7 +26,7 @@ function drush_provision_drupal_provision_login_reset() {
if (empty($account)) {
return drush_set_error('PROVISION_UNABLE_TO_LOAD_UID_1', 'Could not load the admin user with uid 1 on this site.');
}
- $onetime = user_pass_reset_url($account);
+ $onetime = user_pass_reset_url($account) . '/login';
// pass the login link to the front end
drush_set_option('login_link', $onetime);
drush_log(t('Login url: !onetime', array('!onetime' => $onetime)), 'message');
diff --git a/provision-tests/provision_tests.drush.inc b/provision-tests/provision_tests.drush.inc
index f123b46..cba85eb 100644
--- a/provision-tests/provision_tests.drush.inc
+++ b/provision-tests/provision_tests.drush.inc
@@ -236,7 +236,6 @@ function drush_provision_tests_en_module_on_site($module, $site) {
drush_provision_tests_run_remaining_tasks();
}
-
/**
* Helper function to change the data directory
*/
diff --git a/provision.api.php b/provision.api.php
index 54881fd..bef823e 100644
--- a/provision.api.php
+++ b/provision.api.php
@@ -90,3 +90,36 @@ function drush_hook_provision_apache_dir_config($data) {
*/
function drush_hook_provision_apache_vhost_config($uri, $data) {
}
+
+/**
+ * Specify a different template for rendering a config file.
+ *
+ * @param $config
+ * The Provision_config object trying to find its template.
+ *
+ * @return
+ * A filename of a template to use for rendering.
+ *
+ * @see hook_provision_config_load_templates_alter()
+ */
+function hook_provision_config_load_templates($config) {
+ if (is_a($config, 'Provision_Config_Drupal_Settings')) {
+ $file = dirname(__FILE__) . '/custom-php-settings.tpl.php';
+ return $file;
+ }
+}
+
+/**
+ * Alter the templates suggested for rendering a config file.
+ *
+ * @param $templates
+ * The array of templates suggested by other Drush commands.
+ * @param $config
+ * The Provision_config object trying to find its template.
+ *
+ * @see hook_provision_config_load_templates()
+ */
+function hook_provision_config_load_templates_alter(&$templates, $config) {
+ // Don't let any custom templates be used.
+ $templates = array();
+}
diff --git a/provision.drush.inc b/provision.drush.inc
index 3a6832e..36d1e03 100644
--- a/provision.drush.inc
+++ b/provision.drush.inc
@@ -248,7 +248,8 @@ function provision_drush_command() {
'/path/to/platform' => dt('The platform to migrate the site to.'),
),
'options' => array(
- 'makefile' => dt('The optional makefile to use instead of aegir.')
+ 'http_service_type' => dt('Webserver type to configure (default: %webserver)', array('%webserver' => 'apache')),
+ 'makefile' => dt('The makefile used to create the hostmaster platform (default: %makefile)', array('%makefile' => dirname(__FILE__). '/aegir.make')),
),
);
@@ -278,6 +279,15 @@ function provision_drush_command() {
),
);
+ $items['hostmaster-uninstall'] = array(
+ 'description' => dt('Uninstall the Hostmaster frontend.'),
+ 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_SITE,
+ 'options' => array
+ (
+ 'all' => dt('Destroy *ALL* sites managed by the Aegir frontend'),
+ ),
+ );
+
$items['backend-parse'] = array(
'description' => dt('Parse the output of --backend commands to a human readable form'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
diff --git a/provision.inc b/provision.inc
index 6aad782..18f4e45 100644
--- a/provision.inc
+++ b/provision.inc
@@ -207,14 +207,16 @@ function _provision_recursive_delete($path) {
// is_dir() follows symlinks, so it can return true on a symlink
if (is_dir($path) && !is_link($path)) {
$d = dir($path);
- while (($entry = $d->read()) !== FALSE) {
- if ($entry == '.' || $entry == '..') {
- continue;
+ if (!empty($d)) {
+ while (($entry = $d->read()) !== FALSE) {
+ if ($entry == '.' || $entry == '..') {
+ continue;
+ }
+ $entry_path = $path . '/' . $entry;
+ $ret &= _provision_recursive_delete($entry_path);
}
- $entry_path = $path . '/' . $entry;
- $ret &= _provision_recursive_delete($entry_path);
+ $d->close();
}
- $d->close();
$rm = provision_file()->rmdir($path)
->succeed('Deleting @path directory successful.')
@@ -418,285 +420,6 @@ function provision_backend_invoke($target, $command, $arguments = array(), $data
}
/**
- * Invoke a command in a new process, targeting the site specified by
- * the provided site alias record.
- *
- * Use this function instead of drush_backend_invoke_sitealias,
- * drush_backend_invoke_args, or drush_backend_invoke_command
- * (all obsolete in drush 5).
- *
- * @param array $site_alias_record
- * The site record to execute the command on. Use '@self' to run on the current site.
- * @param string $command_name
- * The command to invoke.
- * @param array $commandline_args
- * The arguments to pass to the command.
- * @param array $commandline_options
- * The options (e.g. --select) to provide to the command.
- * @param $backend_options
- * - TRUE - integrate errors
- * - FALSE - do not integrate errors
- * - array - @see drush_backend_invoke_concurrent
- * There are also several options that _only_ work when set in
- * this parameter. They include:
- * - 'invoke-multiple'
- * If $site_alias_record represents a single site, then 'invoke-multiple'
- * will cause the _same_ command with the _same_ arguments and options
- * to be invoked concurrently (e.g. for running concurrent batch processes).
- * - 'concurrency'
- * Limits the number of concurrent processes that will run at the same time.
- * Defaults to '4'.
- * - 'override-simulated'
- * Forces the command to run, even in 'simulated' mode. Useful for
- * commands that do not change any state on the machine, e.g. to fetch
- * database information for sql-sync via sql-conf.
- * - 'interactive'
- * Overrides the backend invoke process to run commands interactively.
- * - 'fork'
- * Overrides the backend invoke process to run non blocking commands in
- * the background. Forks a new process by adding a '&' at the end of the
- * command. The calling process does not receive any output from the child
- * process. The fork option is used to spawn a process that outlives its
- * parent.
- *
- * @return
- * If the command could not be completed successfully, FALSE.
- * If the command was completed, this will return an associative
- * array containing the results of the API call.
- * @see drush_backend_get_result()
- *
- * Do not change the signature of this function! drush_invoke_process
- * is one of the key Drush APIs. See http://drupal.org/node/1152908
- */
-function _provision__drush_invoke_process($site_alias_record, $command_name, $commandline_args = array(), $commandline_options = array(), $backend_options = FALSE) {
- if (is_array($site_alias_record) && array_key_exists('site-list', $site_alias_record)) {
- $site_alias_records = drush_sitealias_resolve_sitespecs($site_alias_record['site-list']);
- $site_alias_records = drush_sitealias_simplify_names($site_alias_records);
- foreach ($site_alias_records as $alias_name => $alias_record) {
- $invocations[] = array(
- 'site' => $alias_record,
- 'command' => $command_name,
- 'args' => $commandline_args,
- );
- }
- }
- else {
- $invocations[] = array(
- 'site' => $site_alias_record,
- 'command' => $command_name,
- 'args' => $commandline_args);
- $invoke_multiple = drush_get_option_override($backend_options, 'invoke-multiple', 0);
- if ($invoke_multiple) {
- $invocations = array_fill(0, $invoke_multiple, $invocations[0]);
- }
- }
- return _provison__drush_backend_invoke_concurrent($invocations, $commandline_options, $backend_options);
-}
-
-/**
- * Execute a new local or remote command in a new process.
- *
- * n.b. Prefer drush_invoke_process() to this function.
- *
- * @param invocations
- * An array of command records to exacute. Each record should contain:
- * - 'site':
- * An array containing information used to generate the command.
- * - 'remote-host'
- * Optional. A remote host to execute the drush command on.
- * - 'remote-user'
- * Optional. Defaults to the current user. If you specify this, you can choose which module to send.
- * - 'ssh-options'
- * Optional. Defaults to "-o PasswordAuthentication=no"
- * - 'path-aliases'
- * Optional; contains paths to folders and executables useful to the command.
- * - '%drush-script'
- * Optional. Defaults to the current drush.php file on the local machine, and
- * to simply 'drush' (the drush script in the current PATH) on remote servers.
- * You may also specify a different drush.php script explicitly. You will need
- * to set this when calling drush on a remote server if 'drush' is not in the
- * PATH on that machine.
- * - 'command':
- * A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
- * - 'args':
- * An array of arguments for the command.
- * - 'options'
- * Optional. An array containing options to pass to the remote script.
- * Array items with a numeric key are treated as optional arguments to the
- * command.
- * - 'backend-options':
- * Optional. Additional parameters that control the operation of the invoke.
- * - 'method'
- * Optional. Defaults to 'GET'.
- * If this parameter is set to 'POST', the $data array will be passed
- * to the script being called as a JSON encoded string over the STDIN
- * pipe of that process. This is preferable if you have to pass
- * sensitive data such as passwords and the like.
- * For any other value, the $data array will be collapsed down into a
- * set of command line options to the script.
- * - 'integrate'
- * Optional. Defaults to TRUE.
- * If TRUE, any error statuses will be integrated into the current
- * process. This might not be what you want, if you are writing a
- * command that operates on multiple sites.
- * - 'log'
- * Optional. Defaults to TRUE.
- * If TRUE, any log messages will be integrated into the current
- * process.
- * - 'output'
- * Optional. Defaults to TRUE.
- * If TRUE, output from the command will be synchronously printed to
- * stdout.
- * - 'drush-script'
- * Optional. Defaults to the current drush.php file on the local
- * machine, and to simply 'drush' (the drush script in the current
- * PATH) on remote servers. You may also specify a different drush.php
- * script explicitly. You will need to set this when calling drush on
- * a remote server if 'drush' is not in the PATH on that machine.
- * @param common_options
- * Optional. Merged in with the options for each invocation.
- * @param backend_options
- * Optional. Merged in with the backend options for each invocation.
- * @param default_command
- * Optional. Used as the 'command' for any invocation that does not
- * define a command explicitly.
- * @param default_site
- * Optional. Used as the 'site' for any invocation that does not
- * define a site explicitly.
- * @param context
- * Optional. Passed in to proc_open if provided.
- *
- * @return
- * If the command could not be completed successfully, FALSE.
- * If the command was completed, this will return an associative array containing the data from drush_backend_output().
- */
-function _provison__drush_backend_invoke_concurrent($invocations, $common_options = array(), $common_backend_options = array(), $default_command = NULL, $default_site = NULL, $context = NULL) {
- $index = 0;
-
- // Slice and dice our options in preparation to build a command string
- $invocation_options = array();
- foreach ($invocations as $invocation) {
- $site_record = isset($invocation['site']) ? $invocation['site'] : $default_site;
- // NULL is a synonym to '@self', although the latter is preferred.
- if (!isset($site_record)) {
- $site_record = '@self';
- }
- // If the first parameter is not a site alias record,
- // then presume it is an alias name, and try to look up
- // the alias record.
- if (!is_array($site_record)) {
- $site_record = drush_sitealias_get_record($site_record);
- }
- $command = isset($invocation['command']) ? $invocation['command'] : $default_command;
- $args = isset($invocation['args']) ? $invocation['args'] : array();
- $command_options = isset($invocation['options']) ? $invocation['options'] : array();
- $backend_options = isset($invocation['backend-options']) ? $invocation['backend-options'] : array();
- // If $backend_options is passed in as a bool, interpret that as the value for 'integrate'
- if (!is_array($common_backend_options)) {
- $integrate = (bool)$common_backend_options;
- $common_backend_options = array('integrate' => $integrate);
- }
-
- $command_options += $common_options;
- $backend_options += $common_backend_options;
-
- $backend_options = _drush_backend_adjust_options($site_record, $command, $command_options, $backend_options);
-
- // Insure that contexts such as DRUSH_SIMULATE and NO_COLOR are included.
- $command_options += _drush_backend_get_global_contexts($site_record);
-
- if (isset($site_record['#name'])) {
- list($post_options, $commandline_options, $drush_global_options) = _drush_backend_classify_options(array(), $command_options, $backend_options);
- $command = '@' . ltrim($site_record['#name'], '@') . ' ' . $command;
- }
- else {
- list($post_options, $commandline_options, $drush_global_options) = _drush_backend_classify_options($site_record, $command_options, $backend_options);
- }
- $site_record += array('path-aliases' => array());
- $site_record['path-aliases'] += array(
- '%drush-script' => NULL,
- );
-
- $site = (array_key_exists('#name', $site_record) && !array_key_exists($site_record['#name'], $invocation_options)) ? $site_record['#name'] : $index++;
- $invocation_options[$site] = array(
- 'site-record' => $site_record,
- 'command' => $command,
- 'args' => $args,
- 'post-options' => $post_options,
- 'drush-global-options' => $drush_global_options,
- 'commandline-options' => $commandline_options,
- 'command-options' => $command_options,
- 'backend-options' => $backend_options,
- );
- }
-
- // Calculate the length of the longest output label
- $max_name_length = 0;
- $label_separator = '';
- if (!array_key_exists('no-label', $common_options) && (count($invocation_options) > 1)) {
- $label_separator = array_key_exists('#label-separator', $common_options) ? $common_options['#label-separator'] : ' >> ';
- foreach ($invocation_options as $site => $item) {
- $backend_options = $item['backend-options'];
- if (!array_key_exists('#output-label', $backend_options)) {
- if (is_numeric($site)) {
- $backend_options['#output-label'] = ' * [@self.' . $site;
- $label_separator = '] ';
- }
- else {
- $backend_options['#output-label'] = $site;
- }
- $invocation_options[$site]['backend-options']['#output-label'] = $backend_options['#output-label'];
- }
- $name_len = strlen($backend_options['#output-label']);
- if ($name_len > $max_name_length) {
- $max_name_length = $name_len;
- }
- if (array_key_exists('#label-separator', $backend_options)) {
- $label_separator = $backend_options['#label-separator'];
- }
- }
- }
- // Now pad out the output labels and add the label separator.
- $reserve_margin = $max_name_length + strlen($label_separator);
- foreach ($invocation_options as $site => $item) {
- $backend_options = $item['backend-options'] + array('#output-label' => '');
- $invocation_options[$site]['backend-options']['#output-label'] = str_pad($backend_options['#output-label'], $max_name_length, " ") . $label_separator;
- if ($reserve_margin) {
- $invocation_options[$site]['drush-global-options']['reserve-margin'] = $reserve_margin;
- }
- }
-
- // Now take our prepared options and generate the command strings
- $cmds = array();
- foreach ($invocation_options as $site => $item) {
- $site_record = $item['site-record'];
- $command = $item['command'];
- $args = $item['args'];
- $post_options = $item['post-options'];
- $commandline_options = $item['commandline-options'];
- $command_options = $item['command-options'];
- $drush_global_options = $item['drush-global-options'];
- $backend_options = $item['backend-options'];
- $os = drush_os($site_record);
- // If the caller did not pass in a specific path to drush, then we will
- // use a default value. For commands that are being executed on the same
- // machine, we will use DRUSH_COMMAND, which is the path to the drush.php
- // that is running right now. For remote commands, we will run a wrapper
- // script instead of drush.php -- drush.bat on Windows, or drush on Linux.
- $drush_path = $site_record['path-aliases']['%drush-script'];
- $drush_command_path = drush_build_drush_command($drush_path, array_key_exists('php', $command_options) ? $command_options['php'] : NULL, $os, array_key_exists('remote-host', $site_record));
- $cmd = _drush_backend_generate_command($site_record, $drush_command_path . " " . _drush_backend_argument_string($drush_global_options, $os) . " " . $command, $args, $commandline_options, $backend_options) . ' 2>&1';
- $cmds[$site] = array(
- 'cmd' => $cmd,
- 'post-options' => $post_options,
- 'backend-options' => $backend_options,
- );
- }
-
- return _drush_backend_invoke($cmds, $common_backend_options, $context);
-}
-
-/**
* the aegir version of the backend
*
* @return string
diff --git a/release.sh b/release.sh
index 24c68cc..23a1354 100644..100755
--- a/release.sh
+++ b/release.sh
@@ -29,7 +29,7 @@ if [ $# -lt 1 -o "$version" = "-h" ]; then
cat <<EOF
not enough arguments
-Usage: $0 <new_version> [<old_version>]
+Usage: $0 <new_version>
EOF
exit 1
fi
@@ -77,9 +77,7 @@ echo changing makefile to download tarball
#sed -i'.tmp' -e'/^projects\[hostmaster\]\[download\]\[type\]/s/=.*$/ = "get"/' \
# -e'/^projects\[hostmaster\]\[download\]\[url\]/s#=.*$#= "http://ftp.drupal.org/files/projects/hostmaster-'$major-$version'.tgz"#' \
# -e'/^projects\[hostmaster\]\[download\]\[branch\].*/s/\[branch\] *=.*$/[directory_name] = "hostmaster"/' aegir.make && git add aegir.make && rm aegir.make.tmp
-sed -i'.tmp' -e'/^projects\[hostmaster\]\[download\]\[type\]/s/=.*$/= "git"/' \
- -e'/^projects\[hostmaster\]\[download\]\[url\]/s#=.*$#= "http://git.drupal.org/project/hostmaster.git"#' \
- -e'/^projects\[hostmaster\]\[download\]\[branch\].*/s/\[branch\] *=.*$/[tag] = "'$major-$version'"/' aegir.make && git add aegir.make && rm aegir.make.tmp
+sed -i'.tmp' -e'/^projects\[hostmaster\]\[download\]\[branch\].*/s/\[branch\] *=.*$/[tag] = "'$major-$version'"/' aegir.make && git add aegir.make && rm aegir.make.tmp
echo changing provision.info version
sed -i'.tmp' -e"s/version *=.*$/version=$major-$version/" provision.info
@@ -91,7 +89,7 @@ sed -i'.tmp' -e"s/AEGIR_VERSION=.*$/AEGIR_VERSION=\"$major-$version\"/" upgrade.
echo resulting changes to be committed:
git diff --cached | cat
-if prompt_yes_no "commit changes and tag release? (y/N) "; then
+if prompt_yes_no "commit changes and tag release?"; then
echo okay, committing...
else
echo 'aborting, leaving changes in git staging area'
@@ -111,8 +109,7 @@ git reset --quiet HEAD 'debian/changelog'
git checkout -- 'debian/changelog'
git commit
-
-if prompt_yes_no "push tags and commits upstream? (y/N) "; then
+if prompt_yes_no "push tags and commits upstream? "; then
# this makes sure we push the commit *and* the tag
git push --tags origin HEAD
fi
diff --git a/uninstall.hostmaster.inc b/uninstall.hostmaster.inc
new file mode 100644
index 0000000..813a675
--- /dev/null
+++ b/uninstall.hostmaster.inc
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Prompt the user to confirm.
+ *
+ * Here we ask to confirm, and also ask if all sites and platforms
+ * also need to be trashed.
+ */
+function drush_provision_hostmaster_uninstall_validate($site = NULL) {
+ drush_print(dt('This command will DELETE YOUR MAIN AEGIR SITE!
+
+This command will:
+
+ 1. delete the Aegir site (database, database user and files)
+ 2. remove the dispatcher crontab'));
+
+ if (drush_get_option('all')) {
+ drush_print(dt(' 3. DELETE ALL PLATFORMS AND SITES MANAGED BY AEGIR!
+'));
+ } else {
+ drush_print(dt('
+
+The hostmaster platform and other platforms and sites managed by Aegir will be
+left for your perusal.
+'));
+ }
+
+ if (!drush_confirm(dt('Do you want to uninstall Aegir?'))) {
+ return drush_set_error('PROVISION_CANCEL_UNINSTALL', dt('Uninstall aborted'));
+ }
+ if (drush_get_option('all') && !drush_confirm(dt('REALLY? Do you REALLY want to destroy all sites managed by Aegir?'))) {
+ return drush_set_error('PROVISION_CANCEL_UNINSTALL', dt('Uninstall aborted'));
+ }
+ return TRUE;
+}
+
+function drush_provision_hostmaster_uninstall() {
+ if (drush_get_option('all')) {
+ // need to access the hostmaster database
+ drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_DATABASE);
+
+ drush_log(dt('Destroying sites'), 'info');
+ $query = db_query("SELECT n.title AS uri, h.name AS context FROM {node} n INNER JOIN {hosting_site} s ON s.nid=n.nid LEFT JOIN {hosting_context} h ON h.nid = n.nid WHERE n.type = '%s' AND s.status != %d AND h.name != 'hostmaster'", 'site', -2);
+ while ($resource = db_fetch_object($query)) {
+ drush_log(dt("Destroying @resource", array('@resource' => $resource->uri)));
+ $context = $resource->context;
+ if (!$context) {
+ drush_log(dt('Context missing for resource @resource, guessing', array('@resource' => $resource->uri)), 'warning');
+ $context = $resource->uri;
+ }
+ provision_backend_invoke($context, 'provision-delete');
+ }
+
+ drush_log(dt('Destroying platforms'), 'info');
+ $query = db_query("SELECT n.title AS uri, h.name AS context FROM {node} n INNER JOIN {hosting_platform} p LEFT JOIN {hosting_context} h ON h.nid = n.nid WHERE n.type = '%s' AND p.status != %d AND h.name != '%s'", 'platform', -2, d('@hostmaster')->platform->name);
+ while ($resource = db_fetch_object($query)) {
+ drush_log(dt("Destroying @resource", array('@resource' => $resource->uri)));
+ $context = $resource->context;
+ if (!$context) {
+ drush_log(dt('Context missing for platform @resource, ignoring', array('@resource' => $resource->uri)), 'warning');
+ } else {
+ provision_backend_invoke($context, 'provision-delete');
+ }
+ }
+
+ drush_log(dt('Destroying servers'), 'info');
+ $query = db_query("SELECT n.title AS uri, h.name AS context FROM {node} n LEFT JOIN {hosting_context} h ON h.nid = n.nid WHERE n.type = '%s' AND h.name != '%s' AND h.name != '%s'", 'server', d('@hostmaster')->server->name, d('@hostmaster')->db_server->name);
+ while ($resource = db_fetch_object($query)) {
+ drush_log(dt("Destroying @resource", array('@resource' => $resource->uri)));
+ $context = $resource->context;
+ if (!$context) {
+ drush_log(dt('Context missing for platform @resource, ignoring', array('@resource' => $resource->uri)), 'warning');
+ } else {
+ provision_backend_invoke($context, 'provision-delete');
+ }
+ }
+ }
+
+ drush_log(dt('Destroying main hostmaster site'), 'info');
+ provision_backend_invoke('@hostmaster', 'provision-delete');
+ drush_log(dt('Removing crontab'), 'info');
+ exec('crontab -r');
+ drush_log(dt('Removing alias'), 'info');
+ $config = new Provision_Config_Drushrc_Alias('@hostmaster');
+ $config->unlink();
+}