#!raku
use Sparky::JobApi;
class Pipeline
does Sparky::JobApi::Role
{
method stage-main {
directory "scm";
my $repo = tags()<repo>.subst(/^^ \s* "~/" /,%*ENV<HOME> ~ "/");
my $use_case_repo = tags()<use_case_repo>.subst(/^^ \s* "~/" /,%*ENV<HOME> ~ "/");
if $repo.IO ~~ :d {
bash "cp -r {$repo}/* scm/";
} else {
git-scm tags()<repo>, %(
to => "scm",
branch => tags()<branch>,
);
}
directory "use_case_repo";
file-delete "use_case_repo.tar";
if $use_case_repo.IO ~~ :d {
say "archiving {$use_case_repo} files to use_case_repo.tar";
bash "tar cf {$*CWD}/use_case_repo.tar -C {$use_case_repo} .";
} else {
git-scm tags()<use_case_repo>, %(
to => "use_case_repo",
branch => "HEAD",
);
say "(git) archiving {tags()<use_case_repo>} files to use_case_repo.tar";
bash "git archive --format=tar -o {$*CWD}/use_case_repo.tar HEAD", %(
cwd => "{$*CWD}/use_case_repo",
);
}
my $me = Sparky::JobApi.new: :mine;
$me.put-file("{$*CWD}/use_case_repo.tar","use_case_repo.tar");
if tags()<qemu_new_session> {
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
# spawns a child job
my $j = self.new-job: :project<qemu-session>;
$j.queue({
description => "start qemu session",
tags => %(
stage => "qemu-session",
distro_url => config()<distro_url>,
repo => $repo,
branch => tags()<branch>,
download_distro => config()<download_distro> ?? "yes" !! "no",
qemu_binary => tags()<qemu_binary>,
ssh_key_path => tags()<ssh_key_path>.subst(/^^ \s* "~/" /,%*ENV<HOME> ~ "/"),
qemu_machine => tags()<qemu_machine>,
),
});
say "queue qemu-session job, ",$j.info.raku;
say "wait till qemu box is ready";
my $ssh-ok = False;
for 1 .. 40 -> $i {
my $s = task-run "scm/tasks/check-ssh", %(
:host<127.0.0.1>,
:port<10022>,
:user<admin>,
);
if $s<state> eq "alive" {
$ssh-ok = True;
last;
}
sleep(10);
say "[$i] ...";
say "qemu-session job status: ", $j.status;
unless $j.status eq "RUNNING" {
say "qemu box is not good, stopping qemu session and exiting ...";
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
exit(1);
}
}
if $j.status eq "FAIL" or $ssh-ok == False {
say "qemu box is not good";
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
exit(1);
}
unless tags()<skip_bootstrap> {
$j = Sparky::JobApi.new: :project<qemu-bootstrap>;
$j.queue({
description => "bootstrap qemu box",
tags => %(
stage => "qemu-bootstrap",
),
sparrowdo => %(
:bootstrap,
ssh_user => "admin",
ssh_port => 10022,
host => "127.0.0.1",
),
});
say "queue bootstrap qemu job, ",$j.info.raku;
say "wait up to 20 munutes till bootstrap has finished";
my $st = self.wait-job($j, %( :1200timeout ) );
unless $st<OK> {
say "qemu box is not good, stopping qemu session and exiting ...";
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
exit(1);
}
}
}
say "run use case scenario on qemu box";
my $j = Sparky::JobApi.new: :project<qemu-use-case>;
$j.queue({
description => "use case scenario",
tags => %(
stage => "use-case",
dump_task_code => tags()<dump_task_code> ?? "on" !! "off",
parent_job_id => tags()<SPARKY_JOB_ID>,
parent_job_name => tags()<SPARKY_PROJECT>,
),
sparrowdo => %(
ssh_user => "admin",
ssh_port => 10022,
host => "127.0.0.1",
:no_sudo,
#:debug,
),
});
say "queue use case job, ",$j.info.raku;
say "wait up to 15 minutes till use case scenario has finished";
my $st = self.wait-job($j, %( :900timeout ) );
# check if child job send us any message
my $jdata = $me.get-stash();
if $jdata<need-reboot> {
say "reboot signal recieved from child job, reboot qemu box";
my $j = Sparky::JobApi.new: :project<qemu-reboot>;
$j.queue({
description => "reboot qemu box",
tags => %(
stage => "qemu-reboot",
),
sparrowdo => %(
ssh_user => "admin",
ssh_port => 10022,
host => "127.0.0.1",
:no_sudo,
#:debug,
),
});
say "queue qemu-reboot job, ",$j.info.raku;
say "wait up to 7 minutes till reboot has finished";
my $st = self.wait-job($j, %( :420timeout ) );
unless $st<OK> {
say "qemu box is not good, stopping qemu session and exiting ...";
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
exit(1);
}
sleep(15); # wait till VM has rebooted
my $ssh-ok = False;
for 1 .. 40 -> $i {
my $s = task-run "scm/tasks/check-ssh", %(
:host<127.0.0.1>,
:port<10022>,
:user<admin>,
);
if $s<state> eq "alive" {
$ssh-ok = True;
last;
}
sleep(10);
say "[$i] ...";
}
if $ssh-ok == True {
say "machine successfully rebooted, run use case scenario on qemu box";
my $j = Sparky::JobApi.new: :project<qemu-use-case>;
$j.queue({
description => "use case scenario",
tags => %(
stage => "use-case",
dump_task_code => tags()<dump_task_code> ?? "on" !! "off",
parent_job_id => tags()<SPARKY_JOB_ID>,
parent_job_name => tags()<SPARKY_PROJECT>,
:reboot-ok,
),
sparrowdo => %(
ssh_user => "admin",
ssh_port => 10022,
host => "127.0.0.1",
:no_sudo,
#:debug,
),
});
say "queue use case job, ",$j.info.raku;
say "wait up to 15 minutes till use case scenario has finished";
my $st = self.wait-job($j, %( :900timeout ) );
if tags()<qemu_shut> {
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
}
} else {
# handle case when vm has not showed up after reboot
say "qemu box is not good, stopping qemu session and exiting ...";
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
exit(1);
}
# reboot is not required, just stop VM in case qemu_shut is enabled
} elsif tags()<qemu_shut> {
task-run "scm/tasks/stop-qemu-box", %(
qemu_binary => tags()<qemu_binary>,
);
}
}
method stage-qemu-session {
directory "scm";
my $repo = tags()<repo>.subst(/^^ \s* "~/" /,%*ENV<HOME> ~ "/");
if $repo.IO ~~ :d {
bash "cp -r {$repo}/* scm/";
} else {
git-scm tags()<repo>, %(
to => "scm",
branch => tags()<branch>,
);
}
task-run "scm/tasks/setup-qemu-image", %(
distro_url => tags()<distro_url>,
ssh_key_path => tags()<ssh_key_path>,
);
bash "ls -lth {%*ENV<HOME>}/rocky-linux-distro";
task-run "scm/tasks/run-qemu-box", %(
iso => "{%*ENV<HOME>}/rocky-linux-distro/distro.qcow2",
seed => "/tmp/init.iso",
qemu_binary => tags()<qemu_binary>,
machine => tags()<qemu_machine>,
);
}
method stage-qemu-bootstrap {
say "hello from RockyLinux";
}
method stage-use-case {
directory "scm";
bash "echo OK";
my $job = Sparky::JobApi.new(
api => "http://10.0.2.2:4000",
project => tags()<parent_job_name>,
job-id => tags()<parent_job_id>,
);
my $blob = $job.get-file("use_case_repo.tar");
my $fh = open "scm/use_case_repo.tar", :w, :bin;
$fh.write($blob);
$fh.close;
bash "tar -xf use_case_repo.tar && ls -l", %(
cwd => "{$*CWD}/scm",
description => "unpack use_case_repo.tar",
);
if "scm/main.raku".IO ~~ :e {
say "load scenario from main.raku";
chdir "scm/";
if tags()<dump_task_code> eq "on" {
say "enable dump_task_code ...";
%*ENV<SP6_DUMP_TASK_CODE> = 1;
}
EVALFILE "main.raku";
} else {
warn "no file main.raku found, nothing to do"
}
}
method stage-qemu-reboot {
say "rebooting machine ...";
task-run "reboot", "reboot";
}
}
Pipeline.new.run;