Skip to content
Commits on Source (49)
...@@ -6,10 +6,11 @@ This is the backend of the Aegir hosting system. ...@@ -6,10 +6,11 @@ This is the backend of the Aegir hosting system.
The front end and back end are designed to be run separately, and each The front end and back end are designed to be run separately, and each
front end will also be able to drive multiple back ends. front end will also be able to drive multiple back ends.
The most up to date information regarding the project and its goal The most up to date information regarding the project and its goals
can be found in the Aegir wiki page: can be found on the Aegir website and the community portal:
http://groups.drupal.org/aegir/overview http://aegirproject.org
http://community.aegirproject.org
To install Aegir, you should follow the INSTALL.txt document in docs/. To install Aegir, you should follow the INSTALL.txt document in docs/.
The HINTS_<arch>.txt files can be useful if you have a specific The HINTS_<arch>.txt files can be useful if you have a specific
...@@ -20,8 +21,8 @@ To upgrade Aegir, follow the UPGRADE.txt document in docs/. ...@@ -20,8 +21,8 @@ To upgrade Aegir, follow the UPGRADE.txt document in docs/.
The core of the documentation in docs/ should be sufficient to get you The core of the documentation in docs/ should be sufficient to get you
started. If you have further questions or are having trouble with Aegir, started. If you have further questions or are having trouble with Aegir,
head for the documentation wiki: head for the documentation:
http://groups.drupal.org/aegir-hosting-system/documentation http://community.aegirproject.org/notebook
Other documentation for developpers is also available in docs/. Other documentation for developers is also available in docs/.
...@@ -71,7 +71,7 @@ class provisionService_db extends provisionService { ...@@ -71,7 +71,7 @@ class provisionService_db extends provisionService {
function suggest_db_name() { function suggest_db_name() {
$uri = $this->context->uri; $uri = $this->context->uri;
$suggest_base = substr(str_replace(array('.', '-'), '' , ereg_replace('^www\.', '', $uri)), 0, 16); $suggest_base = substr(str_replace(array('.', '-'), '' , preg_replace('/^www\./', '', $uri)), 0, 16);
if (!$this->database_exists($suggest_base)) { if (!$this->database_exists($suggest_base)) {
return $suggest_base; return $suggest_base;
...@@ -91,8 +91,10 @@ class provisionService_db extends provisionService { ...@@ -91,8 +91,10 @@ class provisionService_db extends provisionService {
/** /**
* Generate a new mysql database and user account for the specified credentials * Generate a new mysql database and user account for the specified credentials
*/ */
function create_site_database() { function create_site_database($creds = array()) {
$creds = $this->generate_site_credentials(); if (!sizeof($creds)) {
$creds = $this->generate_site_credentials();
}
extract($creds); extract($creds);
if (!$this->can_create_database()) { if (!$this->can_create_database()) {
...@@ -150,12 +152,14 @@ class provisionService_db extends provisionService { ...@@ -150,12 +152,14 @@ class provisionService_db extends provisionService {
} }
function import_site_database($dump_file = null) { function import_site_database($dump_file = null, $creds = array()) {
if (is_null($dump_file)) { if (is_null($dump_file)) {
$dump_file = d()->site_path . '/database.sql'; $dump_file = d()->site_path . '/database.sql';
} }
$creds = $this->fetch_site_credentials(); if (!sizeof($creds)) {
$creds = $this->fetch_site_credentials();
}
$exists = provision_file()->exists($dump_file) $exists = provision_file()->exists($dump_file)
->succeed('Found database dump at @path.') ->succeed('Found database dump at @path.')
......
...@@ -14,6 +14,8 @@ class provisionService_db_mysql extends provisionService_db_pdo { ...@@ -14,6 +14,8 @@ class provisionService_db_mysql extends provisionService_db_pdo {
} }
function database_exists($name) { function database_exists($name) {
// An underscore in a LIKE clause is a single character wildcard, escape it.
$name = str_replace('_', '\_', $name);
$result = $this->query("SHOW DATABASES LIKE '%s'", $name); $result = $this->query("SHOW DATABASES LIKE '%s'", $name);
if ($result) { if ($result) {
return $result->fetchColumn(0); return $result->fetchColumn(0);
...@@ -88,7 +90,7 @@ class provisionService_db_mysql extends provisionService_db_pdo { ...@@ -88,7 +90,7 @@ class provisionService_db_mysql extends provisionService_db_pdo {
} }
function grant_host(provisionContext_server $server) { function grant_host(provisionContext_server $server) {
$command = sprintf('mysql -u intntnllyInvalid -h %s -P %s', $command = sprintf('mysql -u intntnllyInvalid -h %s -P %s -e ""',
escapeshellarg($this->server->remote_host), escapeshellarg($this->server->remote_host),
escapeshellarg($this->server->db_port)); escapeshellarg($this->server->db_port));
...@@ -124,6 +126,13 @@ class provisionService_db_mysql extends provisionService_db_pdo { ...@@ -124,6 +126,13 @@ class provisionService_db_mysql extends provisionService_db_pdo {
* We go through all this trouble to hide the password from the commandline, * We go through all this trouble to hide the password from the commandline,
* it's the most secure way (apart from writing a temporary file, which would * it's the most secure way (apart from writing a temporary file, which would
* create conflicts in parallel runs) * create conflicts in parallel runs)
*
* XXX: this needs to be refactored so it:
* - works even if /dev/fd/3 doesn't exit
* - has a meaningful name (we're talking about reading and writing
* dumps here, really, or at least call mysql and mysqldump, not
* just any command)
* - can be pushed upstream to drush (http://drupal.org/node/671906)
*/ */
function safe_shell_exec($cmd, $db_host, $db_user, $db_passwd, $dump_file = null) { function safe_shell_exec($cmd, $db_host, $db_user, $db_passwd, $dump_file = null) {
$mycnf = sprintf('[client] $mycnf = sprintf('[client]
...@@ -141,6 +150,7 @@ port=%s ...@@ -141,6 +150,7 @@ port=%s
2 => array("pipe", "w"), // stderr is a file to write to 2 => array("pipe", "w"), // stderr is a file to write to
3 => array("pipe", "r"), // fd3 is our special file descriptor where we pass credentials 3 => array("pipe", "r"), // fd3 is our special file descriptor where we pass credentials
); );
$pipes = array();
$process = proc_open($cmd, $descriptorspec, $pipes); $process = proc_open($cmd, $descriptorspec, $pipes);
$this->safe_shell_exec_output = ''; $this->safe_shell_exec_output = '';
if (is_resource($process)) { if (is_resource($process)) {
......
...@@ -16,7 +16,7 @@ fairly simple. It's 3 basic steps:: ...@@ -16,7 +16,7 @@ fairly simple. It's 3 basic steps::
1. Install requirements 1. Install requirements
2. Configure system requirements, which include:: 2. Configure system requirements, which include::
* create a Aegir user * create a Aegir user
* configure Apache, MySQL, DNS, etc * configure Apache (or Nginx with PHP-FPM), MySQL, DNS, etc
3. Run the install script. 3. Run the install script.
Those steps are detailed below. The following instructions provide example Those steps are detailed below. The following instructions provide example
...@@ -32,10 +32,11 @@ bullet-point summary of the steps required for the installation. In case of ...@@ -32,10 +32,11 @@ bullet-point summary of the steps required for the installation. In case of
conflict between INSTALL.txt and other documentation, INSTALL.txt should be conflict between INSTALL.txt and other documentation, INSTALL.txt should be
considered the canonical source of information. considered the canonical source of information.
Also note that those instructions setup a complete Aegir system. If you want Also note that these instructions setup a complete Aegir system. If you want
to only setup a new server, it should be sufficient to install requirement to only setup a new remote web/db server, it should be sufficient to install
(step 1) and configure them (step 2). You will just need the --backend-only flag requirements (step 1), configure them (step 2) and follow the Remote server
to avoid installing the frontend on the server. how-to which you can find at http://community.aegirproject.org/node/30.
1. Install software requirements 1. Install software requirements
================================ ================================
...@@ -53,6 +54,7 @@ assumed to be run as root user. ...@@ -53,6 +54,7 @@ assumed to be run as root user.
A standard umask of 022 is assumed. This is the default on most systems. A standard umask of 022 is assumed. This is the default on most systems.
Web server Web server
---------- ----------
...@@ -62,6 +64,15 @@ need root access to that server and the server must be reserved for ...@@ -62,6 +64,15 @@ need root access to that server and the server must be reserved for
Aegir. Sharing the server with other control panels such as Cpanel, Plesk or Aegir. Sharing the server with other control panels such as Cpanel, Plesk or
AlternC will very likely create problems and is not supported. AlternC will very likely create problems and is not supported.
Aegir also supports Nginx web server, but requires at least version 0.7.27 or
newer. Since Nginx doesn't provide php-cgi or php-fpm (recommended) modules,
you will need to install and run php-fpm server separately. You can find
useful examples and tips in the third party Barracuda installer available
at http://gitorious.org/aegir/barracuda-octopus. Note: this third party
installer is not supported by the core Aegir developers, but you can find
helpful community support at http://community.aegirproject.org.
PHP 5.2 PHP 5.2
------- -------
...@@ -75,12 +86,15 @@ load. As a result, we suggest using PHP 5.2 for the time-being. ...@@ -75,12 +86,15 @@ load. As a result, we suggest using PHP 5.2 for the time-being.
See http://drupal.org/node/360605 (amongst other issues) for details. See http://drupal.org/node/360605 (amongst other issues) for details.
Database server Database server
--------------- ---------------
You will require a database server, obviously. Aegir currently only supports You will require a database server, obviously. Aegir currently only supports
MySQL. It is preferable to use a dedicated server since Aegir will create MySQL and MariaDB. It is preferable to use a dedicated (not shared-hosting)
database users and will requires the use of the mysql 'root' user. server since Aegir will create database users and will require the use of the
MySQL 'root' user.
Mail transfer agent Mail transfer agent
------------------- -------------------
...@@ -92,6 +106,7 @@ email". Additional messages will show that site has been removed because of ...@@ -92,6 +106,7 @@ email". Additional messages will show that site has been removed because of
this problem. To remedy the situation simply install an MTA like sendmail, this problem. To remedy the situation simply install an MTA like sendmail,
postfix, or exim and do the minimal configuration. postfix, or exim and do the minimal configuration.
Other utilities: sudo, rsync, git and unzip Other utilities: sudo, rsync, git and unzip
------------------------------ ------------------------------
...@@ -104,13 +119,14 @@ The jQueryUI library is used in the Aegir UI, unzip is required to extract it. ...@@ -104,13 +119,14 @@ The jQueryUI library is used in the Aegir UI, unzip is required to extract it.
Sudo is required to allow the aegir user the limited privilege to restart the Sudo is required to allow the aegir user the limited privilege to restart the
webserver when required. Rsync is used to sync files to remote servers. webserver when required. Rsync is used to sync files to remote servers.
Summary Summary
------- -------
This may vary according to your platform, but under a Debian derivative, you This may vary according to your platform, but under a Debian derivative, you
can install all those packages using the following. can install all those packages using the following.
Shell commands:: Shell commands as root::
apt-get install apache2 php5 php5-cli php5-gd php5-mysql mysql-server \ apt-get install apache2 php5 php5-cli php5-gd php5-mysql mysql-server \
postfix sudo rsync git-core unzip postfix sudo rsync git-core unzip
...@@ -150,6 +166,7 @@ the resolved IP address to be the '127.0.0.1' loopback address. ...@@ -150,6 +166,7 @@ the resolved IP address to be the '127.0.0.1' loopback address.
If you intend to manage multiple servers using Aegir, you will need to If you intend to manage multiple servers using Aegir, you will need to
make sure that the IP address is the public IP of this server. make sure that the IP address is the public IP of this server.
Aegir user Aegir user
---------- ----------
...@@ -170,7 +187,7 @@ username if desired. ...@@ -170,7 +187,7 @@ username if desired.
In addition we will create a directory layout for Aegir configuration and In addition we will create a directory layout for Aegir configuration and
backups. backups.
Shell commands:: Shell commands as root::
adduser --system --group --home /var/aegir aegir adduser --system --group --home /var/aegir aegir
adduser aegir www-data #make aegir a user of group www-data adduser aegir www-data #make aegir a user of group www-data
...@@ -196,7 +213,6 @@ Change the memory_limit directive in /etc/php5/apache2/php.ini to read:: ...@@ -196,7 +213,6 @@ Change the memory_limit directive in /etc/php5/apache2/php.ini to read::
memory_limit = 128M ; Maximum amount of memory a script may consume (128MB) memory_limit = 128M ; Maximum amount of memory a script may consume (128MB)
Apache configuration Apache configuration
-------------------- --------------------
...@@ -228,21 +244,47 @@ file. ...@@ -228,21 +244,47 @@ file.
/etc/sudoers configuration:: /etc/sudoers configuration::
aegir ALL=NOPASSWD: /usr/sbin/apache2ctl aegir ALL=NOPASSWD: /usr/sbin/apache2ctl
Nginx configuration
--------------------
Aegir assumes standard Nginx configuration is available on the server, and
generates its own configuration files. The way we enable this is by
symlinking a single file which contains all the configuration necessary.
In Debian-based systems, you should symlink this file inside
``/etc/nginx/conf.d`` that will be parsed on startup.
Shell command as root::
ln -s /var/aegir/config/nginx.conf /etc/nginx/conf.d/aegir.conf
**Do not reload/restart Nginx after running these commands, it will fail.**
The installer script creates the configuration file referenced by the newly
created symlink.
The aegir user needs to have sudo access. Add the relevant line to your sudoers
file.
/etc/sudoers configuration::
aegir ALL=NOPASSWD: /etc/init.d/nginx
Remote web servers Remote web servers
------------------ ------------------
Any number of remote web servers may be configured. They need an aegir user and Any number of remote web servers may be configured. They need an aegir user and
Apache configuration as above, with the same user name and directory paths. SSH Apache configuration as above, with the same user name and directory paths. SSH
public/private keys should be set up so hostmaster's Aegir user can access public/private keys should be set up so hostmaster's Aegir user can access
remote web Aegir users with no passwords. The above apache configuration needs remote web Aegir users with no passwords. The above Apache configuration needs
to be performed too. to be performed too.
They will also need a login shell, which can be modified using the ``chsh`` command. They will also need a login shell, which can be modified using the ``chsh`` command.
Shell command as root:: Shell commands as root::
chsh -s /bin/sh aegir chsh -s /bin/sh aegir
apt-get install rsync apache2 php5 php5-cli php5-mysql apt-get install rsync apache2 php5 php5-cli php5-mysql
Database configuration Database configuration
---------------------- ----------------------
...@@ -269,6 +311,7 @@ If you are concerned about MySQL being accessible in this way, you can also ...@@ -269,6 +311,7 @@ If you are concerned about MySQL being accessible in this way, you can also
configure your firewall to only allow incoming connections from certain addresses. configure your firewall to only allow incoming connections from certain addresses.
This is outside the scope of this document however. This is outside the scope of this document however.
3. Run the install script 3. Run the install script
========================= =========================
...@@ -276,6 +319,7 @@ This section deals with the actual installation of Aegir. You can ...@@ -276,6 +319,7 @@ This section deals with the actual installation of Aegir. You can
install aegir in one of two ways: one assumes you have already install aegir in one of two ways: one assumes you have already
downloaded drush and provision, while the other will do that for you. downloaded drush and provision, while the other will do that for you.
3.1 Installing aegir with only the install.sh script 3.1 Installing aegir with only the install.sh script
---------------------------------------------------- ----------------------------------------------------
...@@ -285,7 +329,7 @@ as the aegir user created above, so it needs to be placed somewhere that the ...@@ -285,7 +329,7 @@ as the aegir user created above, so it needs to be placed somewhere that the
aegir user can access in order to execute it. This file is available in aegir user can access in order to execute it. This file is available in
Provision or can be downloaded through the web with this command:: Provision or can be downloaded through the web with this command::
Shell commands:: Shell command::
wget -O install.sh 'http://git.aegirproject.org/?p=provision.git;a=blob_plain;f=install.sh.txt;hb=HEAD' wget -O install.sh 'http://git.aegirproject.org/?p=provision.git;a=blob_plain;f=install.sh.txt;hb=HEAD'
By default, the install script will install the "correct" version of Aegir By default, the install script will install the "correct" version of Aegir
...@@ -294,9 +338,12 @@ git master branch. If you downloaded an official release, it should install ...@@ -294,9 +338,12 @@ git master branch. If you downloaded an official release, it should install
the official release.). You can modify which version to install by editing the the official release.). You can modify which version to install by editing the
AEGIR_VERSION variable in the script. AEGIR_VERSION variable in the script.
Shell commands:: Shell command for Apache version::
su -s /bin/sh aegir -c "sh install.sh" su -s /bin/sh aegir -c "sh install.sh"
Shell command for Nginx version::
su -s /bin/sh aegir -c "sh install.sh --http_service_type=nginx"
Note you must run the above command as root or prefix with sudo. Note you must run the above command as root or prefix with sudo.
You will be prompted for the information necessary to complete the You will be prompted for the information necessary to complete the
...@@ -306,6 +353,7 @@ Once you have run install.sh once, drush and provision should be ...@@ -306,6 +353,7 @@ Once you have run install.sh once, drush and provision should be
installed and you can use the more powerful hostmaster-install command installed and you can use the more powerful hostmaster-install command
to retry the install if it failed the first time. to retry the install if it failed the first time.
3.2 Installing aegir with drush and provision installed 3.2 Installing aegir with drush and provision installed
------------------------------------------------------- -------------------------------------------------------
...@@ -315,7 +363,7 @@ provision in the commands directory of Drush (either ~aegir/.drush or ...@@ -315,7 +363,7 @@ provision in the commands directory of Drush (either ~aegir/.drush or
is properly installed, you can install all other aegir components using is properly installed, you can install all other aegir components using
the hostmaster-install command. the hostmaster-install command.
Shell commands:: Shell command::
drush hostmaster-install --version=HEAD drush hostmaster-install --version=HEAD
...@@ -335,6 +383,7 @@ or if not provided as a command line switch, the address prompted by the ...@@ -335,6 +383,7 @@ or if not provided as a command line switch, the address prompted by the
installer process. This e-mail address will also be used as the default e-mail installer process. This e-mail address will also be used as the default e-mail
address of the first user and client in Aegir, but can be changed later. address of the first user and client in Aegir, but can be changed later.
Checkpoint / Finished! Checkpoint / Finished!
---------------------- ----------------------
......
...@@ -51,13 +51,19 @@ the bottom of this document before attempting to run the upgrade.sh script, ...@@ -51,13 +51,19 @@ the bottom of this document before attempting to run the upgrade.sh script,
as the script will assume you have your system set up appropriately to as the script will assume you have your system set up appropriately to
handle the upgrade process. handle the upgrade process.
You can download and run the upgrade.sh script with the following. You can download the upgrade.sh script with the following command.
Make sure you download it to somewhere that the aegir user can access in order Make sure you download it to somewhere that the aegir user can access in order
to execute it. to execute it.
Shell commands:: Shell commands::
wget -O upgrade.sh.txt 'http://git.aegirproject.org/?p=provision.git;a=blob_plain;f=upgrade.sh.txt;hb=HEAD' wget -O upgrade.sh.txt 'http://git.aegirproject.org/?p=provision.git;a=blob_plain;f=upgrade.sh.txt;hb=HEAD'
You may need to edit the script to set any variables that are different from the
defaults. Pay particular attention to the OLD_DRUPAL_DIR variable, as you may be
upgrading from a different release to the default here.
Shell commands::
su -s /bin/sh aegir -c "sh upgrade.sh.txt aegir.example.com" su -s /bin/sh aegir -c "sh upgrade.sh.txt aegir.example.com"
Remember to replace aegir.example.com with the domain of your Aegir installation. Remember to replace aegir.example.com with the domain of your Aegir installation.
...@@ -81,19 +87,19 @@ you are reading this document. ...@@ -81,19 +87,19 @@ you are reading this document.
Shell commands:: Shell commands::
export AEGIR_VERSION=HEAD export AEGIR_VERSION=HEAD
export AEGIR_DIR=/var/aegir export AEGIR_HOME="$HOME"
export DRUPAL_DIR=$AEGIR_DIR/hostmaster-$AEGIR_VERSION export DRUPAL_DIR=$AEGIR_HOME/hostmaster-$AEGIR_VERSION
export DRUSH_VERSION=6.x-3.3 export DRUSH_VERSION=6.x-3.3
export DRUSH_MAKE_VERSION=6.x-2.0-beta9 export DRUSH_MAKE_VERSION=6.x-2.0-beta11
export AEGIR_DOMAIN=aegir.example.com export AEGIR_DOMAIN=aegir.example.com
export OLD_DRUPAL_DIR=$AEGIR_DIR/hostmaster-0.4-alpha9 export OLD_DRUPAL_DIR=$AEGIR_HOME/hostmaster-0.4-beta2
This document also assumes drush is installed properly and we use an This document also assumes drush is installed properly and we use an
environment variable to simplify the documentation again. environment variable to simplify the documentation again.
Shell commands:: Shell commands::
export DRUSH="php $AEGIR_DIR/drush/drush.php" export DRUSH="php $AEGIR_HOME/drush/drush.php"
Generic upgrade instructions Generic upgrade instructions
============================ ============================
...@@ -128,7 +134,7 @@ frontend. ...@@ -128,7 +134,7 @@ frontend.
Shell commands:: Shell commands::
cd $AEGIR_DIR cd $AEGIR_HOME
mv drush drush.bak mv drush drush.bak
wget http://ftp.drupal.org/files/projects/drush-$DRUSH_VERSION.tar.gz wget http://ftp.drupal.org/files/projects/drush-$DRUSH_VERSION.tar.gz
gunzip -c drush-$DRUSH_VERSION.tar.gz | tar -xf - gunzip -c drush-$DRUSH_VERSION.tar.gz | tar -xf -
...@@ -229,7 +235,7 @@ Finally, set an $AEGIR_IP environment variable for use in the Database ...@@ -229,7 +235,7 @@ Finally, set an $AEGIR_IP environment variable for use in the Database
configuration step below. configuration step below.
Shell commands as root:: Shell commands as root::
AEGIR_IP=`resolveip $AEGIR_HOST` AEGIR_IP=`resolveip $AEGIR_HOST | awk {'print $6'}`
0.4 - unzip dependency 0.4 - unzip dependency
---------------------- ----------------------
......
...@@ -114,6 +114,7 @@ class provisionService_http_public extends provisionService_http { ...@@ -114,6 +114,7 @@ class provisionService_http_public extends provisionService_http {
$this->server->http_postd_path = "{$app_dir}/post.d"; $this->server->http_postd_path = "{$app_dir}/post.d";
$this->server->http_platformd_path = "{$app_dir}/platform.d"; $this->server->http_platformd_path = "{$app_dir}/platform.d";
$this->server->http_vhostd_path = "{$app_dir}/vhost.d"; $this->server->http_vhostd_path = "{$app_dir}/vhost.d";
$this->server->http_platforms_path = "{$this->server->aegir_root}/platforms";
} }
} }
...@@ -142,7 +143,12 @@ class provisionService_http_public extends provisionService_http { ...@@ -142,7 +143,12 @@ class provisionService_http_public extends provisionService_http {
provision_file()->create_dir($this->server->http_vhostd_path , dt("Webserver virtual host configuration"), 0700); provision_file()->create_dir($this->server->http_vhostd_path , dt("Webserver virtual host configuration"), 0700);
$this->sync($this->server->http_vhostd_path, array( $this->sync($this->server->http_vhostd_path, array(
'exclude' => $this->server->http_vhostd_path . '/*', // Make sure remote directory is created 'exclude' => $this->server->http_vhostd_path . '/*', // Make sure remote directory is created
)); ));
provision_file()->create_dir($this->server->http_platforms_path, dt("Platforms"), 0755);
$this->sync($this->server->http_platforms_path, array(
'exclude' => $this->server->http_platforms_path . '/*', // Make sure remote directory is created
));
} }
parent::verify_server_cmd(); parent::verify_server_cmd();
......
...@@ -7,14 +7,15 @@ ...@@ -7,14 +7,15 @@
function drush_provision_hostmaster_install_validate($site = NULL) { function drush_provision_hostmaster_install_validate($site = NULL) {
// set defaults for this whole script // set defaults for this whole script
// those are settings that are not prompted to the user but still overridable // those are settings that are not prompted to the user but still overridable
$version = drush_set_default('version', drush_get_option('version', 'HEAD')); drush_set_default('version', provision_version());
$version = drush_get_option('version');
$aegir_root = drush_set_default('aegir_root', drush_server_home()); $aegir_root = drush_set_default('aegir_root', drush_server_home());
drush_set_default('root', $aegir_root . '/' . 'hostmaster-' . $version); drush_set_default('root', $aegir_root . '/' . 'hostmaster-' . $version);
drush_set_default('r', drush_get_option('root')); drush_set_default('r', drush_get_option('root'));
drush_set_default('script_user', provision_current_user()); drush_set_default('script_user', provision_current_user());
drush_set_default('web_group', _provision_default_web_group()); drush_set_default('web_group', _provision_default_web_group());
drush_set_default('http_service_type', 'apache'); drush_set_default('http_service_type', 'apache');
drush_set_default('drush_make_version', '6.x-2.0-beta9'); drush_set_default('drush_make_version', '6.x-2.0-beta11');
drush_set_default('aegir_db_user', 'root'); drush_set_default('aegir_db_user', 'root');
$aegir_db_user = drush_get_option('aegir_db_user'); $aegir_db_user = drush_get_option('aegir_db_user');
drush_set_default('makefile', $aegir_root . '/.drush/provision/aegir.make'); drush_set_default('makefile', $aegir_root . '/.drush/provision/aegir.make');
...@@ -23,20 +24,17 @@ function drush_provision_hostmaster_install_validate($site = NULL) { ...@@ -23,20 +24,17 @@ function drush_provision_hostmaster_install_validate($site = NULL) {
drush_print("=============================================================================="); drush_print("==============================================================================");
if (!$site || !drush_get_option('aegir_host', NULL) || !drush_get_option('aegir_db_pass', NULL) || filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL)) { if (!$site || !drush_get_option('aegir_host', NULL) || !drush_get_option('aegir_db_pass', NULL) || filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL)) {
drush_print("Some settings have not been guessed and will now be prompted. drush_print("Some settings have not been provided and will now be prompted.
Don't worry: you will get to review those settings after the final install"); Don't worry: you will get to review those settings after the final install");
} }
// now we prompt the user for settings if not provided or not sane // now we prompt the user for settings if not provided or not sane
if (!$site) { if (!$site) {
$site = drush_prompt(dt("Aegir domain name"), provision_fqdn()); $site = drush_prompt(dt("Aegir frontend URL"), provision_fqdn());
} }
drush_set_option('site', $site); drush_set_option('site', $site);
$aegir_host = drush_get_option('aegir_host', NULL, 'options'); drush_set_default('aegir_host', provision_fqdn());
if (is_null($aegir_host)) { drush_set_default('aegir_db_host', 'localhost');
$aegir_host = drush_prompt(dt("Master server FQDN"), provision_fqdn());
}
drush_set_option('aegir_host', $aegir_host);
if (is_null(drush_get_option('aegir_db_pass', NULL))) { if (is_null(drush_get_option('aegir_db_pass', NULL))) {
// XXX: may not be portable everywhere? // XXX: may not be portable everywhere?
...@@ -46,8 +44,13 @@ Don't worry: you will get to review those settings after the final install"); ...@@ -46,8 +44,13 @@ Don't worry: you will get to review those settings after the final install");
print "\n"; // add a newline since the user's didn't print print "\n"; // add a newline since the user's didn't print
} }
if (drush_get_option('aegir_host') == 'localhost') {
$default_email = 'webmaster@example.com';
} else {
$default_email = 'webmaster@' . drush_get_option('aegir_host');
}
while (!filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL)) { while (!filter_var(drush_get_option('client_email'), FILTER_VALIDATE_EMAIL)) {
$client_email = drush_prompt(dt("Admin user e-mail"), "you@example.com"); $client_email = drush_prompt(dt("Admin user e-mail"), $default_email);
drush_set_option('client_email', $client_email); drush_set_option('client_email', $client_email);
} }
...@@ -72,6 +75,7 @@ The following settings will be used: ...@@ -72,6 +75,7 @@ The following settings will be used:
Aegir user: !user Aegir user: !user
Web group: !web Web group: !web
Web server: !web_server Web server: !web_server
Aegir DB host: !db_host
Aegir DB user: !db_user Aegir DB user: !db_user
Aegir DB password: !db_pass Aegir DB password: !db_pass
Drush make version: !drush_make Drush make version: !drush_make
...@@ -85,6 +89,7 @@ The following settings will be used: ...@@ -85,6 +89,7 @@ The following settings will be used:
'!user' => drush_get_option('script_user'), '!user' => drush_get_option('script_user'),
'!web' => drush_get_option('web_group'), '!web' => drush_get_option('web_group'),
'!web_server' => drush_get_option('http_service_type'), '!web_server' => drush_get_option('http_service_type'),
'!db_host' => drush_get_option('aegir_db_host'),
'!db_user' => drush_get_option('aegir_db_user'), '!db_user' => drush_get_option('aegir_db_user'),
'!db_pass' => is_null(drush_get_option('aegir_db_pass', NULL, 'process')) ? '<previously set>' : '<prompted>', '!db_pass' => is_null(drush_get_option('aegir_db_pass', NULL, 'process')) ? '<previously set>' : '<prompted>',
'!drush_make' => drush_get_option('drush_make_version'), '!drush_make' => drush_get_option('drush_make_version'),
...@@ -110,11 +115,8 @@ function drush_provision_hostmaster_install($site = NULL) { ...@@ -110,11 +115,8 @@ function drush_provision_hostmaster_install($site = NULL) {
$aegir_db_user = drush_get_option('aegir_db_user'); $aegir_db_user = drush_get_option('aegir_db_user');
$aegir_db_pass = drush_get_option('aegir_db_pass'); $aegir_db_pass = drush_get_option('aegir_db_pass');
$master_db = sprintf("mysql://%s:%s@%s",$aegir_db_user, $aegir_db_pass, drush_get_option('aegir_host'));
// TODO: support creation of an external db server
$server = '@server_master'; $server = '@server_master';
drush_backend_invoke_args("provision-save", array($server), array( $master_context = array(
'context_type' => 'server', 'context_type' => 'server',
// files // files
'remote_host' => drush_get_option('aegir_host'), 'remote_host' => drush_get_option('aegir_host'),
...@@ -124,10 +126,25 @@ function drush_provision_hostmaster_install($site = NULL) { ...@@ -124,10 +126,25 @@ function drush_provision_hostmaster_install($site = NULL) {
'http_service_type' => drush_get_option('http_service_type'), 'http_service_type' => drush_get_option('http_service_type'),
'web_group' => drush_get_option('web_group'), 'web_group' => drush_get_option('web_group'),
'master_url' => "http://" . $site, 'master_url' => "http://" . $site,
// mysql );
'db_service_type' => 'mysql',
'master_db' => $master_db, $master_db = sprintf("mysql://%s:%s@%s",$aegir_db_user, $aegir_db_pass, drush_get_option('aegir_db_host'));
)); if (drush_get_option('aegir_host') == drush_get_option('aegir_db_host')) {
$master_context['db_service_type'] = 'mysql';
$master_context['master_db'] = $master_db;
$dbserver = $server;
} else {
$dbserver = '@server_' . drush_get_option('aegir_db_host');
$dbserver_context = array(
'remote_host' => drush_get_option('aegir_db_host'),
'context_type' => 'server',
'db_service_type' => 'mysql',
'master_db' => $master_db,
);
drush_backend_invoke_args("provision-save", array($dbserver), $dbserver_context);
provision_backend_invoke($dbserver, 'provision-verify');
}
drush_backend_invoke_args("provision-save", array($server), $master_context);
provision_backend_invoke($server, 'provision-verify'); provision_backend_invoke($server, 'provision-verify');
// exit if an error has occured. // exit if an error has occured.
...@@ -167,7 +184,7 @@ function drush_provision_hostmaster_install($site = NULL) { ...@@ -167,7 +184,7 @@ function drush_provision_hostmaster_install($site = NULL) {
drush_backend_invoke_args("provision-save", array($site_name), array( drush_backend_invoke_args("provision-save", array($site_name), array(
'context_type' => 'site', 'context_type' => 'site',
'platform' => $platform_name, 'platform' => $platform_name,
'db_server' => $server, 'db_server' => $dbserver,
'uri' => $site, 'uri' => $site,
'client_email' => drush_get_option('client_email'), 'client_email' => drush_get_option('client_email'),
'profile' => 'hostmaster', 'profile' => 'hostmaster',
......
...@@ -26,11 +26,10 @@ ...@@ -26,11 +26,10 @@
# 2. downloads provision in $AEGIR_HOME/.drush # 2. downloads provision in $AEGIR_HOME/.drush
# 3. delegate the rest of the install to hostmaster-install # 3. delegate the rest of the install to hostmaster-install
######################################################################## ########################################################################
# basic variables, change before release
AEGIR_VERSION="HEAD"
DRUSH_VERSION=6.x-3.3
# when adding a variable here, add it to the display below # guess the aegir version based on the info file
AEGIR_VERSION=HEAD
DRUSH_VERSION=6.x-3.3
######################################################################## ########################################################################
# functions # functions
......
<?php
function drush_provision_backend_parse() {
return drush_backend_parse_output(file_get_contents('php://stdin'), TRUE);
}
<?php
/**
* @file
* Provision hooks for the provision backup_delete command.
*/
/**
* Provision backup_delete command
*
* These are the hooks that will be executed by the drush_invoke function
* when deleting a backup file from the backend.
*/
function drush_provision_drupal_provision_backup_delete($backup = null) {
if($backup) {
$backups = explode(',', $backup);
foreach ($backups as $filename) {
$success = provision_file()->unlink($filename)
->succeed('Removed backup file @path')
->fail('Could not remove backup file @path');
}
}
else {
drush_set_error(dt('No backup files provided'));
}
}
...@@ -43,8 +43,8 @@ function drush_provision_drupal_provision_clone($new_uri, $platform = null) { ...@@ -43,8 +43,8 @@ function drush_provision_drupal_provision_clone($new_uri, $platform = null) {
$options['name'] = $new_uri; $options['name'] = $new_uri;
$options['platform'] = (isset($platform)) ? $platform : $options['platform']; $options['platform'] = (isset($platform)) ? $platform : $options['platform'];
$options['root'] = d($options['platform'])->root; $options['root'] = d($options['platform'])->root;
$options['aliases'] = array(); $options['aliases'] = drush_get_option('aliases');
$options['redirection'] = 0; $options['redirection'] = drush_get_option('redirection');
if ($profile = drush_get_option('profile', FALSE)) { if ($profile = drush_get_option('profile', FALSE)) {
$options['profile'] = $profile; $options['profile'] = $profile;
......
...@@ -17,6 +17,32 @@ drush_log( ...@@ -17,6 +17,32 @@ drush_log(
db_query("UPDATE {files} SET filepath=replace(filepath, 'sites/%s', 'sites/%s')", $old_url, $new_url); db_query("UPDATE {files} SET filepath=replace(filepath, 'sites/%s', 'sites/%s')", $old_url, $new_url);
db_query("UPDATE {users} SET picture = replace(picture, 'sites/%s', 'sites/%s')", $old_url, $new_url); db_query("UPDATE {users} SET picture = replace(picture, 'sites/%s', 'sites/%s')", $old_url, $new_url);
db_query("UPDATE {files} SET filepath=replace(filepath, 'sites/default', 'sites/%s')", $new_url);
db_query("UPDATE {users} SET picture = replace(picture, 'sites/default', 'sites/%s')", $new_url);
variable_set('file_directory_path', "sites/$new_url/files"); variable_set('file_directory_path', "sites/$new_url/files");
variable_set('file_directory_temp', "sites/$new_url/files/tmp"); variable_set('file_directory_temp', "sites/$new_url/files/tmp");
// Global theme settings paths.
if ($var = variable_get('theme_settings', FALSE)) {
$var['logo_path'] = str_replace($old_url, $new_url, $var['logo_path']);
$var['favicon_path'] = str_replace($old_url, $new_url, $var['favicon_path']);
variable_set('theme_settings', $var);
}
$themes = list_themes();
foreach (array_keys($themes) as $theme) {
// Update logo and favicon paths for each theme.
if ($var = variable_get('theme_'. $theme .'_settings', FALSE)) {
$var['logo_path'] = str_replace($old_url, $new_url, $var['logo_path']);
$var['favicon_path'] = str_replace($old_url, $new_url, $var['favicon_path']);
variable_set('theme_'. $theme .'_settings', $var);
}
// Update color module paths.
if (module_exists('color')) {
foreach (array('_files', '_logo', '_screenshot', '_stylesheets') as $suffix) {
if ($var = variable_get('color_'. $theme . $suffix, FALSE)) {
variable_set('color_'. $theme . $suffix, str_replace($old_url, $new_url, $var));
}
}
}
}
...@@ -171,37 +171,29 @@ function _provision_drupal_create_directories($url = NULL, $profile = NULL) { ...@@ -171,37 +171,29 @@ function _provision_drupal_create_directories($url = NULL, $profile = NULL) {
"sites/$url/libraries" => 02775, # http://drupal.org/node/496240 "sites/$url/libraries" => 02775, # http://drupal.org/node/496240
); );
$chown = array();
$chgrp = array(); $chgrp = array();
// special case: platform. do not handle files dir // special case: platform. do not handle files dir
if ($url != 'all') { if ($url != 'all') {
$mkdir["sites/$url/files"] = 02770; $mkdir["sites/$url/files"] = 02770;
$chown["sites/$url/files"] = d('@server_master')->script_user;
$chgrp["sites/$url/files"] = d('@server_master')->web_group; $chgrp["sites/$url/files"] = d('@server_master')->web_group;
$mkdir["sites/$url/files/tmp"] = 02770; $mkdir["sites/$url/files/tmp"] = 02770;
$chown["sites/$url/files/tmp"] = d('@server_master')->script_user;
$chgrp["sites/$url/files/tmp"] = d('@server_master')->web_group; $chgrp["sites/$url/files/tmp"] = d('@server_master')->web_group;
$mkdir["sites/$url/files/images"] = 02770; $mkdir["sites/$url/files/images"] = 02770;
$chown["sites/$url/files/images"] = d('@server_master')->script_user;
$chgrp["sites/$url/files/images"] = d('@server_master')->web_group; $chgrp["sites/$url/files/images"] = d('@server_master')->web_group;
$mkdir["sites/$url/files/pictures"] = 02770; $mkdir["sites/$url/files/pictures"] = 02770;
$chown["sites/$url/files/pictures"] = d('@server_master')->script_user;
$chgrp["sites/$url/files/pictures"] = d('@server_master')->web_group; $chgrp["sites/$url/files/pictures"] = d('@server_master')->web_group;
// d7 support // d7 support
$mkdir["sites/$url/private"] = 02770; $mkdir["sites/$url/private"] = 02770;
$chown["sites/$url/private"] = d('@server_master')->script_user;
$chgrp["sites/$url/private"] = d('@server_master')->web_group; $chgrp["sites/$url/private"] = d('@server_master')->web_group;
$mkdir["sites/$url/private/files"] = 02770; $mkdir["sites/$url/private/files"] = 02770;
$chown["sites/$url/private/files"] = d('@server_master')->script_user;
$chgrp["sites/$url/private/files"] = d('@server_master')->web_group; $chgrp["sites/$url/private/files"] = d('@server_master')->web_group;
$mkdir["sites/$url/private/temp"] = 02770; $mkdir["sites/$url/private/temp"] = 02770;
$chown["sites/$url/private/temp"] = d('@server_master')->script_user;
$chgrp["sites/$url/private/temp"] = d('@server_master')->web_group; $chgrp["sites/$url/private/temp"] = d('@server_master')->web_group;
} }
...@@ -228,11 +220,6 @@ function _provision_drupal_create_directories($url = NULL, $profile = NULL) { ...@@ -228,11 +220,6 @@ function _provision_drupal_create_directories($url = NULL, $profile = NULL) {
->succeed('Changed permissions of <code>@path</code> to @perm') ->succeed('Changed permissions of <code>@path</code> to @perm')
->fail('Could not change permissions <code>@path</code> to @perm'); ->fail('Could not change permissions <code>@path</code> to @perm');
} }
foreach ($chown as $path => $owner) {
provision_file()->chown($path, $owner, !in_array($path, $not_recursive))
->succeed('Changed ownership of <code>@path</code> to @uid')
->fail('Could not change ownership <code>@path</code>', 'DRUSH_PERM_ERROR');
}
foreach ($chgrp as $path => $group) { foreach ($chgrp as $path => $group) {
provision_file()->chgrp($path, $group, !in_array($path, $not_recursive)) provision_file()->chgrp($path, $group, !in_array($path, $not_recursive))
->succeed('Changed group ownership of <code>@path</code> to @gid') ->succeed('Changed group ownership of <code>@path</code> to @gid')
......
...@@ -46,7 +46,7 @@ function drush_provision_drupal_pre_provision_verify() { ...@@ -46,7 +46,7 @@ function drush_provision_drupal_pre_provision_verify() {
elseif (d()->type === 'platform') { elseif (d()->type === 'platform') {
// create a platform from a makefile, if it doesnt already exist and the makefile does. // create a platform from a makefile, if it doesnt already exist and the makefile does.
if (!provision_file()->exists(d()->root)->status() && !empty(d()->makefile)) { if (!provision_file()->exists(d()->root)->status() && !empty(d()->makefile)) {
drush_log(dt("Platform path does not exists, fetching from drush makefile")); drush_log(dt("Platform path does not exist, fetching from drush makefile"));
$options = array('root' => null, 'uri' => null); $options = array('root' => null, 'uri' => null);
// propagate working-copy args downward // propagate working-copy args downward
if (drush_get_option('working-copy')) { if (drush_get_option('working-copy')) {
......
...@@ -77,7 +77,7 @@ function provision_context_factory($name) { ...@@ -77,7 +77,7 @@ function provision_context_factory($name) {
$type = 'server'; $type = 'server';
$record = provision_sitealias_get_record($name); $record = provision_sitealias_get_record($name);
$options = array_merge(drush_get_context('stdin'), drush_get_context('options')); $options = array_merge(drush_get_context('stdin'), drush_get_context('options'), drush_get_context('cli'));
if (isset($record['context_type'])) { if (isset($record['context_type'])) {
$type = $record['context_type']; $type = $record['context_type'];
...@@ -133,7 +133,7 @@ class provisionContext { ...@@ -133,7 +133,7 @@ class provisionContext {
*/ */
function __get($name) { function __get($name) {
if ($name == 'options') { if ($name == 'options') {
return array_merge(provision_sitealias_get_record($this->name), array_filter(drush_get_context('stdin')), array_filter(drush_get_context('options'))); return array_merge(provision_sitealias_get_record($this->name), array_filter(drush_get_context('stdin')), array_filter(drush_get_context('options')), array_filter(drush_get_context('cli')));
} }
if (array_key_exists($name, $this->properties)) { if (array_key_exists($name, $this->properties)) {
if (isset($this->oid_map[$name]) && !empty($this->properties[$name])) { if (isset($this->oid_map[$name]) && !empty($this->properties[$name])) {
......
...@@ -173,14 +173,13 @@ class provisionContext_server extends provisionContext { ...@@ -173,14 +173,13 @@ class provisionContext_server extends provisionContext {
'relative' => TRUE, 'relative' => TRUE,
'keep-dirlinks' => TRUE, 'keep-dirlinks' => TRUE,
'omit-dir-times' => TRUE, 'omit-dir-times' => TRUE,
'delete' => TRUE,
), $additional_options); ), $additional_options);
// We need to do this due to how drush creates the rsync command. // We need to do this due to how drush creates the rsync command.
// If the option is present at all , even if false or null, it will // If the option is present at all , even if false or null, it will
// add it to the command. // add it to the command.
if (!isset($additional_options['no-delete'])) { if (!isset($additional_options['no-delete']) || $additional_options['no-delete'] == FALSE ) {
$options['delete'] = TRUE; $options['delete'] = TRUE;
} }
......
...@@ -170,6 +170,11 @@ function provision_drush_command() { ...@@ -170,6 +170,11 @@ function provision_drush_command() {
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT
); );
$items['provision-backup_delete'] = array(
'description' => 'Delete a backup file.',
'arguments' => array('backup-file' => dt('The backup file to delete. This will be a gzipped tarball.')),
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH
);
$items['hostmaster-migrate'] = array( $items['hostmaster-migrate'] = array(
'description' => dt('Migrate an instance of the Hostmaster front end to a new platform'), 'description' => dt('Migrate an instance of the Hostmaster front end to a new platform'),
...@@ -203,6 +208,11 @@ function provision_drush_command() { ...@@ -203,6 +208,11 @@ function provision_drush_command() {
'example.com' => dt('The url of the site being migrated.')), 'example.com' => dt('The url of the site being migrated.')),
); );
$items['backend-parse'] = array(
'description' => dt('Parse the output of --backend commands to a human readable form'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
);
return $items; return $items;
} }
......
...@@ -298,6 +298,13 @@ function provision_backend_invoke($target, $command, $arguments = array(), $opti ...@@ -298,6 +298,13 @@ function provision_backend_invoke($target, $command, $arguments = array(), $opti
return drush_backend_invoke_args('@' . ltrim($target, '@') . ' ' . $command, $arguments, $options + array('root' => null, 'uri' => null), $mode); return drush_backend_invoke_args('@' . ltrim($target, '@') . ' ' . $command, $arguments, $options + array('root' => null, 'uri' => null), $mode);
} }
/**
* parse the .ini file to get the aegir version
*/
function provision_version() {
$ini = parse_ini_file(dirname(__FILE__) . '/provision.info');
return $ini['version'];
}
/** /**
* A base class for the service and file handling classes that implements * A base class for the service and file handling classes that implements
......
name=Provision
description="Aegir backend"
version=HEAD
...@@ -83,9 +83,9 @@ sed -i'.tmp' -e'/^projects\[hostmaster\]\[download\]\[type\]/s/=.*$/ = "get"/' \ ...@@ -83,9 +83,9 @@ sed -i'.tmp' -e'/^projects\[hostmaster\]\[download\]\[type\]/s/=.*$/ = "get"/' \
echo changing INSTALL.txt to point to tagged install.sh echo changing INSTALL.txt to point to tagged install.sh
sed -i'.tmp' -e"/http:\/\/git.aegirproject.org\/?p=provision.git;a=blob_plain;f=install.sh.txt;hb=HEAD/s/HEAD/provision-$version/" docs/INSTALL.txt && git add docs/INSTALL.txt && rm docs/INSTALL.txt.tmp sed -i'.tmp' -e"/http:\/\/git.aegirproject.org\/?p=provision.git;a=blob_plain;f=install.sh.txt;hb=HEAD/s/HEAD/provision-$version/" docs/INSTALL.txt && git add docs/INSTALL.txt && rm docs/INSTALL.txt.tmp
echo changing INSTALL.txt to point hostmaster-install --version to tag echo changing hostmaster-install version
sed -i'.tmp' -e"s/--version=HEAD/--version=$version/" docs/INSTALL.txt sed -i'.tmp' -e"s/version *=.*$/version=$version/" provision.info
git add docs/INSTALL.txt && rm docs/INSTALL.txt.tmp git add provision.info && rm provision.info.tmp
echo changing UPGRADE.txt to point to tagged upgrade.sh echo changing UPGRADE.txt to point to tagged upgrade.sh
sed -i'.tmp' -e"/http:\/\/git.aegirproject.org\/?p=provision.git;a=blob_plain;f=upgrade.sh.txt;hb=HEAD/s/HEAD/provision-$version/" docs/UPGRADE.txt && git add docs/UPGRADE.txt && rm docs/UPGRADE.txt.tmp sed -i'.tmp' -e"/http:\/\/git.aegirproject.org\/?p=provision.git;a=blob_plain;f=upgrade.sh.txt;hb=HEAD/s/HEAD/provision-$version/" docs/UPGRADE.txt && git add docs/UPGRADE.txt && rm docs/UPGRADE.txt.tmp
......