update dix
This commit is contained in:
parent
e921a49d5b
commit
11691a5876
11 changed files with 1108 additions and 54 deletions
|
|
@ -340,6 +340,7 @@ my $d = Frontier::Daemon::OGP::Forking->new(
|
|||
fastdl_get_info => \&fastdl_get_info,
|
||||
fastdl_create_config => \&fastdl_create_config,
|
||||
agent_restart => \&agent_restart,
|
||||
component_update => \&component_update,
|
||||
scheduler_add_task => \&scheduler_add_task,
|
||||
scheduler_del_task => \&scheduler_del_task,
|
||||
scheduler_list_tasks => \&scheduler_list_tasks,
|
||||
|
|
@ -3498,6 +3499,162 @@ sub fastdl_create_config
|
|||
return 1;
|
||||
}
|
||||
|
||||
sub component_update_shell_quote
|
||||
{
|
||||
my ($value) = @_;
|
||||
$value = '' unless defined $value;
|
||||
$value =~ s/'/'"'"'/g;
|
||||
return "'" . $value . "'";
|
||||
}
|
||||
|
||||
sub component_update_response
|
||||
{
|
||||
my (%data) = @_;
|
||||
my %encoded = ();
|
||||
foreach my $key (keys %data)
|
||||
{
|
||||
$encoded{$key} = encode_base64(defined $data{$key} ? $data{$key} : '', '');
|
||||
}
|
||||
return \%encoded;
|
||||
}
|
||||
|
||||
sub component_update_parse_payload
|
||||
{
|
||||
my ($payload) = @_;
|
||||
my %data = ();
|
||||
foreach my $line (split(/\r?\n/, $payload || ''))
|
||||
{
|
||||
next if $line !~ /^([A-Za-z0-9_]+)=(.*)$/;
|
||||
$data{$1} = decode_base64($2);
|
||||
}
|
||||
return %data;
|
||||
}
|
||||
|
||||
sub component_update
|
||||
{
|
||||
return component_update_response(success => 0, status => 'bad_encryption', message => 'Bad Encryption Key')
|
||||
unless(decrypt_param(pop(@_)) eq "Encryption checking OK");
|
||||
my ($payload) = decrypt_params(@_);
|
||||
my %cfg = component_update_parse_payload($payload);
|
||||
|
||||
my $component = $cfg{component} || 'windows_agent';
|
||||
if ($component ne 'linux_agent' && $component ne 'windows_agent')
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_component', message => 'Invalid component.');
|
||||
}
|
||||
my $repo_url = $cfg{repo_url} || '';
|
||||
my $branch = $cfg{branch} || '';
|
||||
my $source_path = $cfg{source_path} || '';
|
||||
my $install_path = $cfg{install_path} || AGENT_RUN_DIR;
|
||||
my $git_path = $cfg{git_path} || 'git';
|
||||
my $backup_path = $cfg{backup_path} || Path::Class::Dir->new(AGENT_RUN_DIR, 'component_backups')->stringify;
|
||||
my $post_update_command = $cfg{post_update_command} || '';
|
||||
|
||||
if ($repo_url !~ m{^(https?://|ssh://|git@|/)} || $repo_url =~ /[\r\n\0]/)
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_repo', message => 'Invalid repository URL or path.');
|
||||
}
|
||||
if ($branch !~ /^[A-Za-z0-9._\/-]{1,128}$/)
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_branch', message => 'Invalid branch.');
|
||||
}
|
||||
if ($source_path eq '' || $source_path =~ /\.\./ || $source_path =~ /[\r\n\0]/ || $source_path !~ /^[A-Za-z0-9._\/-]+$/)
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_source_path', message => 'Invalid source path.');
|
||||
}
|
||||
if ($install_path !~ m{^/} || $install_path =~ /\.\./ || $install_path =~ /[\r\n\0]/)
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_install_path', message => 'Invalid install path.');
|
||||
}
|
||||
if ($post_update_command =~ /[\r\n\0]/)
|
||||
{
|
||||
return component_update_response(success => 0, status => 'invalid_post_update', message => 'Post-update command must be a single line.');
|
||||
}
|
||||
|
||||
my $ts = time();
|
||||
my $script_path = Path::Class::File->new(AGENT_RUN_DIR, "gsp_component_update_$ts.sh")->stringify;
|
||||
my $log_path = Path::Class::File->new(AGENT_RUN_DIR, 'gsp_component_update.log')->stringify;
|
||||
my $screenrc = SCREENRC_FILE;
|
||||
my $repo_q = component_update_shell_quote($repo_url);
|
||||
my $branch_q = component_update_shell_quote($branch);
|
||||
my $source_q = component_update_shell_quote($source_path);
|
||||
my $install_q = component_update_shell_quote($install_path);
|
||||
my $git_q = component_update_shell_quote($git_path);
|
||||
my $backup_q = component_update_shell_quote($backup_path);
|
||||
my $post_q = component_update_shell_quote($post_update_command);
|
||||
my $log_q = component_update_shell_quote($log_path);
|
||||
my $screenrc_q = component_update_shell_quote($screenrc);
|
||||
|
||||
my $script = <<"EOS";
|
||||
#!/usr/bin/env bash
|
||||
set -u
|
||||
LOG=$log_q
|
||||
log(){ printf '[%s] %s\\n' "\$(date '+%Y-%m-%d %H:%M:%S')" "\$*" >> "\$LOG"; }
|
||||
fail(){ log "FAILED: \$*"; exit 1; }
|
||||
REPO=$repo_q
|
||||
BRANCH=$branch_q
|
||||
SOURCE_REL=$source_q
|
||||
DEST=$install_q
|
||||
GIT_BIN=$git_q
|
||||
BACKUP_BASE=$backup_q
|
||||
POST_UPDATE=$post_q
|
||||
TMP="\${TMPDIR:-/tmp}/gsp_agent_update_\$(date +%s)_\$\$"
|
||||
mkdir -p "\$TMP" "\$BACKUP_BASE" || fail "Cannot create staging or backup directories"
|
||||
log "queued component=$component repo=\$REPO branch=\$BRANCH source=\$SOURCE_REL dest=\$DEST"
|
||||
if ! command -v "\$GIT_BIN" >/dev/null 2>&1 && [ ! -x "\$GIT_BIN" ]; then
|
||||
fail "Git executable not found: \$GIT_BIN"
|
||||
fi
|
||||
"\$GIT_BIN" clone --depth 1 --branch "\$BRANCH" "\$REPO" "\$TMP/repo" >> "\$LOG" 2>&1 || fail "git clone failed"
|
||||
SRC="\$TMP/repo/\$SOURCE_REL"
|
||||
[ -d "\$SRC" ] || fail "Source component folder missing: \$SRC"
|
||||
case "\$DEST" in /*) ;; *) fail "Destination must be absolute: \$DEST" ;; esac
|
||||
mkdir -p "\$DEST" || fail "Cannot create destination: \$DEST"
|
||||
ARCHIVE="\$BACKUP_BASE/${component}_\$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
tar --exclude='./Cfg' --exclude='./ServerFiles' --exclude='./Schedule' --exclude='./logs' --exclude='./screenlogs' --exclude='./steamcmd' --exclude='./startups' --exclude='./tmp' --exclude='./shared' --exclude='./component_backups' --exclude='./*.pid' -czf "\$ARCHIVE" -C "\$DEST" . >> "\$LOG" 2>&1 || fail "Backup failed"
|
||||
if command -v rsync >/dev/null 2>&1; then
|
||||
rsync -a --exclude='Cfg/' --exclude='ServerFiles/' --exclude='Schedule/' --exclude='logs/' --exclude='screenlogs/' --exclude='steamcmd/' --exclude='startups/' --exclude='tmp/' --exclude='shared/' --exclude='component_backups/' --exclude='*.pid' "\$SRC"/ "\$DEST"/ >> "\$LOG" 2>&1 || fail "rsync copy failed"
|
||||
else
|
||||
(cd "\$SRC" && tar --exclude='./Cfg' --exclude='./ServerFiles' --exclude='./Schedule' --exclude='./logs' --exclude='./screenlogs' --exclude='./steamcmd' --exclude='./startups' --exclude='./tmp' --exclude='./shared' --exclude='./component_backups' --exclude='./*.pid' -cf - .) | (cd "\$DEST" && tar -xf -) >> "\$LOG" 2>&1 || fail "tar copy failed"
|
||||
fi
|
||||
if [ -f "\$DEST/ogp_agent.pl" ]; then
|
||||
perl -c "\$DEST/ogp_agent.pl" >> "\$LOG" 2>&1 || fail "Updated ogp_agent.pl failed syntax validation"
|
||||
fi
|
||||
if [ -n "\$POST_UPDATE" ]; then
|
||||
(cd "\$DEST" && bash -lc "\$POST_UPDATE") >> "\$LOG" 2>&1 || fail "post-update command failed"
|
||||
fi
|
||||
log "copy complete archive=\$ARCHIVE"
|
||||
sleep 2
|
||||
cd "\$DEST" || exit 0
|
||||
if [ -f ogp_agent_run.pid ]; then kill "\$(cat ogp_agent_run.pid)" >/dev/null 2>&1 || true; fi
|
||||
if [ -f ogp_agent.pid ]; then kill "\$(cat ogp_agent.pid)" >/dev/null 2>&1 || true; fi
|
||||
sleep 2
|
||||
if [ -f ogp_agent_run ]; then
|
||||
screen -d -m -t "ogp_agent" -c $screenrc_q -S ogp_agent bash ogp_agent_run -pidfile ogp_agent_run.pid >> "\$LOG" 2>&1 || true
|
||||
else
|
||||
screen -d -m -t "ogp_agent" -c $screenrc_q -S ogp_agent perl ogp_agent.pl >> "\$LOG" 2>&1 || true
|
||||
fi
|
||||
log "restart attempted"
|
||||
rm -rf "\$TMP"
|
||||
exit 0
|
||||
EOS
|
||||
|
||||
my $fh;
|
||||
if (!open($fh, '>', $script_path))
|
||||
{
|
||||
return component_update_response(success => 0, status => 'write_failed', message => "Cannot write updater script: $!");
|
||||
}
|
||||
print $fh $script;
|
||||
close($fh);
|
||||
chmod 0700, $script_path;
|
||||
system('screen -d -m -t "component_update" -c "' . SCREENRC_FILE . '" -S component_update bash ' . component_update_shell_quote($script_path));
|
||||
if ($? != 0)
|
||||
{
|
||||
system('bash ' . component_update_shell_quote($script_path) . ' >/dev/null 2>&1 &');
|
||||
}
|
||||
logger "Component update queued for $component from $repo_url branch $branch.";
|
||||
return component_update_response(success => 1, status => 'queued', message => 'Component update queued on agent.', log_path => $log_path, script_path => $script_path);
|
||||
}
|
||||
|
||||
sub agent_restart
|
||||
{
|
||||
return "Bad Encryption Key" unless(decrypt_param(pop(@_)) eq "Encryption checking OK");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue