View raw

1 #!/usr/bin/perl 2 # -*- mode: cperl; -*- 3 4 use 5.40.2; 5 use strict; 6 use warnings; 7 8 use Getopt::Long; 9 use Pod::Usage; 10 use File::Basename; 11 use File::Path qw(make_path); 12 use File::Copy; 13 use POSIX qw(strftime); 14 use Data::Dumper; 15 $Data::Dumper::Terse = 1; 16 17 =head1 NAME 18 19 deploy - deploy the MyFitnessTracker web app to my vps 20 21 =head1 SYNOPSIS 22 23 deploy [--help] IMAGE HOST 24 25 =head1 AUTHOR 26 27 Marius Peter <mft@marius-peter.com> 28 29 =head1 COPYRIGHT 30 31 Copyright 2024 Marius Peter <mft@marius-peter.com> 32 33 =cut 34 35 GetOptions( test => \my $test ); 36 37 my ( $source, $destination ) = @ARGV; 38 if ( not defined $source ) { 39 pod2usage "No development image specified."; 40 } elsif ( not -e $source ) { 41 pod2usage "$source does not exist."; 42 } elsif ( not defined $destination ) { 43 pod2usage "No destination host specified."; 44 } 45 46 my $iso8601 = strftime '%Y-%m-%dT%H:%M:%SZ', localtime; 47 48 # Identify resources 49 50 my ( $image_devel, $path_devel ) = fileparse $source; 51 my ( $image_staging, $path_staging ) = ( "mft.image", "/tmp/mft-${iso8601}" ); 52 53 open my $fh, '<', "${path_devel}/pharo.version"; 54 chomp( my $pharo_version = <$fh> ); 55 close $fh; 56 say "Pharo version for $image_devel is $pharo_version."; 57 my $pharo_vm = $ENV{HOME} . "/Pharo/vms/${pharo_version}-x64/pharo"; 58 if ( -x $pharo_vm ) { 59 say "Found Pharo VM $pharo_vm."; 60 } else { 61 die "$pharo_vm is not a valid Pharo VM executable path"; 62 } 63 64 # Staging image 65 66 make_path $path_staging or die $!; 67 say "Copying development image $image_devel to staging image..."; 68 copy "${path_devel}/${image_devel}", "${path_staging}/${image_staging}" 69 or die $!; 70 71 my $script = "MFTUtils createDeploymentImage"; 72 say "Building staging image at $path_staging..."; 73 system "$pharo_vm --headless ${path_staging}/${image_staging} eval $script"; 74 if ($?) { 75 die "Failed to build staging image"; 76 } else { 77 say "Staging image built at ${path_staging}/${image_staging}."; 78 } 79 80 # Production image 81 82 my $image_prod = "${destination}:/var/www/myfitnesstracker.io/${image_staging}"; 83 84 say "Deploying production image at $image_prod..."; 85 system 'rsync', qw( --verbose --progress --human-readable --compress ), 86 "${path_staging}/${image_staging}", $image_prod; 87 88 warn "You must manually log into $destination in order to restart mft.service."; 89 90 # system 'ssh root@vps systemctl restart mft'; 91 # if ($?) { 92 # die "Couldn't restart mft.service on $destination" 93 # } 94 # else { 95 # print "Successfully restarted mft.service on $destination.\n" 96 # } 97 98 say "$image_devel successfully deployed to $image_prod." 99