diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..de6a3b3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+**/.vscode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
diff --git a/backup-gitea-bin.pl b/backup-gitea-bin.pl
new file mode 100755
index 0000000..eb106d6
--- /dev/null
+++ b/backup-gitea-bin.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+
+# backup_gitea_bin.pl
+# Author: Tracey Clark
+# Created: 2019-06-20
+# You must have a mail transport agent installed to run this script
+
+use strict;
+use warnings;
+
+### TEST CODE ###
+my $gitea_bin='/home/tracey/tmp/testbin';
+my $gitea_current_version='1';
+my %binary_file = (
+ input => $gitea_bin,
+ version => $gitea_current_version,
+ );
+ my ( %opts ) = %binary_file;
+ my $input = $opts{input};
+ my $version = $opts{version};
+ my $gitea_bin_backup = '/home/tracey/tmp/testbin.' . $gitea_current_version . '.bz2';
+
+### TEST CODE ###
+# my ( %opts ) = %{shift()};
+# my $input = $opts{input};
+# my $version = $opts{version};
+printf("Backing up the current binary\n");
+printf("Input in backup_bin script is $input\n and version is $version\n");
+
+
+# my $gitea_bin_backup = '/home/gitea/bin/gitea.' . $gitea_current_version . '.bz2';
+printf("Gitea bin backup will be $gitea_bin_backup\n");
+# Do this with a system call to make a compressed copy of the current binary
+# bzip2 -k file.txt
+# my $status = system("vi", "fred.txt");
+# if (($status >>=8) != 0) {
+# die "Failed to run vi";
+# }
+
+# HEREHERE how to specify output file??
+my $bzip_status = system("/bin/bzip2 -k $input");
+if (($bzip_status >>=8) != 0) {
+ die "Failed to run bzip2";
+}
diff --git a/update-gitea.pl b/update-gitea.pl
new file mode 100755
index 0000000..d8cd101
--- /dev/null
+++ b/update-gitea.pl
@@ -0,0 +1,416 @@
+#!/usr/bin/perl
+
+# Update gitea based on version provided
+# Author: Tracey Clark
+# Created: 2019-03-04
+# You must have a mail transport agent installed to run this script
+
+# Note: Daily backups are also being run from cron
+# /home/gitea/gitea_backup.sh
+
+# Re-write to use this dir according to gitea docs
+# https://docs.gitea.io/en-us/install-from-binary/
+# Get binary from system rather than hard code
+# Stop gitea with systemctl before file copy
+# Set right mod & perms?
+
+use strict;
+use warnings;
+use LWP::UserAgent;
+use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error);
+use File::Basename;
+use JSON;
+use Sort::Versions;
+use Getopt::Long qw(GetOptions);
+use Term::ANSIColor qw(:constants);
+use feature qw(say);
+use MIME::Lite;
+use utf8;
+use open ':std', ':encoding(UTF-8)';
+use Encode qw(encode encode_utf8 );
+# use Net::SSH qw(sshopen2);
+use Capture::Tiny qw(capture);
+
+my ( $verbose, $info );
+
+GetOptions(
+ 'info!' => \$info,
+ 'verbose!' => \$verbose,
+);
+
+##########################################
+### The user must set these variables ###
+my $email = 'gitea-update@tlcnet.info';
+my $filetype = '-linux-amd64';
+my $download_dir = '/home/gitea/bin/';
+##########################################
+
+my $update_needed = 0;
+
+###################################
+# Get version currently installed #
+###################################
+# https://api.github.com/repos/go-gitea/gitea/releases/latest
+# This URL will only have one version listed
+my $gitea_bin_dir = '/usr/local/bin/';
+my $gitea_bin = $gitea_bin_dir . '/gitea';
+my $gitea_current_version_string = `$gitea_bin --version`;
+my $alphanum_ver = 0;
+chomp $gitea_current_version_string;
+unless ( defined $gitea_current_version_string ) {
+ my $status = "❌ [DIE]: Unable to get the version of the gitea binary on the system: $!";
+ notification('failed ❌', $status);
+ die RED "$status", RESET;
+}
+my %binary_file = get_current_binary($gitea_current_version_string);
+my $gitea_current_version = $binary_file{'version'};
+
+######################################
+# Check upstream version and get tag #
+######################################
+my $baseURL = q{https://github.com/go-gitea/gitea/};
+my $latestURL = q{https://api.github.com/repos/go-gitea/gitea/releases/latest};
+
+# https://hubpages.com/technology/Use-Perl-to-access-REST-API
+# Spin up the browser object
+my $ua = LWP::UserAgent->new(
+ cookie_jar => {}, # keep cookies in RAM but not persistent between sessions
+);
+
+my $resp = $ua->get($latestURL);
+my $latest_release_hash = decode_json( $resp->content )
+ or die "[DIE]: Unable to parse the version data! Output is:\n $resp";
+
+my $orig_tag = $latest_release_hash->{tag_name};
+print "[TLC DEBUG]: ORIG TAG is $orig_tag\n" if defined $verbose;
+my $tag = $orig_tag;
+substr( $tag, 0, 1, '' );
+my $release_id = $latest_release_hash->{id}; # Works
+
+################
+# Set filename #
+################
+my $unz_filename = 'gitea-' . $tag . $filetype;
+#ex: gitea-1.7.6-linux-amd64
+my $download_filename = $unz_filename . '.xz';
+
+if ( defined $verbose ) {
+ printf( YELLOW
+ "[INFO] Latest upstream version: $tag\n Release ID $release_id\n", RESET);
+ printf( YELLOW
+ "[INFO]\nRelease id: $release_id\nUncompressed filename: $unz_filename\nDownload file target: $download_filename\n", RESET
+ );
+}
+
+#############################################
+# Check if upstream is newer than installed #
+#############################################
+if ( versioncmp( $gitea_current_version, $tag ) == -1 ) {
+ $update_needed = 1;
+ printf(
+ "[INFO] Version tag is greater than the system version, proceeding with update\n"
+ );
+ backup_bin( \%binary_file );
+
+ my $download_url = get_download_url( $download_filename, $release_id );
+ print("Downloading the compressed binary\n");
+ print("[INFO] Download URL we got from the sub is $download_url\n");
+ `wget -P $download_dir $download_url`;
+ my $xz_file = $download_dir . $download_filename;
+
+ if ( defined $info ) {
+ print YELLOW "[INFO] xz file is $xz_file\n", RESET;
+ }
+ install_bin($download_filename);
+}
+
+##################################
+# Get service status and version #
+##################################
+my ($gitea_status, $gitea_proc_status, $gitea_ssh_status) = check_gitea_status();
+$gitea_current_version_string = `$gitea_bin --version`;
+chomp $gitea_current_version_string;
+%binary_file = get_current_binary($gitea_current_version_string);
+$gitea_current_version = $binary_file{'version'};
+
+if ( $gitea_status ) {
+ print( GREEN "[INFO] ✅ Gitea service is active\n", RESET );
+}
+else {
+ print( RED "[ERROR] ❌ Gitea service is NOT active\nProcess: $gitea_proc_status\nSSH: $gitea_ssh_status\n", RESET );
+}
+
+########################
+# Notify appropriately #
+########################
+if ( !$update_needed && $gitea_status ) {
+ my $status = '✅ Version tag upstream matches the system version, no update needed. Service is running.';
+ print( YELLOW "[INFO] $status\nInstalled version: $gitea_current_version\nUpstream version: $tag\n", RESET );
+ notification('not needed ✅', $status, $gitea_current_version, $tag);
+ exit 1;
+}
+elsif ( $update_needed && versioncmp( $gitea_current_version, $tag ) == -1 ) {
+ my $status = '❌ Upstream version tag is STILL greater than the current system version after attempting to update, something went wrong';
+ notification('failed ❌', $status, $gitea_current_version, $tag);
+ print( RED $status, RESET );
+}
+elsif ( $update_needed && $gitea_status ) {
+ my $status = '✅ [INFO] Gitea successfuly updated. Installed version is current and service is running';
+ print( GREEN "[INFO] $status\n", RESET );
+ say "Removing the downloaded xz file and uncompressed file";
+ system("rm -vf " . $download_dir . $unz_filename);
+ system("rm -vf " . $download_dir . $download_filename);
+ notification('succeeded ✅', $status, $gitea_current_version, $tag);
+ # Intentionally *not* removing the 'gitea' binary in case something goes wrong running the current binary.
+}
+elsif ( !$gitea_status ) {
+ my $status = q{❌ [DIE] The gitea service is no good!
+ Process: } . $gitea_proc_status . q{
+ SSH Output:
} . $gitea_ssh_status . q{
};
+ notification('failed ❌', $status, $gitea_current_version, $tag);
+ die '❌ [DIE] The gitea service is no good!';
+}
+else {
+ my $status = '❌ [DIE] Unknown update status!';
+ print( RED $status, RESET );
+ notification('failed ❌', $status, $gitea_current_version, $tag);
+ die $status;
+}
+
+# ##### Subroutines #####
+
+# sub check_deps {
+# # Check to make sure dependencies installed on system - unit test??
+# # bzip2 perl mods
+# }
+
+sub get_current_binary {
+ my $current_version_string = shift;
+ my $current_version;
+ if ( $current_version_string =~ m/ion\ (\d+\.\d+\.\d*)\s+b/ ) {
+ $current_version = $1;
+ printf("Version number of the installed gitea binary: $1\n") if defined $verbose;
+ }
+ elsif ( $current_version_string =~ m/ion\ (\d+\d+\w*)\s/ ) {
+ $current_version = $1;
+ printf("Current version number the installed gitea binary: $1\n");
+ $alphanum_ver = 1;
+ }
+ my %binary_file = (
+ input => $gitea_bin,
+ version => $current_version,
+ );
+ unless ( defined $current_version ) {
+ die RED
+ "[DIE]: Unable to get the current gitea version! Value is $current_version",
+ RESET;
+ }
+ return %binary_file;
+}
+
+sub get_binary_file {
+ my $version = shift;
+}
+
+sub backup_bin {
+
+ # Ghetto to get it working for now
+
+ my (%opts) = %{ shift() };
+ my $input = $opts{input};
+ my $version = $opts{version};
+ print GREEN "Backing up the current binary\n", RESET;
+ if ( defined $info ) {
+ print YELLOW
+ "[INFO] Input in backup_bin sub is:\n Directory $input\n Version $version\n",
+ RESET;
+ }
+ my $gitea_bin_backup =
+ '/home/gitea/bin/gitea.' . $gitea_current_version . '.bz2';
+ print GREEN "Gitea bin backup will be $gitea_bin_backup\n", RESET;
+ system("cp $input $input.bak");
+
+ # TODO
+ # # Do this with a system call to make a compressed copy of the current binary
+ # # bzip2 -k file.txt
+ # # my $status = system("vi", "fred.txt");
+ # # if (($status >>=8) != 0) {
+ # # die "[DIE] Failed to run vi";
+ # # }
+ # my $bzip_status = system("bzip2 -k", "$input");
+ # if (($status >>=8) != 0) {
+ # die "[DIE] Failed to run bzip2";
+ # }
+
+ return;
+}
+
+sub get_download_url {
+ my ( $dl_filename, $rel_id ) = @_;
+ my $dl_url;
+
+ # Get the download_url from the array
+ my $assetsURL =
+ 'https://api.github.com/repos/go-gitea/gitea/releases/'
+ . $release_id
+ . '/assets';
+ if ( defined $info ) {
+ print YELLOW "[INFO] Assets URL\n";
+ print "$assetsURL\n", RESET;
+ }
+
+ my $asset_resp = $ua->get($assetsURL);
+ my $asset_resp_array_ref = decode_json( $asset_resp->content );
+
+ if ( defined $verbose ) {
+ printf( RED
+ "[DEBUG] Array of hashes of the json response for the assets:\n"
+ );
+ printf Dumper($asset_resp_array_ref), RESET;
+ }
+
+ foreach my $asset_ref ( @{$asset_resp_array_ref} ) {
+ if ( defined $verbose ) {
+ print( RED
+ "[DEBUG] The asset ref in get_download_url is $asset_ref\n" );
+ print(
+ "The asset ref name in get_download_url is $asset_ref->{name}\n",
+ RESET
+ );
+ }
+ if ( $asset_ref->{name} eq $dl_filename ) {
+ print("Yay we have a match for our desired file :D and it is \n");
+ print $asset_ref->{name} . "\n";
+ $dl_url = $asset_ref->{browser_download_url};
+ if ( defined $info ) {
+ print YELLOW
+ "[INFO] The download url from the response array is $dl_url\n",
+ RESET;
+ }
+ return $dl_url;
+ }
+ }
+ unless ( defined $dl_url ) {
+ print( RED
+ "ONOES we have no download URL from the github API! Trying to build one manually\n",
+ RESET
+ );
+ my $dl_url = build_download_url( $orig_tag, $download_filename );
+ return $dl_url;
+ }
+ return 0;
+}
+
+sub build_download_url {
+ my ( $url_tag, $url_file ) = @_;
+ print "Building the URL based on the version\n";
+
+# If getting the download URL fails through the API, use this to build it manually
+# URL is in the form of
+# https://github.com/go-gitea/gitea/releases/download/v1.15.2/gitea-1.15.2-linux-amd64.xz
+ my $built_url =
+ 'https://github.com/go-gitea/gitea/releases/download/'
+ . $url_tag . '/'
+ . $url_file;
+ if ( defined $info ) {
+ print YELLOW "The URL built for the download is $built_url\n", RESET;
+ }
+ return $built_url;
+}
+
+sub install_bin {
+ my $filename = shift;
+ print("Unpacking the downloaded file \"$download_dir$filename\", setting owner and permissions\n");
+ my $unpacked_filename = basename($filename, ".xz");
+ print "Unpacked filename is $unpacked_filename\n";
+
+ # Copy the downloaded binary to gitea and chmod it 750
+ # Doing this with a filthy system call because the perl library
+ # for xz manipulation is a memory hog and buggy besides
+ system("xz -d --keep $download_dir" . "/" . "$filename");
+ system("systemctl stop gitea");
+ system("cp $download_dir$unpacked_filename $gitea_bin");
+ system("chown gitea.gitea $gitea_bin");
+ system("chmod 750 $gitea_bin");
+
+ # Restart service
+ print("[INFO] Restarting the gitea service\n");
+ return system("systemctl restart gitea");
+}
+
+sub check_gitea_status {
+ my $gitea_status;
+ my $gitea_proc_status = `systemctl is-active gitea`;
+ sleep 1; # Otherwise the SSH regex doesnt work;
+
+ my $command = 'ssh -i /home/tracey/.ssh/id_tlc_gitea gitea';
+ # DEBUG - induce failure
+ # my $command = 'ssh -i /home/tracey/.ssh/blerg gitea';
+ my ($out, $err, $exit) = capture { system $command };
+
+ # print "\n---- STDERR: --------------\n";
+ # print $err;
+ # print "\n---- STDOUT: --------------\n";
+ # print $out;
+ # print "\n---- EXIT CODE: -----------\n";
+ # print $exit / 256;
+ # print "\n---------------------------\n";
+ my $gitea_ssh_status = $err;
+ if ($gitea_ssh_status =~ /(successful)/gm) {
+ print "Gitea SSH connection attempt: $1\n";
+ }
+
+
+ unless ( ($gitea_proc_status =~ /active/) && ($gitea_ssh_status =~ /successfully/gm) ) {
+ $gitea_status = 0;
+ }
+ if ( ($gitea_proc_status =~ /active/) && ($gitea_ssh_status =~ /successfully/gm) ) {
+ $gitea_status = 1;
+ }
+ return $gitea_status, $gitea_proc_status, $gitea_ssh_status;
+}
+
+sub notification {
+ my ($result, $body, $running_version, $upstream_version) = @_;
+ my $subject = "Gitea update check: update " . $result;
+ my $from = 'system@host.tlcnet.info';
+ my $ver_body;
+
+ print "[TLC DEBUG] Body received is\n$body\n" if defined $verbose;
+
+ if ( defined $running_version ) {
+ $ver_body = q{
+
| Running version: | +} . $running_version . q{ | +
| Upstream version: | +} . $upstream_version . q{ | +
' . $body . '
' . $ver_body . + '⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
+Sincerely,
Your Linode VM