Skip to content
This repository has been archived by the owner on Sep 6, 2024. It is now read-only.

Commit

Permalink
Add ability to have a pool of pre-generated PHP environments (#191)
Browse files Browse the repository at this point in the history
* Add table forzpare sites
* Log new site into spare_sites table
* Log app id in spare_sites
* Check if there is an available spare_site
* Do not depend on SP API response data structure. Just use flat array for representing a PHP app
* Do not depend on SP API response data structure. Just use flat array for representing a system user
* Make default PHP version be a setting
* Add Command Line Interface
* Allow to launch a spare site from cli
* Add get_sp_app and update_sp_app
* Make it launch first php app and install WordPress ourselves
* Drop action interface for filterable class name interface for provisioning-specific stuff
* Log user who launched a   site
* Note if site was launched via cli
* Add ability to launch sites taking them from a pool of spare sites
* Add purge command to cli
* Move name generation collision mitigation logic to generate_random_subdomain()
* Do not wait for ssl forcing action
* Add ability to populate pool of spare sites
* Fix case when we do not need to launch more spare sites
* Decouple SSL certificate addition and SSL forced redirection
* Add settinig for disabling spare sites
* Show user that launched the site
* Always register wildcard for sites - Previously wildcard subdomain was only available for subdomain based multisite
* Update debug function to format objects and array
* Just launch one spare site at a time when refreshing the pool
* Delete record of a spare site if the app does not exist anymore
* Avoid race conditions when picking a spare site
* Add setting to disable launching if no spare site available
* Bump version to 5.0
  • Loading branch information
oskosk authored Jun 6, 2020
1 parent d55da83 commit 87ed63a
Show file tree
Hide file tree
Showing 8 changed files with 732 additions and 429 deletions.
52 changes: 32 additions & 20 deletions features/ssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,52 @@
'ssl' => false,
];

add_action( 'jurassic_ninja_add_features_before_auto_login', function( &$app, $features, $domain ) use ( $defaults ) {
add_action( 'jurassic_ninja_add_features_after_create_app', function( &$app, $features, $domain ) use ( $defaults ) {
$features = array_merge( $defaults, $features );
// Currently not used but the code works.
if ( $features['auto_ssl'] ) {
enable_sp_auto_ssl( $app->data->id );
// Currently not a feature of Jurassic Ninja but the code works.
provisioner()->enable_auto_ssl( $app->id );
} else {
$response = provisioner()->add_ssl_certificate( $app->id );
}
}, 10, 3 );

add_action( 'jurassic_ninja_add_features_before_auto_login', function( &$app = null, $features, $domain ) use ( $defaults ) {
// We can't easily enable SSL for subodmains because
// wildcard certificates don't support multiple levels of subdomains
// and this can result in awful experience.
// Need to explorer a little bit better
if ( $features['ssl'] && ! $features['subdomain_multisite'] ) {
// Need to explore a little bit better

if ( $features['ssl'] && ! ( isset( $features['subdomain_multisite'] ) && $features['subdomain_multisite'] ) ) {
$features = array_merge( $defaults, $features );
if ( $features['auto_ssl'] ) {
debug( 'Both ssl and auto_ssl features were requested. Ignoring ssl and launching with auto_ssl' );
} else {
debug( '%s: Enabling custom SSL', $domain );
$response = enable_sp_ssl( $app->data->id );
if ( is_wp_error( $response ) ) {
debug( 'Error enabling SSL for %s. Check the next log line for a dump of the WP_Error', $domain );
// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_print_r
debug( print_r( $response, true ) );
// phpcs:enable
throw new \Exception( 'Error enabling SSL: ' . $response->get_error_message() );
}
debug( '%s: Setting home and siteurl options', $domain );
set_home_and_site_url( $domain );
debug( 'Both ssl and auto_ssl features were requested. Ignoring ssl and launching with custom SSL' );
}
debug( '%s: Enabling custom SSL', $domain );

$response = provisioner()->force_ssl_redirection( $app->id );

if ( is_wp_error( $response ) ) {
throw new \Exception( 'Error enabling SSL: ' . $response->get_error_message() );
}

debug( '%s: Setting home and siteurl options to account for SSL', $domain );
set_home_and_site_url( $domain );
}
}, 10, 3 );
add_filter( 'jurassic_ninja_rest_feature_defaults', function( $defaults ) {
return array_merge( $defaults, [

add_filter( 'jurassic_ninja_rest_feature_defaults', function( $rest_default_features ) use ( $defaults ) {
return array_merge( $defaults, $rest_default_features, [
'ssl' => (bool) settings( 'ssl_use_custom_certificate', false ),
] );
} );

add_filter( 'jurassic_ninja_rest_create_request_features', function( $features, $json_params ) {
return array_merge( $features, [
'ssl' => $features['ssl'] && ( isset( $json_params['ssl'] ) ? $json_params['ssl'] : true ),
] );
}, 10, 2 );

add_filter( 'jurassic_ninja_created_site_url', function( $domain, $features ) {
// See note in launch_wordpress() about why we can't launch subdomain_multisite with ssl.
$schema = ( $features['ssl'] && ! $features['subdomain_multisite'] ) ? 'https' : 'http';
Expand Down
10 changes: 9 additions & 1 deletion jurassic.ninja.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*
* Plugin Name: Jurassic Ninja
* Description: Launch ephemeral instances of WordPress + Jetpack using ServerPilot and an Ubuntu Box.
* Version: 4.19.3
* Version: 5.0
* Author: Automattic
**/

Expand Down Expand Up @@ -32,6 +32,10 @@ function init() {
require_once __DIR__ . '/lib/settings-stuff.php';
require_once __DIR__ . '/lib/stuff.php';

if ( is_cli_running() ) {
require_once __DIR__ . '/lib/cli-stuff.php';
}

/**
* Done before adding settings page or anything else related to Jurassic Ninja Admin specifics.
*
Expand Down Expand Up @@ -67,6 +71,10 @@ function init() {
create_tables( __FILE__ );
}

function is_cli_running() {
return defined( 'WP_CLI' ) && WP_CLI;
}

/**
* Checks if the vendor directory is present and just shows a warning and quits if it's not the case.
* This can probably be removed if it makes sense to just include dependencies.
Expand Down
67 changes: 67 additions & 0 deletions lib/cli-stuff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace jn;

if ( ! defined( '\\ABSPATH' ) ) {
exit;
}

/**
* Comand Line Interface to Jurassic Ninja's deeds.
*/
class JN_CLI_Command extends \WP_CLI_Command {
/**
* Launch a spare site.
*/
public function launch( $args ) {
if ( count( $args ) ) {
if ( $args[0] === 'spare' ) {
\WP_CLI::line( 'Launching a spare site' );
}
$app = launch_wordpress( 'default', [], true );
\WP_CLI::line( sprintf( 'Launched spare site', $app->domains[0] ) );
return;
}
try {
$app = launch_wordpress( 'default', [ 'ssl' => true ] );
if ( !$app ) {
throw new \Exception();
}
\WP_CLI::line( sprintf( 'Launched %s', $app->domains[0] ) );

} catch ( \Exception $e ) {
\WP_CLI::line( sprintf( 'Error launching site' ) );
}
}

/**
* Run the purge job.
*/
public function purge( $args ) {
try {
$purged = purge_sites();
if ( is_array( $purged ) && count( $purged ) ) {
\WP_CLI::line( sprintf( 'Purged %s Jurassic Ninja site(s).', count( $purged ) ) );
} else {
\WP_CLI::line( sprintf( "There weren't any sites to purge" ) );
}

} catch ( \Exception $e ) {
\WP_CLI::line( sprintf( 'Error purging Jurassic Ninja sites' ) );
}
}

/**
* Refresh the spare sites pooll.
*/
public function pool( $args ) {
try {
maintain_spare_sites_pool();
\WP_CLI::line( sprintf( "Spare sites pool was refreshed" ) );
} catch ( \Exception $e ) {
\WP_CLI::line( sprintf( 'Error refreshing the spare sites pool' ) );
}
}
}

\WP_CLI::add_command( 'jn', 'jn\JN_CLI_Command' );
27 changes: 21 additions & 6 deletions lib/db-stuff.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,39 @@ function jurassic_ninja_create_table() {

$charset_collate = $wpdb->get_charset_collate();

$sql = "CREATE TABLE sites (
$sites_sql = "CREATE TABLE sites (
`id` INT NOT NULL AUTO_INCREMENT,
username text not null,
password text not null,
domain text not null,
created datetime ,
last_logged_in datetime ,
last_logged_in datetime,
checked_in datetime,
shortlived boolean not null DEFAULT 0,
launched_by text not null,
PRIMARY KEY (id)
) $charset_collate;";

$sql2 = "CREATE TABLE purged (
$purged_sites_sql = "CREATE TABLE purged (
`id` INT NOT NULL AUTO_INCREMENT,
username text not null,
domain text not null,
created datetime ,
last_logged_in datetime ,
last_logged_in datetime,
checked_in datetime,
shortlived boolean not null DEFAULT 0,
launched_by text not null,
PRIMARY KEY (id)
) $charset_collate;";

$spare_sites_sql = "CREATE TABLE spare_sites (
`id` INT NOT NULL AUTO_INCREMENT,
username text not null,
password text not null,
domain text not null,
created datetime,
app_id text not null,
locked_by text not null,
PRIMARY KEY (id)
) $charset_collate;";

Expand All @@ -57,8 +71,9 @@ function jurassic_ninja_create_table() {

try {
// phpcs:disable Generic.PHP.NoSilencedErrors.Discouraged
@dbDelta( $sql );
@dbDelta( $sql2 );
@dbDelta( $sites_sql );
@dbDelta( $purged_sites_sql );
@dbDelta( $spare_sites_sql );
// phpcs:enable

} catch ( \Exception $e ) {
Expand Down
Loading

0 comments on commit 87ed63a

Please sign in to comment.