<commit_before># ${license-info}
# ${developer-info
# ${author-info}
# ${build-info}
#
# Note: all methods in this component are called in a
# $self->$method ($config) way, unless explicitly stated.

#package NCM::Component::ks;
package NCM::Component::ks;

use strict;
use warnings;
use NCM::Component;
use EDG::WP4::CCM::Property;
use EDG::WP4::CCM::Element qw (unescape);
use NCM::Filesystem;
use NCM::Partition qw (partition_compare);
use NCM::BlockdevFactory qw (build);
use FileHandle;
use LC::Exception qw (throw_error);
use Data::Dumper;
use Exporter;
use CAF::FileWriter;
use Sys::Hostname;

our @ISA = qw (NCM::Component Exporter);
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);

# PAN paths for some of the information needed to generate the
# Kickstart.
use constant { KS		=> "/system/aii/osinstall/ks",
	       HOSTNAME		=> "/system/network/hostname",
	       DOMAINNAME	=> "/system/network/domainname",
	       FS		=> "/system/filesystems/",
	       PART		=> "/system/blockdevices/partitions",
	       REPO		=> "/software/repositories",
	       PRESCRIPT	=> "/system/aii/osinstall/ks/pre_install_script",
	       PREHOOK		=> "/system/aii/hooks/pre_install",
	       PREENDHOOK	=> "/system/aii/hooks/pre_install_end",
	       POSTREBOOTSCRIPT	=> "/system/aii/osinstall/ks/post_reboot_script",
	       POSTREBOOTHOOK	=> "/system/aii/hooks/post_reboot",
	       POSTREBOOTENDHOOK	=> "/system/aii/hooks/post_reboot_end",
	       POSTSCRIPT	=> "/system/aii/osinstall/ks/post_install_script",
	       POSTHOOK		=> "/system/aii/hooks/post_install",
	       ANACONDAHOOK	=> "/system/aii/hooks/anaconda",
	       PREREBOOTHOOK	=> "/system/aii/hooks/pre_reboot",
	       PKG		=> "/software/packages/",
	       KERNELVERSION	=> "/system/kernel/version",
	       ACKURL		=> "/system/aii/osinstall/ks/ackurl",
	       ACKLIST          => "/system/aii/osinstall/ks/acklist",
	       CARDS		=> "/hardware/cards/nic",
	       SPMAPROXY	=> "/software/components/spma/proxy",
	       SPMA		=> "/software/components/spma",
	       SPMA_OBSOLETES	=> "/software/components/spma/process_obsoletes",
	       ROOTMAIL		=> "/system/rootmail",
	       AII_PROFILE	=> "/system/aii/osinstall/ks/node_profile",
	       CCM_PROFILE	=> "/software/components/ccm/profile",
	       CCM_TRUST	=> "/software/components/ccm/trust",
	       CCM_KEY		=> "/software/components/ccm/key_file",
	       CCM_CERT		=> "/software/components/ccm/cert_file",
	       CCM_CA		=> "/software/components/ccm/ca_file",
	       CCM_WORLDR	=> "/software/components/ccm/world_readable",
               CCM_DBFORMAT     => "/software/components/ccm/dbformat",
	       EMAIL_SUCCESS	=> "/system/aii/osinstall/ks/email_success",
	       NAMESERVER	=> "/system/network/nameserver/0",
	       FORWARDPROXY	=> "forward",
	       END_SCRIPT_FIELD => "/system/aii/osinstall/ks/end_script",
	       BASE_PKGS	=> "/system/aii/osinstall/ks/base_packages",
	       LOCALHOST        => hostname(),
	       ENABLE_SSHD      => "/system/aii/osinstall/ks/enable_sshd",
	   };

# Base package path for user hooks.
use constant   MODULEBASE	=> "AII::";
use constant   USEMODULE	=> "use " . MODULEBASE;

# Configuration variable for the osinstall directory.
use constant   KSDIROPT		=> 'osinstalldir';

# Packages to be installed when setting up Quattor.


# Packages containing kernels. kernel-xen is not listed here, as it
# depends on different versions of mkinitrd and e2fsprogs, and
# installing them may cause a dependency hell.
use constant KERNELLIST		=> qw (kernel-firmware kernel kernel-smp);


# Opens the kickstart file and sets its handle as the default.
sub ksopen
{
    my ($self, $cfg) = @_;

    my $host = $cfg->getElement (HOSTNAME)->getValue;
    my $domain = $cfg->getElement (DOMAINNAME)->getValue;

    my $ksdir = $this_app->option (KSDIROPT);
    $self->debug(3,"Kickstart file directory = $ksdir");

    my $ks = CAF::FileWriter->open ("$ksdir/$host.$domain.ks",
				    mode => 0664, log => $this_app);
    select ($ks);
}

# Prints the opening here doc statement for the post-reboot
# script. It's usefult to separate this, as other plug-ins might want
# only the post_reboot script.
sub kspostreboot_hereopen
{
    print <<EOF;

cat <<End_Of_Post_Reboot > /etc/rc.d/init.d/ks-post-reboot
EOF
}

# Prints the heredoc closing the KS postreboot statement.
sub kspostreboot_hereclose
{
    print <<EOF;

End_Of_Post_Reboot

EOF
}

# Configures the network, allowing both DHCP and static boots.
sub ksnetwork
{
    my ($tree, $config) = @_;

    if ($tree->{bootproto} eq 'dhcp') {
	$this_app->debug (5, "Node configures its network via DHCP");
	print "network --bootproto=dhcp\n";
	return;
    }

    my $dev = $config->getElement("/system/aii/nbp/pxelinux/ksdevice")->getValue;
    my $fqdn = $config->getElement (HOSTNAME)->getValue . "." .
      $config->getElement (DOMAINNAME)->getValue;
    return unless $dev =~ m/eth\d+/;
    $this_app->debug (5, "Node will boot from $dev");
    my $net = $config->getElement("/system/network/interfaces/$dev")->getTree;
    unless (exists ($net->{ip})) {
	    $this_app->error ("Static boot protocol specified ",
			      "but no IP given to the interface");
	    return;
    }
    my $gw = '--gateway=';
    if (exists($net->{gateway})) {
        $gw .= $net->{gateway};
    } elsif ($config->elementExists ("/system/network/default_gateway")) {
        $gw .= $config->getElement ("/system/network/default_gateway")->getValue;
    } else {
        # This is a recipe for disaster
        # Best guess is that no gateway is needed.
        $this_app->debug (5, "No gateway defined for dev $dev and ",
			  " using static network description.",
			  "Let's hope everything is reachable through a ",
			  "direct route.");
        $gw='';
        print <<EOF;
## No gateway defined for dev $dev and using static network description.
## Lets hope all is reachable through direct route.
EOF<commit_msg>Define the MTU in the KS, if present<commit_after># ${license-info}
# ${developer-info
# ${author-info}
# ${build-info}
#
# Note: all methods in this component are called in a
# $self->$method ($config) way, unless explicitly stated.

#package NCM::Component::ks;
package NCM::Component::ks;

use strict;
use warnings;
use NCM::Component;
use EDG::WP4::CCM::Property;
use EDG::WP4::CCM::Element qw (unescape);
use NCM::Filesystem;
use NCM::Partition qw (partition_compare);
use NCM::BlockdevFactory qw (build);
use FileHandle;
use LC::Exception qw (throw_error);
use Data::Dumper;
use Exporter;
use CAF::FileWriter;
use Sys::Hostname;

our @ISA = qw (NCM::Component Exporter);
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);

# PAN paths for some of the information needed to generate the
# Kickstart.
use constant { KS		=> "/system/aii/osinstall/ks",
	       HOSTNAME		=> "/system/network/hostname",
	       DOMAINNAME	=> "/system/network/domainname",
	       FS		=> "/system/filesystems/",
	       PART		=> "/system/blockdevices/partitions",
	       REPO		=> "/software/repositories",
	       PRESCRIPT	=> "/system/aii/osinstall/ks/pre_install_script",
	       PREHOOK		=> "/system/aii/hooks/pre_install",
	       PREENDHOOK	=> "/system/aii/hooks/pre_install_end",
	       POSTREBOOTSCRIPT	=> "/system/aii/osinstall/ks/post_reboot_script",
	       POSTREBOOTHOOK	=> "/system/aii/hooks/post_reboot",
	       POSTREBOOTENDHOOK	=> "/system/aii/hooks/post_reboot_end",
	       POSTSCRIPT	=> "/system/aii/osinstall/ks/post_install_script",
	       POSTHOOK		=> "/system/aii/hooks/post_install",
	       ANACONDAHOOK	=> "/system/aii/hooks/anaconda",
	       PREREBOOTHOOK	=> "/system/aii/hooks/pre_reboot",
	       PKG		=> "/software/packages/",
	       KERNELVERSION	=> "/system/kernel/version",
	       ACKURL		=> "/system/aii/osinstall/ks/ackurl",
	       ACKLIST          => "/system/aii/osinstall/ks/acklist",
	       CARDS		=> "/hardware/cards/nic",
	       SPMAPROXY	=> "/software/components/spma/proxy",
	       SPMA		=> "/software/components/spma",
	       SPMA_OBSOLETES	=> "/software/components/spma/process_obsoletes",
	       ROOTMAIL		=> "/system/rootmail",
	       AII_PROFILE	=> "/system/aii/osinstall/ks/node_profile",
	       CCM_PROFILE	=> "/software/components/ccm/profile",
	       CCM_TRUST	=> "/software/components/ccm/trust",
	       CCM_KEY		=> "/software/components/ccm/key_file",
	       CCM_CERT		=> "/software/components/ccm/cert_file",
	       CCM_CA		=> "/software/components/ccm/ca_file",
	       CCM_WORLDR	=> "/software/components/ccm/world_readable",
               CCM_DBFORMAT     => "/software/components/ccm/dbformat",
	       EMAIL_SUCCESS	=> "/system/aii/osinstall/ks/email_success",
	       NAMESERVER	=> "/system/network/nameserver/0",
	       FORWARDPROXY	=> "forward",
	       END_SCRIPT_FIELD => "/system/aii/osinstall/ks/end_script",
	       BASE_PKGS	=> "/system/aii/osinstall/ks/base_packages",
	       LOCALHOST        => hostname(),
	       ENABLE_SSHD      => "/system/aii/osinstall/ks/enable_sshd",
	   };

# Base package path for user hooks.
use constant   MODULEBASE	=> "AII::";
use constant   USEMODULE	=> "use " . MODULEBASE;

# Configuration variable for the osinstall directory.
use constant   KSDIROPT		=> 'osinstalldir';

# Packages to be installed when setting up Quattor.


# Packages containing kernels. kernel-xen is not listed here, as it
# depends on different versions of mkinitrd and e2fsprogs, and
# installing them may cause a dependency hell.
use constant KERNELLIST		=> qw (kernel-firmware kernel kernel-smp);


# Opens the kickstart file and sets its handle as the default.
sub ksopen
{
    my ($self, $cfg) = @_;

    my $host = $cfg->getElement (HOSTNAME)->getValue;
    my $domain = $cfg->getElement (DOMAINNAME)->getValue;

    my $ksdir = $this_app->option (KSDIROPT);
    $self->debug(3,"Kickstart file directory = $ksdir");

    my $ks = CAF::FileWriter->open ("$ksdir/$host.$domain.ks",
				    mode => 0664, log => $this_app);
    select ($ks);
}

# Prints the opening here doc statement for the post-reboot
# script. It's usefult to separate this, as other plug-ins might want
# only the post_reboot script.
sub kspostreboot_hereopen
{
    print <<EOF;

cat <<End_Of_Post_Reboot > /etc/rc.d/init.d/ks-post-reboot
EOF
}

# Prints the heredoc closing the KS postreboot statement.
sub kspostreboot_hereclose
{
    print <<EOF;

End_Of_Post_Reboot

EOF
}

# Configures the network, allowing both DHCP and static boots.
sub ksnetwork
{
    my ($tree, $config) = @_;

    if ($tree->{bootproto} eq 'dhcp') {
	$this_app->debug (5, "Node configures its network via DHCP");
	print "network --bootproto=dhcp\n";
	return;
    }

    my $dev = $config->getElement("/system/aii/nbp/pxelinux/ksdevice")->getValue;
    my $fqdn = $config->getElement (HOSTNAME)->getValue . "." .
      $config->getElement (DOMAINNAME)->getValue;
    return unless $dev =~ m/eth\d+/;
    $this_app->debug (5, "Node will boot from $dev");
    my $net = $config->getElement("/system/network/interfaces/$dev")->getTree;
    unless (exists ($net->{ip})) {
	    $this_app->error ("Static boot protocol specified ",
			      "but no IP given to the interface");
	    return;
    }

    print "--mtu=$net->{mtu} " if exists($net->{mtu});
    my $gw = '--gateway=';
    if (exists($net->{gateway})) {
        $gw .= $net->{gateway};
    } elsif ($config->elementExists ("/system/network/default_gateway")) {
        $gw .= $config->getElement ("/system/network/default_gateway")->getValue;
    } else {
        # This is a recipe for disaster
        # Best guess is that no gateway is needed.
        $this_app->debug (5, "No gateway defined for dev $dev and ",
			  " using static network description.",
			  "Let's hope everything is reachable through a ",
			  "direct route.");
        $gw='';
        print <<EOF;
## No gateway defined for dev $dev and using static network description.
## Lets hope all is reachable through direct route.
EOF
{'fraction_non_alphanumeric': 0.1444307439375257, 'fraction_numerical': 0.001972872996300863, 'mean_word_length': 3.2184466019417477, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 157, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2102077', 'n_tokens_mistral': 4302, 'n_tokens_neox': 4050, 'n_words': 958}