diff --git a/hosting.api.php b/hosting.api.php index 31fc154..cc7ed60 100644 --- a/hosting.api.php +++ b/hosting.api.php @@ -461,3 +461,43 @@ function hook_hosting_task_dangerous_tasks_alter(&$tasks) {} /** * @} End of "addtogroup hostinghooks". */ + +/** + * Easily create a new site and a platform by passing just a name and a makefile URL. + * + * To get a new website running from a new codebase in Aegir, you need to create + * a platform, and then a site node. With the latest version, you can use code + * to do both at once. + * + * This function will create a platform node for /var/aegir/mywebservice/$name + * using the $makefile specified, and will then create a site node with the URL + * $name.mywebservice.com. + */ +function example_create_site($name, $makefile) { + + // Create site node. + $site = new stdClass(); + $site->type = 'site'; + $site->title = "{$name}.mywebservice.com"; + $site->status = 1; + $site->uid = 1; + $site->client = HOSTING_DEFAULT_CLIENT; + $site->site_status = HOSTING_SITE_QUEUED; + + // Create a platform node. + $platform_node = new stdClass(); + $platform_node->type = 'platform'; + $platform_node->title = "mywebservice_{$name}"; + $platform_node->publish_path = "/var/aegir/mywebservice/{$name}"; + $platform_node->makefile = $makefile; + + // Attach platform node to site node: + $site->platform_node = $platform_node; + + // Save the site node, along with the platform. + // This is possible thanks to the patch in https://www.drupal.org/node/2824731 + if ($site = node_submit($site)) { + node_save($site); + } + +} \ No newline at end of file diff --git a/package/hosting_package.drush.inc b/package/hosting_package.drush.inc index 60b686f..eee14c8 100644 --- a/package/hosting_package.drush.inc +++ b/package/hosting_package.drush.inc @@ -9,6 +9,40 @@ function drush_hosting_package_pre_hosting_task() { if ($task->ref->type == 'site') { // populate the profile option, if it hasn't been specified yet. if (empty($task->options['profile'])) { + + // If site node "profile_name" property is a string and not empty, lookup + // the profile package NID and save it to the site node. + if (empty($task->ref->profile) && !empty($task->ref->profile_name) && is_string($task->ref->profile_name)) { + $instances = hosting_package_instances_load(array( + 'i.rid' => $task->ref->platform, + 'p.package_type' => 'profile', + 'p.short_name' => $task->ref->profile_name, + )); + + // If instance is found, save the package ID to hosting_site table. + $instance = current($instances); + if (!empty($instance->package_id)) { + db_update('hosting_site') + ->fields(array('profile' => $instance->package_id)) + ->condition('nid', $task->ref->nid) + ->execute(); + + $task->ref->profile = $instance->package_id; + + drush_log(dt('Updated site node !nid with install profile "!profile" with package ID !package_id.', array( + '!nid' => $task->ref->nid, + '!profile' => $task->ref->profile_name, + '!package_id' => $task->ref->profile, + )), 'notice'); + } + else { + drush_log(dt('Package for install profile "!profile" not found for site !nid.', array( + '!nid' => $task->ref->nid, + '!profile' => $task->ref->profile_name, + )), 'warning'); + } + } + $profile = node_load($task->ref->profile); if ($task->task_type != 'import' && $task->task_type != 'delete' && $task->task_type != 'verify') { $task->options['profile'] = $profile->short_name; diff --git a/site/hosting_site.nodeapi.inc b/site/hosting_site.nodeapi.inc index f7dc81f..9813e0e 100644 --- a/site/hosting_site.nodeapi.inc +++ b/site/hosting_site.nodeapi.inc @@ -249,6 +249,72 @@ function hosting_site_insert(&$node) { // Provide a dummy profile, e.g. for hosting-import. $node->profile = isset($node->profile) ? $node->profile : 0; + // If platform NID is not defined, but platform data is available, + // create the platform. + if (empty($node->platform) + && !empty($node->platform_node) + && !empty($node->platform_node->publish_path) + ) { + + // If a platform exists for the given path, use that. + $existing_platform_nid = db_select('hosting_platform', 'p') + ->condition('publish_path', $node->platform_node->publish_path) + ->condition('status', HOSTING_PLATFORM_ENABLED) + ->fields('p', array('nid')) + ->execute() + ->fetchField(); + + // Use the existing platform NID. + if ($existing_platform_nid) { + $node->platform = $existing_platform_nid; + } + // Or prepare a new one. + else { + + // If platform_status hasn't been explicitly set, + // assume platform status matches site status: + // If developer creates a site node that's disabled, + // the platform should be too. + if (!isset($node->platform_node->platform_status) && isset($node->site_status)) { + $node->platform_node->platform_status = $node->site_status; + } + + // If web_server hasn't been explicity set, use hostmaster's web server. + if (!isset($node->platform_node->web_server)) { + $hostmaster = hosting_context_load('hostmaster'); + $hostmaster_platform = node_load($hostmaster->platform); + $node->platform_node->web_server = $hostmaster_platform->web_server; + } + + // If platform title has not been set, generate one from the site title. + if (empty($node->platform_node->title)) { + $node->platform_node->title = 'platform_' . preg_replace("/[!\W]/", "", $node->title); + } + + // If platform UID has not been set, use site UID. + if (empty($node->platform_node->uid)) { + $node->platform_node->uid = $node->uid; + } + + $node->platform_node->type = 'platform'; + if ($node->platform_node = node_submit($node->platform_node)) { + node_save($node->platform_node); + } + $node->platform = $node->platform_node->nid; + } + } + + // If there is no platform NID and no publish path, throw an exception. + if (empty($node->platform) && empty($node->platform_node->publish_path)) { + throw new Exception('Site nodes require either platform or platform_node->publish_path property'); + } + + // If db_server hasn't been explicity set, use hostmaster's web server. + if (!isset($node->platform_node->db_server)) { + $hostmaster = hosting_context_load('hostmaster'); + $node->db_server = $hostmaster->db_server; + } + $id = db_insert('hosting_site') ->fields(array( 'vid' => $node->vid,