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

Commit 87ed63a

Browse files
authored
Add ability to have a pool of pre-generated PHP environments (#191)
* 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
1 parent d55da83 commit 87ed63a

File tree

8 files changed

+732
-429
lines changed

8 files changed

+732
-429
lines changed

features/ssl.php

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,52 @@
88
'ssl' => false,
99
];
1010

11-
add_action( 'jurassic_ninja_add_features_before_auto_login', function( &$app, $features, $domain ) use ( $defaults ) {
11+
add_action( 'jurassic_ninja_add_features_after_create_app', function( &$app, $features, $domain ) use ( $defaults ) {
1212
$features = array_merge( $defaults, $features );
13-
// Currently not used but the code works.
1413
if ( $features['auto_ssl'] ) {
15-
enable_sp_auto_ssl( $app->data->id );
14+
// Currently not a feature of Jurassic Ninja but the code works.
15+
provisioner()->enable_auto_ssl( $app->id );
16+
} else {
17+
$response = provisioner()->add_ssl_certificate( $app->id );
1618
}
19+
}, 10, 3 );
20+
21+
add_action( 'jurassic_ninja_add_features_before_auto_login', function( &$app = null, $features, $domain ) use ( $defaults ) {
1722
// We can't easily enable SSL for subodmains because
1823
// wildcard certificates don't support multiple levels of subdomains
1924
// and this can result in awful experience.
20-
// Need to explorer a little bit better
21-
if ( $features['ssl'] && ! $features['subdomain_multisite'] ) {
25+
// Need to explore a little bit better
26+
27+
if ( $features['ssl'] && ! ( isset( $features['subdomain_multisite'] ) && $features['subdomain_multisite'] ) ) {
28+
$features = array_merge( $defaults, $features );
2229
if ( $features['auto_ssl'] ) {
23-
debug( 'Both ssl and auto_ssl features were requested. Ignoring ssl and launching with auto_ssl' );
24-
} else {
25-
debug( '%s: Enabling custom SSL', $domain );
26-
$response = enable_sp_ssl( $app->data->id );
27-
if ( is_wp_error( $response ) ) {
28-
debug( 'Error enabling SSL for %s. Check the next log line for a dump of the WP_Error', $domain );
29-
// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_print_r
30-
debug( print_r( $response, true ) );
31-
// phpcs:enable
32-
throw new \Exception( 'Error enabling SSL: ' . $response->get_error_message() );
33-
}
34-
debug( '%s: Setting home and siteurl options', $domain );
35-
set_home_and_site_url( $domain );
30+
debug( 'Both ssl and auto_ssl features were requested. Ignoring ssl and launching with custom SSL' );
31+
}
32+
debug( '%s: Enabling custom SSL', $domain );
33+
34+
$response = provisioner()->force_ssl_redirection( $app->id );
35+
36+
if ( is_wp_error( $response ) ) {
37+
throw new \Exception( 'Error enabling SSL: ' . $response->get_error_message() );
3638
}
39+
40+
debug( '%s: Setting home and siteurl options to account for SSL', $domain );
41+
set_home_and_site_url( $domain );
3742
}
3843
}, 10, 3 );
39-
add_filter( 'jurassic_ninja_rest_feature_defaults', function( $defaults ) {
40-
return array_merge( $defaults, [
44+
45+
add_filter( 'jurassic_ninja_rest_feature_defaults', function( $rest_default_features ) use ( $defaults ) {
46+
return array_merge( $defaults, $rest_default_features, [
4147
'ssl' => (bool) settings( 'ssl_use_custom_certificate', false ),
4248
] );
4349
} );
4450

51+
add_filter( 'jurassic_ninja_rest_create_request_features', function( $features, $json_params ) {
52+
return array_merge( $features, [
53+
'ssl' => $features['ssl'] && ( isset( $json_params['ssl'] ) ? $json_params['ssl'] : true ),
54+
] );
55+
}, 10, 2 );
56+
4557
add_filter( 'jurassic_ninja_created_site_url', function( $domain, $features ) {
4658
// See note in launch_wordpress() about why we can't launch subdomain_multisite with ssl.
4759
$schema = ( $features['ssl'] && ! $features['subdomain_multisite'] ) ? 'https' : 'http';

jurassic.ninja.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/*
44
* Plugin Name: Jurassic Ninja
55
* Description: Launch ephemeral instances of WordPress + Jetpack using ServerPilot and an Ubuntu Box.
6-
* Version: 4.19.3
6+
* Version: 5.0
77
* Author: Automattic
88
**/
99

@@ -32,6 +32,10 @@ function init() {
3232
require_once __DIR__ . '/lib/settings-stuff.php';
3333
require_once __DIR__ . '/lib/stuff.php';
3434

35+
if ( is_cli_running() ) {
36+
require_once __DIR__ . '/lib/cli-stuff.php';
37+
}
38+
3539
/**
3640
* Done before adding settings page or anything else related to Jurassic Ninja Admin specifics.
3741
*
@@ -67,6 +71,10 @@ function init() {
6771
create_tables( __FILE__ );
6872
}
6973

74+
function is_cli_running() {
75+
return defined( 'WP_CLI' ) && WP_CLI;
76+
}
77+
7078
/**
7179
* Checks if the vendor directory is present and just shows a warning and quits if it's not the case.
7280
* This can probably be removed if it makes sense to just include dependencies.

lib/cli-stuff.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace jn;
4+
5+
if ( ! defined( '\\ABSPATH' ) ) {
6+
exit;
7+
}
8+
9+
/**
10+
* Comand Line Interface to Jurassic Ninja's deeds.
11+
*/
12+
class JN_CLI_Command extends \WP_CLI_Command {
13+
/**
14+
* Launch a spare site.
15+
*/
16+
public function launch( $args ) {
17+
if ( count( $args ) ) {
18+
if ( $args[0] === 'spare' ) {
19+
\WP_CLI::line( 'Launching a spare site' );
20+
}
21+
$app = launch_wordpress( 'default', [], true );
22+
\WP_CLI::line( sprintf( 'Launched spare site', $app->domains[0] ) );
23+
return;
24+
}
25+
try {
26+
$app = launch_wordpress( 'default', [ 'ssl' => true ] );
27+
if ( !$app ) {
28+
throw new \Exception();
29+
}
30+
\WP_CLI::line( sprintf( 'Launched %s', $app->domains[0] ) );
31+
32+
} catch ( \Exception $e ) {
33+
\WP_CLI::line( sprintf( 'Error launching site' ) );
34+
}
35+
}
36+
37+
/**
38+
* Run the purge job.
39+
*/
40+
public function purge( $args ) {
41+
try {
42+
$purged = purge_sites();
43+
if ( is_array( $purged ) && count( $purged ) ) {
44+
\WP_CLI::line( sprintf( 'Purged %s Jurassic Ninja site(s).', count( $purged ) ) );
45+
} else {
46+
\WP_CLI::line( sprintf( "There weren't any sites to purge" ) );
47+
}
48+
49+
} catch ( \Exception $e ) {
50+
\WP_CLI::line( sprintf( 'Error purging Jurassic Ninja sites' ) );
51+
}
52+
}
53+
54+
/**
55+
* Refresh the spare sites pooll.
56+
*/
57+
public function pool( $args ) {
58+
try {
59+
maintain_spare_sites_pool();
60+
\WP_CLI::line( sprintf( "Spare sites pool was refreshed" ) );
61+
} catch ( \Exception $e ) {
62+
\WP_CLI::line( sprintf( 'Error refreshing the spare sites pool' ) );
63+
}
64+
}
65+
}
66+
67+
\WP_CLI::add_command( 'jn', 'jn\JN_CLI_Command' );

lib/db-stuff.php

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,39 @@ function jurassic_ninja_create_table() {
2929

3030
$charset_collate = $wpdb->get_charset_collate();
3131

32-
$sql = "CREATE TABLE sites (
32+
$sites_sql = "CREATE TABLE sites (
3333
`id` INT NOT NULL AUTO_INCREMENT,
3434
username text not null,
35+
password text not null,
3536
domain text not null,
3637
created datetime ,
37-
last_logged_in datetime ,
38+
last_logged_in datetime,
3839
checked_in datetime,
3940
shortlived boolean not null DEFAULT 0,
41+
launched_by text not null,
4042
PRIMARY KEY (id)
4143
) $charset_collate;";
4244

43-
$sql2 = "CREATE TABLE purged (
45+
$purged_sites_sql = "CREATE TABLE purged (
4446
`id` INT NOT NULL AUTO_INCREMENT,
4547
username text not null,
4648
domain text not null,
4749
created datetime ,
48-
last_logged_in datetime ,
50+
last_logged_in datetime,
4951
checked_in datetime,
5052
shortlived boolean not null DEFAULT 0,
53+
launched_by text not null,
54+
PRIMARY KEY (id)
55+
) $charset_collate;";
56+
57+
$spare_sites_sql = "CREATE TABLE spare_sites (
58+
`id` INT NOT NULL AUTO_INCREMENT,
59+
username text not null,
60+
password text not null,
61+
domain text not null,
62+
created datetime,
63+
app_id text not null,
64+
locked_by text not null,
5165
PRIMARY KEY (id)
5266
) $charset_collate;";
5367

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

5872
try {
5973
// phpcs:disable Generic.PHP.NoSilencedErrors.Discouraged
60-
@dbDelta( $sql );
61-
@dbDelta( $sql2 );
74+
@dbDelta( $sites_sql );
75+
@dbDelta( $purged_sites_sql );
76+
@dbDelta( $spare_sites_sql );
6277
// phpcs:enable
6378

6479
} catch ( \Exception $e ) {

0 commit comments

Comments
 (0)