diff --git a/aii-ks/src/main/perl/ks.pm b/aii-ks/src/main/perl/ks.pm index 668012bc..e8309f16 100755 --- a/aii-ks/src/main/perl/ks.pm +++ b/aii-ks/src/main/perl/ks.pm @@ -17,7 +17,7 @@ our $EC = LC::Exception::Context->new->will_store_all; our $this_app = $main::this_app; # Modules that may be interesting for hooks. -our @EXPORT_OK = qw (ksuserhooks ksinstall_rpm get_repos replace_repo_glob); +our @EXPORT_OK = qw (ksuserhooks ksinstall_rpm get_repos replace_repo_glob get_fqdn); # PAN paths for some of the information needed to generate the # Kickstart. @@ -110,21 +110,36 @@ sub get_anaconda_version return $version; } +sub _ks_filename +{ + my ($self, $ksdir, $fqdn) = @_; + return "$ksdir/$fqdn.ks"; +} -# Opens the kickstart file and sets its handle as the default. -sub ksopen +sub ks_filename { my ($self, $cfg) = @_; my $fqdn = get_fqdn($cfg); my $ksdir = $this_app->option (KSDIROPT); - $self->debug(3,"Kickstart file directory = $ksdir"); + $self->debug(3, "Kickstart file directory = $ksdir"); + + return $self->_ks_filename($ksdir, $fqdn); +} + + +# Opens the kickstart file and sets its handle as the default. +sub ksopen +{ + my ($self, $cfg) = @_; + + my $ks = CAF::FileWriter->open( + $self->ks_filename($cfg), + mode => 0664, + log => $this_app + ); - my $ks = CAF::FileWriter->open ("$ksdir/$fqdn.ks", - mode => 0664, - log => $this_app - ); select ($ks); } @@ -1724,7 +1739,9 @@ EOF # this method. sub post_install_script { - my ($self, $config, $packages, $repos) = @_; + my ($self, $config, $packages, $repos, $is_kickstart) = @_; + + $is_kickstart = 1 if ! defined($is_kickstart); my $tree = $config->getElement (KS)->getTree; my $version = get_anaconda_version($tree); @@ -1734,21 +1751,28 @@ sub post_install_script my $logfile = '/tmp/post-log.log'; my $logaction = log_action($config, $logfile); - print <option (KSDIROPT); - unlink ("$ksdir/$fqdn.ks"); + unlink ($self->ks_filename($config)); return 1; } + +1; diff --git a/aii-ks/src/main/perl/ks_ansible.pm b/aii-ks/src/main/perl/ks_ansible.pm new file mode 100644 index 00000000..afda6f43 --- /dev/null +++ b/aii-ks/src/main/perl/ks_ansible.pm @@ -0,0 +1,90 @@ +#${PMpre} NCM::Component::ks_ansible${PMpost} + +# Generate a playbook to run the ks post section on a node. + +use parent qw (NCM::Component::ks); + +use CAF::TextRender; +use NCM::Component::ks qw(get_fqdn); + +sub _ks_filename +{ + my ($self, $ksdir, $fqdn) = @_; + return "$ksdir/kickstart_post_$fqdn.yml"; +} + +# Cancels the open filewriter instance on the playbook +# and returns everything (the select magic/hack) to its normal state. +# Returns the content of the cancelled filewriter instance +sub ksclose +{ + my $fh = select; + + my $text = "$fh"; + + select (STDOUT); + + $fh->cancel(); + $fh->close(); + + return "$text"; +} + +sub make_playbook +{ + my ($self, $cfg, $post_script) = @_; + + # make playbook yaml + my @playbook; + + push(@playbook, { + 'name' => 'Execute AII KS post section script', + 'ansible.builtin.shell' => $post_script, + 'chdir' => '/', + 'args' => { + 'executable' => '/bin/bash', + } + }); + + # textrender the yaml + # bypass issue in CAF::TextRender wrt not allowing arrays + my $trd = CAF::TextRender->new('yaml', {}, log => $self); + $trd->{contents} = \@playbook; + + my $fh = $trd->filewriter($self->ks_filename($cfg)); + if (defined($fh)) { + $fh->close(); + } else { + $self->error("Problem rendering the playbook"); + }; +} + +# Prints the kickstart file. +sub Configure +{ + my ($self, $config) = @_; + + my $fqdn = get_fqdn($config); + if ($CAF::Object::NoAction) { + $self->info ("Would run " . ref ($self) . " on $fqdn"); + return 1; + } + + $self->ksopen($config); + + # ignore the packages that are treated in install for now + # for now assume, all is there already + # this is not kickstart + # won't generate the POSTNOCHROOTHOOK + # no repos passed + $self->post_install_script ($config, [], {}, 0); + + my $post_script = $self->ksclose(); + + $self->make_playbook($config, $post_script); + + return 1; +} + + +1; diff --git a/aii-ks/src/test/perl/00-load.t b/aii-ks/src/test/perl/00-load.t index cfabbec9..db583a3e 100644 --- a/aii-ks/src/test/perl/00-load.t +++ b/aii-ks/src/test/perl/00-load.t @@ -3,6 +3,7 @@ use strict; use warnings; use Test::Quattor; -use Test::More tests => 1; +use Test::More tests => 2; use_ok("NCM::Component::ks"); +use_ok("NCM::Component::ks_ansible"); diff --git a/aii-ks/src/test/perl/kickstart_ansible.t b/aii-ks/src/test/perl/kickstart_ansible.t new file mode 100644 index 00000000..3a5d6ebe --- /dev/null +++ b/aii-ks/src/test/perl/kickstart_ansible.t @@ -0,0 +1,44 @@ +use strict; +use warnings; +use Test::More; +use Test::Quattor qw(kickstart_ansible); +use NCM::Component::ks_ansible; +use YAML::XS; + +our $this_app = $main::this_app; + +$this_app->{CONFIG}->define('osinstalldir'); +$this_app->{CONFIG}->set('osinstalldir', '/some/path'); + +my $obj = Test::Quattor::Object->new(); + +my $ks = NCM::Component::ks_ansible->new('ks_ansible', $obj); + +my $cfg = get_config_for_profile('kickstart_ansible'); + +$ks->Configure($cfg); + +my $fh = get_file('/some/path/kickstart_post_x.y.yml'); +my $data = Load("$fh"); + +my $post = $data->[0]->{"ansible.builtin.shell"}; +$data->[0]->{"ansible.builtin.shell"} = 'POSTSCRIPT'; + +like($post, qr{# %post phase}, "contains the post code"); +unlike($post, qr{^%post}m, "does not contain the %post tag"); + + +is_deeply( + $data, [ + { + "ansible.builtin.shell" => 'POSTSCRIPT', + "name" => "", + "args" => { + "executable" => "/bin/bash", + }, + "chdir" => "/", + "name" => "Execute AII KS post section script", + }, + ], "Converted playbook data"); + +done_testing; diff --git a/aii-ks/src/test/resources/kickstart_ansible.pan b/aii-ks/src/test/resources/kickstart_ansible.pan new file mode 100644 index 00000000..80f6da81 --- /dev/null +++ b/aii-ks/src/test/resources/kickstart_ansible.pan @@ -0,0 +1,3 @@ +object template kickstart_ansible; + +include 'kickstart';