Commit dfa824f7 authored by Jon Pugh's avatar Jon Pugh

Merge branch '7.x-3.x' into 2754069-decouple-install-alternate

parents 326e1b6c e10d629c
# Is performed before the scripts in the stages step
before_script:
- source /etc/profile
# Defines stages which are to be executed
stages:
- build
- test
- publish
- upgradetest
# Stage "build"
build:deb:
stage: build
image: aegir/hostmaster:packaging_base
script:
- export commit=$(git log -n 1 --oneline | sed 's/ .*$//')
- export version=$(sed -ne 's/^[^(]*(\([^)]*\)).*/\1/;1p' debian/changelog)
- export new_version="${version}+${CI_BUILD_ID}.${commit}"
- dch -D unstable --newversion "$new_version" "automatic GitLab CI build ${CI_BUILD_ID}"
- dpkg-buildpackage
- mkdir build
- mv -v ../aegir3*.deb build/
- mv -v ../aegir3*.tar.gz build/
- mv -v ../aegir3*.dsc build/
- mv -v ../aegir3*.changes build/
# The files which are to be made available in GitLab as artifacts.
artifacts:
paths:
- build/*
# Stage "test"
test:debian-jessie-aegir3-apt:
stage: test
image: debian:jessie
dependencies:
- build:deb
before_script:
- apt-get update
# Avoid ERROR: invoke-rc.d: policy-rc.d denied execution of start.
- echo "#!/bin/sh" > /usr/sbin/policy-rc.d
- echo "exit 0" >> /usr/sbin/policy-rc.d
- apt-get install --yes sudo curl
script: "scripts/ci-aegir-dev-install-apt-debian8.sh"
test:debian-stretch-aegir3-apt:
stage: test
image: debian:stretch
allow_failure: true
dependencies:
- build:deb
only:
- 7.x-3.x
before_script:
- apt-get update
# Avoid ERROR: invoke-rc.d: policy-rc.d denied execution of start.
- echo "#!/bin/sh" > /usr/sbin/policy-rc.d
- echo "exit 0" >> /usr/sbin/policy-rc.d
- apt-get install --yes sudo curl
script: "scripts/ci-aegir-dev-install-apt-debian9.sh"
test:ubuntu-xenial-aegir3-apt:
stage: test
image: ubuntu:xenial
dependencies:
- build:deb
only:
- 7.x-3.x
before_script:
- apt-get update
# Avoid ERROR: invoke-rc.d: policy-rc.d denied execution of start.
- echo "#!/bin/sh" > /usr/sbin/policy-rc.d
- echo "exit 0" >> /usr/sbin/policy-rc.d
- apt-get install --yes sudo curl
script: "scripts/ci-aegir-dev-install-apt-ubuntu.sh"
test:behat:
stage: test
image: aegir/hostmaster:packaging_base
dependencies:
- build:deb
allow_failure: true
variables:
AEGIR_TESTS_VERSION: "master"
before_script:
- sudo apt-get update
- sudo apt-get install --yes apt-transport-https ca-certificates curl gnupg2 software-properties-common
- curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
- sudo apt-key fingerprint 0EBFCD88
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
- sudo apt-get update
- sudo apt-get install --yes docker-ce
- docker info
- git clone http://github.com/aegir-project/tests.git tests
- cd tests
- git checkout $AEGIR_TESTS_VERSION
# Run prepare scripts.
- cd travis
- sudo bash prepare-docker.sh
- bash prepare-testenv.sh
script:
# Tests are included in the docker-compose.yml file in the tests repo.
- sudo docker-compose -f docker-compose-provision.yml run hostmaster
publish:unstable-repo:
stage: publish
dependencies:
- build:deb
allow_failure: true
only:
- 7.x-3.x
image: ruby:2.1
before_script:
# install ssh-agent
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# run ssh-agent
- eval $(ssh-agent -s)
# add ssh key stored in SSH_PRIVATE_KEY variable to the agent store
- ssh-add <(echo "$SSH_PRIVATE_KEY")
- mkdir -p ~/.ssh
- ls -la /.dockerenv
- echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts
- cat ~/.ssh/known_hosts
script:
- ls -lah build/*
- scp build/* ci@aegir0.aegir.coop:/var/www/repos/incoming/
# reprepro should pick this up in seconds and update the repository index.
# Upgrade the latest stable Aegir to our unstable repo.
upgradetest:debian-jessie-aegir3-apt-upgrade:
stage: upgradetest
image: debian:jessie
dependencies:
- publish:unstable-repo
when: manual
before_script:
- apt-get update
# Avoid ERROR: invoke-rc.d: policy-rc.d denied execution of start.
- echo "#!/bin/sh" > /usr/sbin/policy-rc.d
- echo "exit 0" >> /usr/sbin/policy-rc.d
- apt-get install --yes sudo curl cron
script:
- "scripts/ci-aegir-stable-install-apt-debian8.sh"
# extra step to run the task queue.
- sudo su aegir --login --command 'drush @hostmaster php-eval "echo hosting_task_count();"'
- sudo su aegir --login --command 'drush @hostmaster hosting-tasks --force'
- sudo su aegir --login --command 'drush @hostmaster php-eval "echo hosting_task_count();"'
- sudo su aegir --login --command 'drush @hostmaster hosting-tasks --force'
- sudo su aegir --login --command 'drush @hostmaster php-eval "echo hosting_task_count();"'
- sudo su aegir --login --command 'drush @hostmaster php-eval "echo hosting_task_count_running();"'
- sleep 2m
- sudo su aegir --login --command 'drush @hostmaster php-eval "echo hosting_task_count_running();"'
# upgrade to the latest version from the unstable repo.
- rm -v /etc/apt/sources.list.d/aegir-stable.list
- echo "deb http://debian2.aegirproject.org unstable main" | sudo tee -a /etc/apt/sources.list.d/aegir-unstable.list
- sudo apt-get update
- sudo apt-get --yes upgrade
......@@ -167,6 +167,11 @@ class Provision_Config {
* array.
*/
private function render_template($template, $variables) {
// Allow modules to alter the variables before writing to the template.
// @see hook_provision_config_variables_alter()
drush_command_invoke_all_ref('provision_config_variables_alter', $variables, $template, $this);
drush_errors_off();
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
ob_start(); // Start output buffering
......
......@@ -18,6 +18,14 @@ class Provision_Config_Drushrc_Alias extends Provision_Config_Drushrc {
*/
function __construct($context, $data = array()) {
parent::__construct($context, $data);
if (is_array($data['aliases'])) {
$data['aliases'] = array_unique($data['aliases']);
}
if (is_array($data['drush_aliases'])) {
$data['drush_aliases'] = array_unique($data['drush_aliases']);
}
$this->data = array(
'aliasname' => ltrim($context, '@'),
'options' => $data,
......
......@@ -55,7 +55,13 @@ class Provision_Service extends Provision_ChainedState {
}
// All services have the ability to have an associated restart command and listen port.
/**
* All services have the ability to have an associated restart command and listen port.
*
* If services require a fixed path config file, implement the function symlink_service() inside this method.
*
* @See Provision_Service_http_public::init_server()
*/
function init_server() {
if (!is_null($this->service)) {
if ($this->has_port) {
......@@ -336,4 +342,27 @@ class Provision_Service extends Provision_ChainedState {
static function option_documentation() {
return array();
}
/**
* Save symlink for this server from /var/aegir/config/APPLICATION_NAME.conf -> /var/aegir/config/SERVER/APPLICATION_NAME.conf
*
* If service requires a fixed path config file, implement this function in the init_server() method.
*
* @See Provision_Service_http_public::init_server()
*/
function symlink_service() {
$file = $this->application_name . '.conf';
// We link the app_name.conf file on the remote server to the right version.
$cmd = sprintf('ln -sf %s %s',
escapeshellarg($this->server->config_path . '/' . $file),
escapeshellarg($this->server->aegir_root . '/config/' . $file)
);
if ($this->server->shell_exec($cmd)) {
drush_log(dt("Created symlink for %file on %server", array(
'%file' => $file,
'%server' => $this->server->remote_host,
)), 'notice');
};
}
}
......@@ -34,4 +34,6 @@ Other documentation for developers is also available at:
http://docs.aegirproject.org/en/3.x/extend/
Build status: [![Build Status](https://travis-ci.org/aegir-project/provision.svg?branch=7.x-3.x)](https://travis-ci.org/aegir-project/provision)
Build status Travis: [![Build Status](https://travis-ci.org/aegir-project/provision.svg?branch=7.x-3.x)](https://travis-ci.org/aegir-project/provision) (in-depth and manual install)
Build status GitLab CI: [![build status](https://gitlab.com/aegir/provision/badges/7.x-3.x/build.svg)](https://gitlab.com/aegir/provision/commits/7.x-3.x) (debian packages)
......@@ -5,6 +5,7 @@ api = 2
projects[drupal][type] = "core"
; The release.sh script updates the version of hostmaster.
projects[hostmaster][version] = "7.x-3.0-dev"
projects[hostmaster][type] = "profile"
projects[hostmaster][variant] = "projects"
projects[hostmaster][download][type] = "git"
projects[hostmaster][download][tag] = "7.x-3.0-dev"
projects[hostmaster][download][url] = "http://git.drupal.org/project/hostmaster.git"
aegir3-provision (3.11~beta2) unstable; urgency=medium
* Preparations for the 3.11 release, testing the GitLab build process.
* Many bugfixes and UI improvements, see http://aegir.readthedocs.org/en/3.x/release-notes/3.11
-- Herman van Rink <helmo@initfour.nl> Tue, 23 May 2017 11:13:35 +0200
aegir3-provision (3.11~beta1) unstable; urgency=medium
* Preparations for the 3.11 release, testing the GitLab build process.
* Many bugfixes and UI improvements, see http://aegir.readthedocs.org/en/3.x/release-notes/3.11
-- Herman van Rink <helmo@initfour.nl> Thu, 18 May 2017 14:28:24 +0200
aegir3-provision (3.10) unstable; urgency=medium
* Many bugfixes and UI improvements, see http://aegir.readthedocs.org/en/3.x/release-notes/3.10
-- Herman van Rink <helmo@initfour.nl> Thu, 16 Mar 2017 11:08:16 +0100
aegir3-provision (3.9) unstable; urgency=medium
* Makefile tweaks to allow for minor releases to update Drupal core
* Many bugfixes and UI improvements, see http://aegir.readthedocs.org/en/3.x/release-notes/3.9
-- Herman van Rink <helmo@initfour.nl> Thu, 05 Jan 2017 20:23:06 +0100
aegir3-provision (3.9~beta1) unstable; urgency=medium
* Preparations for the 3.9 release
......
......@@ -11,7 +11,7 @@ Vcs-browser: http://drupalcode.org/project/provision.git
Package: aegir3-provision
Architecture: all
Depends: ${misc:Depends}, php5-cli (>= 5.3) | php7.0-cli, php5-mysql | php7.0-mysql, mysql-client | mariadb-client, sudo, postfix | mail-transport-agent, apache2 | nginx, adduser, ucf, curl
Depends: ${misc:Depends}, php5-cli (>= 5.3) | php7.0-cli, php5 | php7.0-xml, php5-mysql | php7.0-mysql, mysql-client | mariadb-client, sudo, postfix | mail-transport-agent, apache2 | nginx, adduser, ucf, curl
Recommends: mysql-server | mariadb-server, rsync
Conflicts: aegir-provision, aegir-provision2, aegir2-provision
Replaces: aegir-provision, aegir-provision2, aegir2-provision
......
......@@ -17,18 +17,30 @@ NameVirtualHost *:<?php print $http_port; ?>
LoadModule rewrite_module modules/mod_rewrite.so
</IfModule>
<?php
if (drush_get_option('provision_apache_conf_suffix', FALSE)) {
$include_statement = 'IncludeOptional ';
$include_suffix = '/*.conf';
}
else {
$include_statement = 'Include ';
$include_suffix = '';
}
?>
# other configuration, not touched by aegir
# this allows you to override aegir configuration, as it is included before
Include <?php print $http_pred_path ?>
<?php print $include_statement . $http_pred_path . $include_suffix ?>
# virtual hosts
Include <?php print $http_vhostd_path ?>
<?php print $include_statement . $http_vhostd_path . $include_suffix ?>
# platforms
Include <?php print $http_platformd_path ?>
<?php print $include_statement . $http_platformd_path . $include_suffix ?>
# other configuration, not touched by aegir
# this allows to have default (for example during migrations) that are eventually overriden by aegir
Include <?php print $http_postd_path ?>
<?php print $include_statement . $http_postd_path . $include_suffix ?>
<?php print $extra_config; ?>
......@@ -16,23 +16,6 @@ class Provision_Config_Http_Server extends Provision_Config_Http {
function write() {
parent::write();
if (isset($this->data['application_name'])) {
$file = $this->data['application_name'] . '.conf';
// We link the app_name.conf file on the remote server to the right version.
$cmd = sprintf('ln -sf %s %s',
escapeshellarg($this->data['server']->config_path . '/' . $file),
escapeshellarg($this->data['server']->aegir_root . '/config/' . $file)
);
if ($this->data['server']->shell_exec($cmd)) {
drush_log(dt("Created symlink for %file on %server", array(
'%file' => $file,
'%server' => $this->data['server']->remote_host,
)));
};
}
}
function filename() {
......
......@@ -11,7 +11,12 @@ class Provision_Config_Http_Site extends Provision_Config_Http {
function filename() {
return $this->data['http_vhostd_path'] . '/' . $this->uri;
if (drush_get_option('provision_apache_conf_suffix', FALSE)) {
return $this->data['http_vhostd_path'] . '/' . $this->uri . '.conf';
}
else {
return $this->data['http_vhostd_path'] . '/' . $this->uri;
}
}
function process() {
......
......@@ -60,6 +60,14 @@ class Provision_Config_Http_Ssl_Site extends Provision_Config_Http_Site {
if ($this->ssl_enabled) {
// XXX: to be tested, not sure the data structure is sound
//
// ACHTUNG! This deletes even perfectly good certificate and key.
// There is no check in place to determine if the cert is "stale".
// Not sure what the idea was behind this cleanup, but it looks like
// an unfinished work, aggressively deleting existing cert/key pair,
// even if there is absolutely no reason to do so -- like when the site
// is simply migrated to another platform, while its name doesn't change.
//
Provision_Service_http_ssl::free_certificate_site($this->ssl_key, $this);
}
}
......
......@@ -1189,7 +1189,17 @@ location @drupal {
return 418;
}
<?php endif; ?>
rewrite ^/(.*)$ /index.php?q=$1 last;
###
### For Drupal >= 7
###
if ($sent_http_x_generator) {
add_header X-Info-Gen "Modern";
rewrite ^ /index.php?$query_string last;
}
###
### For Drupal <= 6
###
rewrite ^/(.*)$ /index.php?q=$1 last;
}
<?php if ($nginx_config_mode == 'extended'): ?>
......@@ -1198,11 +1208,11 @@ location @drupal {
###
location @nobots {
###
### Support for Accelerated Mobile Pages (AMP).
### Support for Accelerated Mobile Pages (AMP) when bots are redirected below
###
if ( $query_string ~ "^amp$" ) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
# if ( $query_string ~ "^amp$" ) {
# rewrite ^/(.*)$ /index.php?q=$1 last;
# }
###
### Send all known bots to $args free URLs (optional)
......@@ -1218,7 +1228,18 @@ location @nobots {
if ( $args ~* "=PHP[A-Z0-9]{8}-" ) {
return 404;
}
rewrite ^/(.*)$ /index.php?q=$1 last;
###
### For Drupal >= 7
###
if ($sent_http_x_generator) {
add_header X-Info-Gen "Modern";
rewrite ^ /index.php?$query_string last;
}
###
### For Drupal <= 6
###
rewrite ^/(.*)$ /index.php?q=$1 last;
}
###
......
......@@ -288,7 +288,7 @@ map $http_user_agent $deny_on_high_load {
###
map $args $is_denied {
default '';
~*delete.+from|insert.+into|select.+from|union.+select|onload|\.php.+src|system\(.+|document\.cookie|\;|\.\. is_denied;
~*delete.+from|insert.+into|select.+from|union.+select|onload|\.php.+src|system\(.+|document\.cookie|\;|\.\.\/ is_denied;
}
<?php endif; ?>
......
......@@ -1154,6 +1154,16 @@ location @drupal_<?php print $subdir_loc; ?> {
return 418;
}
<?php endif; ?>
###
### For Drupal >= 7
###
if ($sent_http_x_generator) {
add_header X-Info-Gen "Modern";
rewrite ^ /<?php print $subdir; ?>/index.php?$query_string last;
}
###
### For Drupal <= 6
###
rewrite ^/<?php print $subdir; ?>/(.*)$ /<?php print $subdir; ?>/index.php?q=$1 last;
}
......@@ -1163,11 +1173,11 @@ location @drupal_<?php print $subdir_loc; ?> {
###
location @nobots_<?php print $subdir_loc; ?> {
###
### Support for Accelerated Mobile Pages (AMP).
### Support for Accelerated Mobile Pages (AMP) when bots are redirected below
###
if ( $query_string ~ "^amp$" ) {
rewrite ^/<?php print $subdir; ?>/(.*)$ /<?php print $subdir; ?>/index.php?q=$1 last;
}
# if ( $query_string ~ "^amp$" ) {
# rewrite ^/<?php print $subdir; ?>/(.*)$ /<?php print $subdir; ?>/index.php?q=$1 last;
# }
###
### Send all known bots to $args free URLs (optional)
......@@ -1183,6 +1193,17 @@ location @nobots_<?php print $subdir_loc; ?> {
if ( $args ~* "=PHP[A-Z0-9]{8}-" ) {
return 404;
}
###
### For Drupal >= 7
###
if ($sent_http_x_generator) {
add_header X-Info-Gen "Modern";
rewrite ^ /<?php print $subdir; ?>/index.php?$query_string last;
}
###
### For Drupal <= 6
###
rewrite ^/<?php print $subdir; ?>/(.*)$ /<?php print $subdir; ?>/index.php?q=$1 last;
}
......
......@@ -64,7 +64,7 @@ class Provision_Service_http_pack extends Provision_Service_http {
$this->_each_server($this->server->slave_web_servers, __FUNCTION__, array($config));
}
function delete_config($configi, $data = array()) {
function delete_config($config, $data = array()) {
$this->_each_server($this->server->master_web_servers, __FUNCTION__, array($config));
$this->_each_server($this->server->slave_web_servers, __FUNCTION__, array($config));
......
......@@ -57,10 +57,11 @@ class Provision_Service_http_public extends Provision_Service_http {
$this->server->http_vhostd_path = "{$app_dir}/vhost.d";
$this->server->http_subdird_path = "{$app_dir}/subdir.d";
$this->server->http_platforms_path = "{$this->server->aegir_root}/platforms";
$this->symlink_service();
}
}
static function option_documentation() {
return array(
'web_group' => 'server with http: OS group for permissions; working default will be attempted',
......
......@@ -192,6 +192,11 @@ class Provision_Service_http_ssl extends Provision_Service_http_public {
static function free_certificate_site($ssl_key, $site) {
if (empty($ssl_key)) return FALSE;
$ssl_dir = $site->platform->server->http_ssld_path . "/" . $ssl_key . "/";
// Respect hosting_le configuration, if detected -- start
$le_ctrl = d('@server_master')->aegir_root . "/tools/le/.ctrl";
$immutable = $le_ctrl . "/dont-overwrite-" . $site->uri . ".pid";
if (is_link($ssl_dir) || is_file($immutable)) return FALSE;
// Respect hosting_le configuration, if detected -- fin
// 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(
......
......@@ -74,6 +74,11 @@ function _provision_drupal_parse_info_file($filename) {
}
$value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3;
// Remove any invalid UTF-8 sequences to prevent serialization errors.
if (function_exists('mb_convert_encoding')) {
$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
}
// Parse array syntax
$keys = preg_split('/\]?\[/', rtrim($key, ']'));
$last = array_pop($keys);
......@@ -188,3 +193,80 @@ function _provision_drupal_system_map() {
drush_log(dt("Found !count themes", array('!count' => sizeof($packages['themes']))));
return $packages;
}
/**
* Find available profiles on this platform.
*/
function _provision_find_profiles() {
$profiles = array();
include_once('includes/install.inc');
$profiles_subdirs[] = "./profiles";
foreach($profiles_subdirs as $profiles_subdir) {
if (!$dir = opendir($profiles_subdir)) {
drush_log(dt("Cannot find profiles directory"), 'error');
return FALSE;
}
while (FALSE !== ($name = readdir($dir))) {
$languages = array();
if (($name == '..') || ($name == '.') || (!is_dir("$profiles_subdir/$name"))) {
continue;
}
$profile = new stdClass();
$profile->name = $name;
$profile->info = array();
$info_file = "$profiles_subdir/$name/$name.info";
if (file_exists($info_file)) {
$profile->info = provision_parse_info_file($info_file);
// Skip hidden profiles
if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
continue;
}
}
$profile->filename = $info_file;
// Include code from the profile.
if (file_exists($profile_file = "$profiles_subdir/$name/$name.profile")) {
require_once($profile_file);
}
$func = $profile->name . "_profile_details";
if (function_exists($func)) {
$profile->info = array_merge($profile->info, $func());
}
$profile_path = $profiles_subdir . '/' . $name;
$profile->info['languages'] = _provision_find_profile_languages($profile_path);
$profiles[$name] = $profile;
drush_log(dt('Found install profile %name', array('%name' => $name)));
}
}
return $profiles;
}
/**
* Retrieve a list of paths to search in a certain scope
*/
function _provision_drupal_search_paths($scope, $key = '', $type = 'modules') {
$searchpaths = array();
$drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT');
switch ($scope) {
case 'base' :
$searchpaths[] = sprintf("%s/%s", $drupal_root, $type);
$searchpaths[] = sprintf("%s/sites/all/%s", $drupal_root, $type);
break;
default :
if ($key) {
$searchpaths[] = sprintf("%s/%s/%s/%s", $drupal_root, $scope, $key, $type);
}
break;
}
return $searchpaths;
}
......@@ -39,7 +39,12 @@ function _provision_drupal_find_themes($scope, $key = '') {
$files[$name]->template = TRUE;
}
}
$files[$name]->version = $files[$name]->info['version'];
if (!empty($files[$name]->info['version'])) {
$files[$name]->version = $files[$name]->info['version'];
}
else {
$files[$name]->version = NULL;
}
}
return $files;
}
......@@ -77,6 +82,11 @@ function _provision_drupal_parse_info_file($filename) {
}
$value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3;
// Remove any invalid UTF-8 sequences to prevent serialization errors.
if (function_exists('mb_convert_encoding')) {
$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
}
// Parse array syntax
$keys = preg_split('/\]?\[/', rtrim($key, ']'));
$last = array_pop($keys);
......@@ -194,3 +204,86 @@ function _provision_drupal_system_map() {
drush_log(dt("Found !count themes", array('!count' => sizeof($packages['themes']))));
return $packages;
}
/**
* Find available profiles on this platform.
*/
function _provision_find_profiles() {
$profiles = array();
include_once('includes/install.inc');
$profiles_subdirs[] = "./profiles";
foreach($profiles_subdirs as $profiles_subdir) {
if (!$dir = opendir($profiles_subdir)) {
drush_log(dt("Cannot find profiles directory"), 'error');
return FALSE;
}
while (FALSE !== ($name = readdir($dir))) {
$languages = array();
if (($name == '..') || ($name == '.') || (!is_dir("$profiles_subdir/$name"))) {
continue;
}
$profile = new stdClass();
$profile->name = $name;
$profile->info = array();
$info_file = "$profiles_subdir/$name/$name.info";
if (file_exists($info_file)) {
$profile->info = provision_parse_info_file($info_file);
// Skip hidden profiles
if (isset($profile->info['hidden']) && $profile->info['hidden'] == 1) {
continue;
}
}
$profile->filename = $info_file;
// Include code from the profile.
if (file_exists($profile_file = "$profiles_subdir/$name/$name.profile")) {
require_once($profile_file);
}
$func = $profile->name . "_profile_details";
if (function_exists($func)) {
$profile->info = array_merge($profile->info, $func());
}
$profile_path = $profiles_subdir . '/' . $name;
$profile->info['languages'] = _provision_find_profile_languages($profile_path);
// Drupal 7 renamed the default install profile to 'standard'
// Aegir now allows projects to specify an "old short name" to provide an upgrade path when projects get renamed.