diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm index c2bec1f..a426a29 100644 --- a/src/PVE/LXC/Config.pm +++ b/src/PVE/LXC/Config.pm @@ -472,7 +472,7 @@ my $confdesc = { ostype => { optional => 1, type => 'string', - enum => [qw(debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged)], + enum => [qw(debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo altlinux unmanaged)], description => "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", }, console => { diff --git a/src/PVE/LXC/Setup.pm b/src/PVE/LXC/Setup.pm index 891231f..f1caed6 100644 --- a/src/PVE/LXC/Setup.pm +++ b/src/PVE/LXC/Setup.pm @@ -9,6 +9,7 @@ use Cwd 'abs_path'; use PVE::Tools; use PVE::LXC::Setup::Alpine; +use PVE::LXC::Setup::ALTLinux; use PVE::LXC::Setup::ArchLinux; use PVE::LXC::Setup::CentOS; use PVE::LXC::Setup::Debian; @@ -22,6 +23,7 @@ use PVE::LXC::Setup::Unmanaged; my $plugins = { alpine => 'PVE::LXC::Setup::Alpine', + altlinux => 'PVE::LXC::Setup::ALTLinux', archlinux => 'PVE::LXC::Setup::ArchLinux', centos => 'PVE::LXC::Setup::CentOS', debian => 'PVE::LXC::Setup::Debian', @@ -67,6 +69,8 @@ my $autodetect_type = sub { return "devuan"; } elsif (-f "$rootdir/etc/SuSE-brand" || -f "$rootdir/etc/SuSE-release") { return "opensuse"; + } elsif (-f "$rootdir/etc/altlinux-release") { + return "altlinux"; } elsif (-f "$rootdir/etc/fedora-release") { return "fedora"; } elsif (-f "$rootdir/etc/centos-release" || -f "$rootdir/etc/redhat-release") { @@ -239,7 +243,13 @@ sub rewrite_ssh_host_keys { my $keynames = $plugin->ssh_host_key_types_to_generate(); - return if ! -d "$self->{rootdir}/etc/ssh" || !$keynames || !scalar(keys $keynames->%*); + my $sshdir = "/etc/ssh"; + if ( ! -d "$self->{rootdir}$sshdir" || !$keynames || !scalar(keys $keynames->%*) ) { + if ( ! -d "$self->{rootdir}/etc/openssh" || !$keynames || !scalar(keys $keynames->%*) ) { + return; + } + $sshdir = "/etc/openssh"; + } my $hostname = $self->{conf}->{hostname} || 'localhost'; $hostname =~ s/\..*$//; @@ -251,7 +261,7 @@ sub rewrite_ssh_host_keys { my ($id, $private, $public) = generate_ssh_key($keytype, "root\@$hostname"); print "done: $id\n"; - push $keyfiles->@*, ["/etc/ssh/$basename", $private, 0600], ["/etc/ssh/$basename.pub", $public, 0644]; + push $keyfiles->@*, ["$sshdir/$basename", $private, 0600], ["$sshdir/$basename.pub", $public, 0644]; } $self->protected_call(sub { # write them now all to the CTs rootfs at once diff --git a/src/PVE/LXC/Setup/ALTLinux.pm b/src/PVE/LXC/Setup/ALTLinux.pm new file mode 100644 index 0000000..08b220a --- /dev/null +++ b/src/PVE/LXC/Setup/ALTLinux.pm @@ -0,0 +1,60 @@ +package PVE::LXC::Setup::ALTLinux; + +use strict; +use warnings; +use Digest::SHA; +use Crypt::Eksblowfish::Bcrypt; +use PVE::LXC::Setup::Base; +use base qw(PVE::LXC::Setup::Base); + +sub new { + my ($class, $conf, $rootdir) = @_; + my $ostype = "altlinux"; + my $version = PVE::Tools::file_read_firstline("$rootdir/etc/$ostype-release"); + my $self = { conf => $conf, rootdir => $rootdir, version => $version }; + $conf->{ostype} = $ostype; + return bless $self, $class; +} + +sub setup_init { + my ($self, $conf) = @_; + + $self->fixup_old_getty(); + + $self->setup_container_getty_service($conf); +} + +sub setup_network { + my ($self, $conf) = @_; + $self->setup_systemd_networkd($conf); +} + +sub template_fixup { + my ($self, $conf) = @_; + $self->setup_securetty($conf, qw(pts/0 console lxc/console lxc/tty1 lxc/tty2)); +} + +sub set_user_password { + my ($self, $conf, $user, $opt_password) = @_; + + my $shadowfile = "/etc/tcb/$user/shadow"; + return if !$self->ct_file_exists($shadowfile); + + if (defined($opt_password)) { + if ($opt_password !~ m/^\$/) { + my $salt = Crypt::Eksblowfish::Bcrypt::en_base64(substr(Digest::SHA::sha1_base64(time), 0, 16)); + $opt_password = Crypt::Eksblowfish::Bcrypt::bcrypt($opt_password, '$2a$08$'.$salt); + }; + } else { + $opt_password = '*'; + } + + my $data = $user . ":" . $opt_password . ":" . (int(time()/86400)) . "::::::\n"; + + my $st = $self->ct_stat($shadowfile) || die "unable to stat file - $!"; + $self->ct_file_set_contents($shadowfile, $data); + chmod $st->mode, $shadowfile; + chown $st->uid, $st->gid, $shadowfile; +} + +1; diff --git a/src/PVE/LXC/Setup/Base.pm b/src/PVE/LXC/Setup/Base.pm index 547abdb..c05d471 100644 --- a/src/PVE/LXC/Setup/Base.pm +++ b/src/PVE/LXC/Setup/Base.pm @@ -597,7 +597,7 @@ sub post_clone_hook { sub post_create_hook { my ($self, $conf, $root_password, $ssh_keys) = @_; - $self->clear_machine_id($conf); + $self->clear_machine_id($conf, 1); $self->template_fixup($conf); &$randomize_crontab($self, $conf); diff --git a/src/lxcnetdelbr b/src/lxcnetdelbr new file mode 100644 index 0000000..f1219f5 --- /dev/null +++ b/src/lxcnetdelbr @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +exit 0 if $ENV{LXC_NAME} && $ENV{LXC_NAME} !~ /^\d+$/; + +use PVE::Network; + +die "got unexpected argument count\n" if scalar(@ARGV) != 5; + +my ($vmid, $arg2, $arg3, $type, $iface) = @ARGV; + +die "got unexpected argument ($arg2 != net)\n" if $arg2 ne 'net'; +die "got unexpected argument ($arg3 != down)\n" if $arg3 ne 'down'; +die "got unexpected argument ($type != veth)\n" if $type ne 'veth'; +die "got unexpected environment" if $vmid ne $ENV{LXC_NAME}; +die "missing vmid parameter\n" if !$vmid; +die "missing iface parameter\n" if !$iface; + +PVE::Network::tap_unplug($iface); + +exit 0;