Skip to content

Commit 102212e

Browse files
committed
LE generation fix
1 parent edf5919 commit 102212e

File tree

1 file changed

+127
-89
lines changed

1 file changed

+127
-89
lines changed

vscode.php

Lines changed: 127 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function build_le_cert( $user ) {
2020
global $hcpp;
2121
$domain = $this->get_base_domain();
2222

23-
// Check if the LE certificate already exists.
23+
// Check time of existing LE cert. file.
2424
$cert_file = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.pem";
2525
if ( file_exists( $cert_file ) ) {
2626
// Get the file modification time
@@ -36,28 +36,36 @@ public function build_le_cert( $user ) {
3636
}
3737
unlink( $cert_file );
3838
}
39+
40+
// Check if the LE cert. file exists.
41+
if ( file_exists( $cert_file ) ) {
42+
$hcpp->log( "LE certificate already exists for vscode-$user.$domain" );
43+
return;
44+
}
45+
3946
$ip = array_key_first( $hcpp->run( "list-user-ips $user json" ) );
4047

4148
// Get the admin user email address
4249
$email = trim( $hcpp->run( 'list-user admin json' )['admin']['CONTACT'] );
4350

44-
// Swap out nginx.conf and nginx.ssl.conf files to use the LE webroot
45-
$ssl_conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.ssl.conf";
46-
$conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.conf";
47-
$ssl_sav = "/home/$user/conf/web/vscode-$user.$domain/nginx.ssl.sav";
48-
$sav = "/home/$user/conf/web/vscode-$user.$domain/nginx.sav";
49-
rename( $ssl_conf, $ssl_sav );
50-
rename( $conf, $sav );
51-
52-
// Turn off force SSL
53-
$force_ssl_conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.forcessl.conf";
54-
$force_ssl_sav = "/home/$user/conf/web/vscode-$user.$domain/nginx.forcessl.sav";
55-
rename( $force_ssl_conf, $force_ssl_sav );
56-
57-
// Create empty nginx.ssl.conf file
58-
touch( $ssl_conf );
59-
51+
// Clean existing conf files and links
52+
$hcpp->log( "Missing certificate for vscode-$user.$domain; skipping nginx configuration " );
53+
$files = [
54+
"/home/$user/conf/web/vscode-$user.$domain/nginx.ssl.conf",
55+
"/home/$user/conf/web/vscode-$user.$domain/nginx.conf",
56+
"/home/$user/conf/web/vscode-$user.$domain/nginx.forcessl.conf",
57+
"/etc/nginx/conf.d/domains/vscode-$user.$domain.conf",
58+
"/etc/nginx/conf.d/domains/vscode-$user.$domain.ssl.conf"
59+
];
60+
61+
foreach( $files as $file ) {
62+
if ( file_exists( $file ) ) {
63+
unlink( $file );
64+
}
65+
}
66+
6067
// Create nginx.conf that serves up le-webroot folder
68+
$conf = $files[1];
6169
@mkdir( "/home/$user/conf/web/vscode-$user.$domain/le-webroot", 0755, true );
6270
@mkdir( "/home/$user/conf/web/vscode-$user.$domain/ssl", 0755, true );
6371
$content = 'server {
@@ -79,34 +87,36 @@ public function build_le_cert( $user ) {
7987
$hcpp->log( 'Restart nginx to serve le-webroot: ' . shell_exec($cmd) );
8088

8189
// Use certbot to generate the LE certificate
82-
$cmd = "certbot certonly --webroot -w /home/$user/conf/web/vscode-$user.$domain/le-webroot -d vscode-$user.$domain --email $email --agree-tos --non-interactive";
83-
$cmd = $hcpp->do_action( 'vscode_build_le_cert', $cmd );
84-
exec( $cmd, $output, $return_var );
85-
if ( $return_var !== 0 ) {
86-
$hcpp->log("Failed to generate LE certificate: " . implode("\n", $output));
87-
} else {
90+
$cmd = "certbot certonly --webroot -w /home/$user/conf/web/vscode-$user.$domain/le-webroot -d vscode-$user.$domain --email $email --agree-tos --non-interactive 2>&1";
91+
$cmd = $hcpp->do_action( 'vscode_generate_le_cert', $cmd );
92+
$output = shell_exec( $cmd );
93+
$hcpp->log( "Generate LE certificate: " . $output );
94+
95+
$cert_file = "/etc/letsencrypt/live/vscode-$user.$domain/fullchain.pem";
96+
$key_file = "/etc/letsencrypt/live/vscode-$user.$domain/privkey.pem";
97+
$cert_link = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.pem";
98+
$key_link = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.key";
99+
100+
if ( file_exists( $cert_file ) ) {
88101

89102
// Link to the LE certificate and key
90-
$hcpp->log("Successfully generated LE certificate: " . implode("\n", $output));
91-
$cert_file = "/etc/letsencrypt/live/vscode-$user.$domain/fullchain.pem";
92-
$key_file = "/etc/letsencrypt/live/vscode-$user.$domain/privkey.pem";
93-
$cert_link = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.pem";
94-
$key_link = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.key";
103+
$hcpp->log("Successfully generated LE certificate");
95104
@symlink( $cert_file, $cert_link );
96105
@symlink( $key_file, $key_link );
97-
}
98-
99-
// Restore the original nginx.conf and nginx.ssl.conf and force_ssl files
100-
if ( file_exists( $ssl_conf ) ) unlink( $ssl_conf );
101-
rename( $ssl_sav, $ssl_conf );
102-
if ( file_exists( $conf ) ) unlink( $conf );
103-
rename( $sav, $conf );
104-
if ( file_exists( $force_ssl_conf ) ) unlink( $force_ssl_conf );
105-
rename( $force_ssl_sav, $force_ssl_conf );
106+
}else{
107+
$hcpp->log("Failed to generate LE certificate: ");
106108

107-
// Restart nginx to serve vscode- folder
108-
$cmd = '/usr/sbin/service nginx restart 2>&1';
109-
$hcpp->log( 'Restart nginx to serve -vscode: ' . shell_exec($cmd) );
109+
// Cleanup files
110+
$files = [
111+
$cert_link,
112+
$key_link
113+
];
114+
foreach( $files as $file ) {
115+
if ( file_exists( $file ) ) {
116+
unlink( $file );
117+
}
118+
}
119+
}
110120
}
111121

112122
/**
@@ -323,31 +333,55 @@ public function get_most_recently_modified_file( $base_path ) {
323333
*/
324334
public function startup( $user ) {
325335
global $hcpp;
336+
$domain = $this->get_base_domain();
337+
$cert_file = "/home/$user/conf/web/vscode-$user.$domain/ssl/vscode-$user.$domain.pem";
326338

327-
// Check for existing instance of VSCode's "server-main.js" for the user.
328-
$cmd = "ps axo user:20,pid,args | grep \"/opt/vscode/node /opt/vscode/out/server-main.js\" | grep $user | grep -v grep | awk '{print $2}'";
329-
$pid = trim( shell_exec( $cmd ) );
330-
331-
// Start the vscode server for the given user if not already running.
332-
if ( $pid ) {
333-
$hcpp->log( "VSCode server $pid, already running for $user" );
334-
touch( "/home/$user/.openvscode-server/data/token" ); // Keep idle server alive
335-
return;
339+
// Generate website cert if it doesn't exist.
340+
if ( !file_exists( $cert_file) ) {
341+
342+
// Generate website cert if it doesn't exist for Devstia Personal Web edition.
343+
if ( property_exists( $hcpp, 'dev_pw' ) ) {
344+
345+
// Always regenerate the cert to ensure it's up to date.
346+
$hcpp->dev_pw->generate_website_cert( $user, ["vscode-$user.$domain"] );
347+
}else{
348+
349+
// Support LE SSL certs for non-Devstia Personal Web edition.
350+
$this->build_le_cert( $user );
351+
352+
}
336353
}
337-
$hcpp->log( "Setting up VSCode for $user" );
338-
$domain = $this->get_base_domain();
339354

340-
// Get user account first IP address.
341-
$ip = array_key_first( $hcpp->run( "list-user-ips $user json" ) );
355+
// Skip/remove nginx configuration files if cert is missing.
356+
if ( !file_exists( $cert_file ) ) {
357+
$hcpp->log( "Missing certificate for vscode-$user.$domain; skipping nginx configuration " );
358+
$files = [
359+
"/home/$user/conf/web/vscode-$user.$domain/nginx.ssl.conf",
360+
"/home/$user/conf/web/vscode-$user.$domain/nginx.conf",
361+
"/home/$user/conf/web/vscode-$user.$domain/nginx.forcessl.conf",
362+
"/etc/nginx/conf.d/domains/vscode-$user.$domain.conf",
363+
"/etc/nginx/conf.d/domains/vscode-$user.$domain.ssl.conf"
364+
];
342365

343-
// Get a port for the VSCode service.
344-
$port = $hcpp->allocate_port( 'vscode', $user );
366+
foreach( $files as $file ) {
367+
if ( file_exists( $file ) ) {
368+
unlink( $file );
369+
}
370+
}
371+
return;
372+
}
345373

346374
// Create the configuration folder.
347375
if ( ! is_dir( "/home/$user/conf/web/vscode-$user.$domain" ) ) {
348376
mkdir( "/home/$user/conf/web/vscode-$user.$domain" );
349377
}
350378

379+
// Get user account first IP address.
380+
$ip = array_key_first( $hcpp->run( "list-user-ips $user json" ) );
381+
382+
// Get a port for the VSCode service.
383+
$port = $hcpp->allocate_port( 'vscode', $user );
384+
351385
// Create the nginx.conf file.
352386
$conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.conf";
353387
$content = file_get_contents( __DIR__ . '/conf-web/nginx.conf' );
@@ -358,6 +392,12 @@ public function startup( $user ) {
358392
);
359393
file_put_contents( $conf, $content );
360394

395+
// Create the nginx.conf symbolic link.
396+
$link = "/etc/nginx/conf.d/domains/vscode-$user.$domain.conf";
397+
if ( ! is_link( $link ) ) {
398+
symlink( $conf, $link );
399+
}
400+
361401
// Create the nginx.ssl.conf file.
362402
$ssl_conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.ssl.conf";
363403
$content = file_get_contents( __DIR__ . '/conf-web/nginx.ssl.conf' );
@@ -368,48 +408,46 @@ public function startup( $user ) {
368408
);
369409
file_put_contents( $ssl_conf, $content );
370410

371-
// Generate website cert if it doesn't exist for Devstia Personal Web edition.
372-
if ( property_exists( $hcpp, 'dev_pw' ) ) {
373-
374-
// Always regenerate the cert to ensure it's up to date.
375-
$hcpp->dev_pw->generate_website_cert( $user, ["vscode-$user.$domain"] );
376-
}else{
411+
// Create the nginx.ssl.conf symbolic link.
412+
$link = "/etc/nginx/conf.d/domains/vscode-$user.$domain.ssl.conf";
413+
if ( ! is_link( $link ) ) {
414+
symlink( $ssl_conf, $link );
415+
}
377416

378-
// Force SSL on non-Devstia Personal Web edition.
417+
// Create the force SSL conf file on non-Devstia Personal Web edition.
418+
if ( !property_exists( $hcpp, 'dev_pw' ) ) {
379419
$force_ssl_conf = "/home/$user/conf/web/vscode-$user.$domain/nginx.forcessl.conf";
380420
$content = "return 301 https://\$host\$request_uri;";
381421
file_put_contents( $force_ssl_conf, $content );
382-
383-
// Support LE SSL certs for non-Devstia Personal Web edition.
384-
$this->build_le_cert( $user );
385422
}
386423

387-
// Create the nginx.conf configuration symbolic links.
388-
$link = "/etc/nginx/conf.d/domains/vscode-$user.$domain.conf";
389-
if ( ! is_link( $link ) ) {
390-
symlink( $conf, $link );
391-
}
392-
393-
// Create the nginx.ssl.conf configuration symbolic links.
394-
$link = "/etc/nginx/conf.d/domains/vscode-$user.$domain.ssl.conf";
395-
if ( ! is_link( $link ) ) {
396-
symlink( $ssl_conf, $link );
424+
// Check for existing instance of VSCode's "server-main.js" for the user.
425+
$cmd = "ps axo user:20,pid,args | grep \"/opt/vscode/node /opt/vscode/out/server-main.js\" | grep $user | grep -v grep | awk '{print $2}'";
426+
$pid = trim( shell_exec( $cmd ) );
427+
428+
// Start the vscode server for the given user if not already running.
429+
if ( $pid ) {
430+
$hcpp->log( "VSCode server $pid, already running for $user" );
431+
touch( "/home/$user/.openvscode-server/data/token" ); // Keep idle server alive
432+
}else{
433+
$hcpp->log( "Setting up VSCode for $user" );
434+
435+
// Create VSCode token if it doesn't already exist.
436+
$this->update_token( $user );
437+
438+
// Start the VSCode service manually (outside of PM2).
439+
$cmd = 'runuser -l ' . $user . ' -c "';
440+
$cmd .= "(/opt/vscode/node /opt/vscode/out/server-main.js --port $port) > /dev/null 2>&1 &";
441+
$cmd .= '"';
442+
$cmd = $hcpp->do_action( 'vscode_nodejs_cmd', $cmd );
443+
shell_exec( $cmd );
444+
445+
// Reload nginx
446+
$cmd = '(service nginx restart) > /dev/null 2>&1 &';
447+
$cmd = $hcpp->do_action( 'vscode_nginx_restart', $cmd );
448+
shell_exec( $cmd );
397449
}
398450

399-
// Create VSCode token if it doesn't already exist.
400-
$this->update_token( $user );
401-
402-
// Start the VSCode service manually (outside of PM2).
403-
$cmd = 'runuser -l ' . $user . ' -c "';
404-
$cmd .= "(/opt/vscode/node /opt/vscode/out/server-main.js --port $port) > /dev/null 2>&1 &";
405-
$cmd .= '"';
406-
$cmd = $hcpp->do_action( 'vscode_nodejs_cmd', $cmd );
407-
shell_exec( $cmd );
408-
409-
// Reload nginx
410-
$cmd = '(service nginx restart) > /dev/null 2>&1 &';
411-
$cmd = $hcpp->do_action( 'vscode_nginx_restart', $cmd );
412-
shell_exec( $cmd );
413451
}
414452

415453
/**

0 commit comments

Comments
 (0)