PVE/LXC: различия между версиями
(Новая страница: «{{stub}} В данной статье описано разворачивание LXC-контейнера c ALT (из готового шаблона) на ор…») |
|||
Строка 15: | Строка 15: | ||
== Подготовка Proxmox == | == Подготовка Proxmox == | ||
'' | Сначала необходимо установить perl-библиотеку - ''Crypt::Eksblowfish::Bcrypt'' (потребуется для установки пароля рута во время разворачивания шаблона): | ||
apt-get install libcrypt-eksblowfish-perl | |||
Затем необходимо внести изменения в скрипты работы с LXC-контейнерами и добавить новый скрипт - для разворачивания шаблона с ALT Linux. | |||
За основу взят [https://packages.altlinux.org/ru/Sisyphus/srpms/pve-manager/patches/pve-container-altlinux-lxc.patch патч] для пакета {{pkg|pve-container}}. | |||
=== Proxmox VE 5.1 === | |||
Проверено на актуальных версиях - [https://www.proxmox.com/en/downloads/item/proxmox-ve-5-1-iso-installer 5.1-35] и 5.1-36. | |||
Необходимо внести изменения в следующие файлы (изменения под спойлером): | |||
<div class="mw-collapsible mw-collapsed"> | |||
* {{path|/usr/share/perl5/PVE/LXC/Config.pm}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/Config.pm b/Config.pm | |||
index 8d71f4a..a73a6be 100644 | |||
--- a/Config.pm | |||
+++ b/Config.pm | |||
@@ -302,7 +302,7 @@ my $confdesc = { | |||
ostype => { | |||
optional => 1, | |||
type => 'string', | |||
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)], | |||
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", | |||
}, | |||
console => { | |||
</source> | |||
</div></div> | |||
<div class="mw-collapsible mw-collapsed"> | |||
*{{path|/usr/share/perl5/PVE/LXC/Setup.pm}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/Setup.pm b/Setup.pm | |||
index 9b91539..672ed02 100644 | |||
--- a/Setup.pm | |||
+++ b/Setup.pm | |||
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE; | |||
use PVE::LXC::Setup::ArchLinux; | |||
use PVE::LXC::Setup::Alpine; | |||
use PVE::LXC::Setup::Gentoo; | |||
+use PVE::LXC::Setup::ALTLinux; | |||
my $plugins = { | |||
debian => 'PVE::LXC::Setup::Debian', | |||
@@ -23,6 +24,7 @@ my $plugins = { | |||
archlinux => 'PVE::LXC::Setup::ArchLinux', | |||
alpine => 'PVE::LXC::Setup::Alpine', | |||
gentoo => 'PVE::LXC::Setup::Gentoo', | |||
+ altlinux => 'PVE::LXC::Setup::ALTLinux', | |||
}; | |||
# a map to allow supporting related distro flavours | |||
@@ -53,6 +55,8 @@ my $autodetect_type = sub { | |||
return "debian"; | |||
} 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") { | |||
@@ -229,7 +233,12 @@ sub rewrite_ssh_host_keys { | |||
my $plugin = $self->{plugin}; | |||
my $rootdir = $self->{rootdir}; | |||
- return if ! -d "$rootdir/etc/ssh"; | |||
+ my $sshdir = "/etc/ssh"; | |||
+ if ( ! -d "$rootdir$sshdir" ) { | |||
+ if ( ! -d "$rootdir/etc/openssh" ) { | |||
+ return; | |||
+ } $sshdir = "/etc/openssh"; | |||
+ } | |||
my $keynames = { | |||
rsa => 'ssh_host_rsa_key', | |||
@@ -246,8 +255,7 @@ sub rewrite_ssh_host_keys { | |||
my $line = shift; | |||
print "done: $line\n" | |||
- if $line =~ m/^(?:[0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i || | |||
- $line =~ m/^SHA256:[0-9a-z+\/]{43}\s+\Q$ssh_comment\E$/i; | |||
+ if ($line =~ m/^([0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i); | |||
}; | |||
# Create temporary keys in /tmp on the host | |||
@@ -257,10 +265,10 @@ sub rewrite_ssh_host_keys { | |||
my $file = "/tmp/$$.$basename"; | |||
print "Creating SSH host key '$basename' - this may take some time ...\n"; | |||
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype, | |||
- '-N', '', '-E', 'sha256', '-C', $ssh_comment]; | |||
+ '-N', '', '-C', $ssh_comment]; | |||
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc); | |||
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
unlink $file; | |||
unlink "$file.pub"; | |||
} | |||
</source> | |||
</div></div> | |||
И добавить новый файл (с описанием инструкций для ALT): | |||
<div class="mw-collapsible mw-collapsed"> | |||
* {{path|/usr/share/perl5/PVE/LXC/Setup/ALTLinux.pm}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="perl"> | |||
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->setup_systemd_console($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 lxc/console)); | |||
} | |||
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; | |||
</source> | |||
</div></div> | |||
Данные файлы можно поправить вручную, а можно с помощью патча. Необходимо создать файл со следующим содержимым (''TODO: добавить ссылку на ftp''): | |||
<div class="mw-collapsible mw-collapsed"> | |||
{{path|pve5-alt-lxc.patch}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/Config.pm b/Config.pm | |||
index 8d71f4a..a73a6be 100644 | |||
--- a/Config.pm | |||
+++ b/Config.pm | |||
@@ -302,7 +302,7 @@ my $confdesc = { | |||
ostype => { | |||
optional => 1, | |||
type => 'string', | |||
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)], | |||
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", | |||
}, | |||
console => { | |||
diff --git a/Setup.pm b/Setup.pm | |||
index 9b91539..672ed02 100644 | |||
--- a/Setup.pm | |||
+++ b/Setup.pm | |||
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE; | |||
use PVE::LXC::Setup::ArchLinux; | |||
use PVE::LXC::Setup::Alpine; | |||
use PVE::LXC::Setup::Gentoo; | |||
+use PVE::LXC::Setup::ALTLinux; | |||
my $plugins = { | |||
debian => 'PVE::LXC::Setup::Debian', | |||
@@ -23,6 +24,7 @@ my $plugins = { | |||
archlinux => 'PVE::LXC::Setup::ArchLinux', | |||
alpine => 'PVE::LXC::Setup::Alpine', | |||
gentoo => 'PVE::LXC::Setup::Gentoo', | |||
+ altlinux => 'PVE::LXC::Setup::ALTLinux', | |||
}; | |||
# a map to allow supporting related distro flavours | |||
@@ -53,6 +55,8 @@ my $autodetect_type = sub { | |||
return "debian"; | |||
} 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") { | |||
@@ -229,7 +233,12 @@ sub rewrite_ssh_host_keys { | |||
my $plugin = $self->{plugin}; | |||
my $rootdir = $self->{rootdir}; | |||
- return if ! -d "$rootdir/etc/ssh"; | |||
+ my $sshdir = "/etc/ssh"; | |||
+ if ( ! -d "$rootdir$sshdir" ) { | |||
+ if ( ! -d "$rootdir/etc/openssh" ) { | |||
+ return; | |||
+ } $sshdir = "/etc/openssh"; | |||
+ } | |||
my $keynames = { | |||
rsa => 'ssh_host_rsa_key', | |||
@@ -246,8 +255,7 @@ sub rewrite_ssh_host_keys { | |||
my $line = shift; | |||
print "done: $line\n" | |||
- if $line =~ m/^(?:[0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i || | |||
- $line =~ m/^SHA256:[0-9a-z+\/]{43}\s+\Q$ssh_comment\E$/i; | |||
+ if ($line =~ m/^([0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i); | |||
}; | |||
# Create temporary keys in /tmp on the host | |||
@@ -257,10 +265,10 @@ sub rewrite_ssh_host_keys { | |||
my $file = "/tmp/$$.$basename"; | |||
print "Creating SSH host key '$basename' - this may take some time ...\n"; | |||
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype, | |||
- '-N', '', '-E', 'sha256', '-C', $ssh_comment]; | |||
+ '-N', '', '-C', $ssh_comment]; | |||
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc); | |||
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
unlink $file; | |||
unlink "$file.pub"; | |||
} | |||
diff --git a/Setup/ALTLinux.pm b/Setup/ALTLinux.pm | |||
new file mode 100644 | |||
index 0000000..177b617 | |||
--- /dev/null | |||
+++ b/Setup/ALTLinux.pm | |||
@@ -0,0 +1,57 @@ | |||
+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->setup_systemd_console($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 lxc/console)); | |||
+} | |||
+ | |||
+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; | |||
</source> | |||
</div></div> | |||
Затем выполнить следующие команды: | |||
<source lang="sh"> | |||
cd /usr/share/perl5/PVE/LXC | |||
patch -p1 -i <path_to>/pve5-alt-lxc.patch | |||
</source> | |||
После изменения скриптов (вручную или патчем) необходимо перезапустить PVE API Daemon: | |||
service pvedaemon restart | |||
Теперь можно спокойно разворачивать контейнер из шаблона с ALT Linux. | |||
=== Proxmox VE 4.4 === | |||
Проверено на свежих версиях - 4.4-18 и 4.4-20. | |||
Необходимо внести изменения в следующие файлы: | |||
*{{path|/usr/share/perl5/PVE/LXC/Config.pm}} - аналогично 5 версии (см. выше); | |||
<div class="mw-collapsible mw-collapsed"> | |||
* {{path|/usr/share/perl5/PVE/LXC/Setup.pm}} - есть немного отличий; | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/LXC/Setup.pm b/LXC/Setup.pm | |||
index 1baeaa2..04fc082 100644 | |||
--- a/LXC/Setup.pm | |||
+++ b/LXC/Setup.pm | |||
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE; | |||
use PVE::LXC::Setup::ArchLinux; | |||
use PVE::LXC::Setup::Alpine; | |||
use PVE::LXC::Setup::Gentoo; | |||
+use PVE::LXC::Setup::ALTLinux; | |||
my $plugins = { | |||
debian => 'PVE::LXC::Setup::Debian', | |||
@@ -23,6 +24,7 @@ my $plugins = { | |||
archlinux => 'PVE::LXC::Setup::ArchLinux', | |||
alpine => 'PVE::LXC::Setup::Alpine', | |||
gentoo => 'PVE::LXC::Setup::Gentoo', | |||
+ altlinux => 'PVE::LXC::Setup::ALTLinux', | |||
}; | |||
my $autodetect_type = sub { | |||
@@ -40,6 +42,8 @@ my $autodetect_type = sub { | |||
return "debian"; | |||
} 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") { | |||
@@ -206,7 +210,12 @@ sub rewrite_ssh_host_keys { | |||
my $plugin = $self->{plugin}; | |||
my $rootdir = $self->{rootdir}; | |||
- return if ! -d "$rootdir/etc/ssh"; | |||
+ my $sshdir = "/etc/ssh"; | |||
+ if ( ! -d "$rootdir$sshdir" ) { | |||
+ if ( ! -d "$rootdir/etc/openssh" ) { | |||
+ return; | |||
+ } $sshdir = "/etc/openssh"; | |||
+ } | |||
my $keynames = { | |||
rsa1 => 'ssh_host_key', | |||
@@ -236,8 +245,8 @@ sub rewrite_ssh_host_keys { | |||
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype, | |||
'-N', '', '-C', $ssh_comment]; | |||
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc); | |||
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
unlink $file; | |||
unlink "$file.pub"; | |||
} | |||
</source> | |||
</div></div> | |||
* {{path|/usr/share/perl5/PVE/LXC/Setup/ALTLinux.pm}} - аналогично 5 версии (см. выше). | |||
Для 4-ой версии Proxmox VE также необходимо подправить LXC.pm: | |||
<div class="mw-collapsible mw-collapsed"> | |||
* {{path|/usr/share/perl5/PVE/LXC.pm}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/LXC.pm b/LXC.pm | |||
index 9413308..947786b 100644 | |||
--- a/LXC.pm | |||
+++ b/LXC.pm | |||
@@ -366,7 +366,7 @@ sub update_lxc_config { | |||
my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}}; | |||
my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error"; | |||
- if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | unmanaged)$/x) { | |||
+ if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | altlinux | unmanaged)$/x) { | |||
my $inc ="/usr/share/lxc/config/$ostype.common.conf"; | |||
$inc ="/usr/share/lxc/config/common.conf" if !-f $inc; | |||
$raw .= "lxc.include = $inc\n"; | |||
</source> | |||
</div></div> | |||
Данные файлы можно поправить вручную, а можно с помощью патча. Необходимо создать файл со следующим содержимым (''TODO: добавить ссылку на ftp''): | |||
<div class="mw-collapsible mw-collapsed"> | |||
{{path|pve4-alt-lxc.patch}} | |||
<div class="mw-collapsible-content"> | |||
<source lang="diff"> | |||
diff --git a/LXC.pm b/LXC.pm | |||
index 9413308..947786b 100644 | |||
--- a/LXC.pm | |||
+++ b/LXC.pm | |||
@@ -366,7 +366,7 @@ sub update_lxc_config { | |||
my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}}; | |||
my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error"; | |||
- if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | unmanaged)$/x) { | |||
+ if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | altlinux | unmanaged)$/x) { | |||
my $inc ="/usr/share/lxc/config/$ostype.common.conf"; | |||
$inc ="/usr/share/lxc/config/common.conf" if !-f $inc; | |||
$raw .= "lxc.include = $inc\n"; | |||
diff --git a/LXC/Config.pm b/LXC/Config.pm | |||
index 05cd970..397f72a 100644 | |||
--- a/LXC/Config.pm | |||
+++ b/LXC/Config.pm | |||
@@ -296,7 +296,7 @@ my $confdesc = { | |||
ostype => { | |||
optional => 1, | |||
type => 'string', | |||
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)], | |||
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", | |||
}, | |||
console => { | |||
diff --git a/LXC/Setup.pm b/LXC/Setup.pm | |||
index 1baeaa2..04fc082 100644 | |||
--- a/LXC/Setup.pm | |||
+++ b/LXC/Setup.pm | |||
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE; | |||
use PVE::LXC::Setup::ArchLinux; | |||
use PVE::LXC::Setup::Alpine; | |||
use PVE::LXC::Setup::Gentoo; | |||
+use PVE::LXC::Setup::ALTLinux; | |||
my $plugins = { | |||
debian => 'PVE::LXC::Setup::Debian', | |||
@@ -23,6 +24,7 @@ my $plugins = { | |||
archlinux => 'PVE::LXC::Setup::ArchLinux', | |||
alpine => 'PVE::LXC::Setup::Alpine', | |||
gentoo => 'PVE::LXC::Setup::Gentoo', | |||
+ altlinux => 'PVE::LXC::Setup::ALTLinux', | |||
}; | |||
my $autodetect_type = sub { | |||
@@ -40,6 +42,8 @@ my $autodetect_type = sub { | |||
return "debian"; | |||
} 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") { | |||
@@ -206,7 +210,12 @@ sub rewrite_ssh_host_keys { | |||
my $plugin = $self->{plugin}; | |||
my $rootdir = $self->{rootdir}; | |||
- return if ! -d "$rootdir/etc/ssh"; | |||
+ my $sshdir = "/etc/ssh"; | |||
+ if ( ! -d "$rootdir$sshdir" ) { | |||
+ if ( ! -d "$rootdir/etc/openssh" ) { | |||
+ return; | |||
+ } $sshdir = "/etc/openssh"; | |||
+ } | |||
my $keynames = { | |||
rsa1 => 'ssh_host_key', | |||
@@ -236,8 +245,8 @@ sub rewrite_ssh_host_keys { | |||
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype, | |||
'-N', '', '-C', $ssh_comment]; | |||
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc); | |||
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600]; | |||
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644]; | |||
unlink $file; | |||
unlink "$file.pub"; | |||
} | |||
diff --git a/LXC/Setup/ALTLinux.pm b/LXC/Setup/ALTLinux.pm | |||
new file mode 100644 | |||
index 0000000..177b617 | |||
--- /dev/null | |||
+++ b/LXC/Setup/ALTLinux.pm | |||
@@ -0,0 +1,57 @@ | |||
+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->setup_systemd_console($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 lxc/console)); | |||
+} | |||
+ | |||
+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; | |||
</source> | |||
</div></div> | |||
Затем выполнить следующие команды: | |||
<source lang="sh"> | |||
cd /usr/share/perl5/PVE #обратите внимание - запуск патча происходит из отличной от 5-ой версии директории | |||
patch -p1 -i <path_to>/pve4-alt-lxc.patch | |||
</source> | |||
После изменения скриптов (вручную или патчем) необходимо перезапустить PVE API Daemon: | |||
service pvedaemon restart | |||
Теперь можно спокойно разворачивать контейнер из шаблона с ALT Linux. | |||
== Создание CT == | == Создание CT == |
Версия от 14:11, 7 декабря 2017
В данной статье описано разворачивание LXC-контейнера c ALT (из готового шаблона) на оригинальном Proxmox VE (который на данный момент на Debian).
Если у Вас установлен любой из дистрибутивов ALT и собственно сам PVE (pve-manager), или стартовый набор server-pve, данная статья Вам не нужна, так как проблем с разворачиванием контейнера не будет.
Создание шаблона
Для этого можно воспользоваться набором инструментов - m-p. Вся информация тут.
Основным требованием для шаблона является наличие в нем systemd. Исходя из статьи Шаблоны для развёртывания CT в PVE, нам подойдет только шаблон ve/systemd-bare.tar.gz. Для его сборки после первоначальной настройки окружения необходимо выполнить следующие команды (предварительно настроив нужный репозиторий с помощью утилиты apt-repo):
$ git clone git://git.altlinux.org/people/mike/packages/mkimage-profiles.git $ cd mkimage-profiles $ make ve/systemd-bare.tar.gz
После этого готовый шаблон нужно загрузить в локальное хранилище PVE.
Подготовка Proxmox
Сначала необходимо установить perl-библиотеку - Crypt::Eksblowfish::Bcrypt (потребуется для установки пароля рута во время разворачивания шаблона):
apt-get install libcrypt-eksblowfish-perl
Затем необходимо внести изменения в скрипты работы с LXC-контейнерами и добавить новый скрипт - для разворачивания шаблона с ALT Linux. За основу взят патч для пакета pve-container.
Proxmox VE 5.1
Проверено на актуальных версиях - 5.1-35 и 5.1-36.
Необходимо внести изменения в следующие файлы (изменения под спойлером):
- /usr/share/perl5/PVE/LXC/Config.pm
diff --git a/Config.pm b/Config.pm
index 8d71f4a..a73a6be 100644
--- a/Config.pm
+++ b/Config.pm
@@ -302,7 +302,7 @@ my $confdesc = {
ostype => {
optional => 1,
type => 'string',
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)],
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.",
},
console => {
- /usr/share/perl5/PVE/LXC/Setup.pm
diff --git a/Setup.pm b/Setup.pm
index 9b91539..672ed02 100644
--- a/Setup.pm
+++ b/Setup.pm
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE;
use PVE::LXC::Setup::ArchLinux;
use PVE::LXC::Setup::Alpine;
use PVE::LXC::Setup::Gentoo;
+use PVE::LXC::Setup::ALTLinux;
my $plugins = {
debian => 'PVE::LXC::Setup::Debian',
@@ -23,6 +24,7 @@ my $plugins = {
archlinux => 'PVE::LXC::Setup::ArchLinux',
alpine => 'PVE::LXC::Setup::Alpine',
gentoo => 'PVE::LXC::Setup::Gentoo',
+ altlinux => 'PVE::LXC::Setup::ALTLinux',
};
# a map to allow supporting related distro flavours
@@ -53,6 +55,8 @@ my $autodetect_type = sub {
return "debian";
} 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") {
@@ -229,7 +233,12 @@ sub rewrite_ssh_host_keys {
my $plugin = $self->{plugin};
my $rootdir = $self->{rootdir};
- return if ! -d "$rootdir/etc/ssh";
+ my $sshdir = "/etc/ssh";
+ if ( ! -d "$rootdir$sshdir" ) {
+ if ( ! -d "$rootdir/etc/openssh" ) {
+ return;
+ } $sshdir = "/etc/openssh";
+ }
my $keynames = {
rsa => 'ssh_host_rsa_key',
@@ -246,8 +255,7 @@ sub rewrite_ssh_host_keys {
my $line = shift;
print "done: $line\n"
- if $line =~ m/^(?:[0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i ||
- $line =~ m/^SHA256:[0-9a-z+\/]{43}\s+\Q$ssh_comment\E$/i;
+ if ($line =~ m/^([0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i);
};
# Create temporary keys in /tmp on the host
@@ -257,10 +265,10 @@ sub rewrite_ssh_host_keys {
my $file = "/tmp/$$.$basename";
print "Creating SSH host key '$basename' - this may take some time ...\n";
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype,
- '-N', '', '-E', 'sha256', '-C', $ssh_comment];
+ '-N', '', '-C', $ssh_comment];
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc);
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
unlink $file;
unlink "$file.pub";
}
И добавить новый файл (с описанием инструкций для ALT):
- /usr/share/perl5/PVE/LXC/Setup/ALTLinux.pm
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->setup_systemd_console($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 lxc/console));
}
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;
Данные файлы можно поправить вручную, а можно с помощью патча. Необходимо создать файл со следующим содержимым (TODO: добавить ссылку на ftp):
pve5-alt-lxc.patch
diff --git a/Config.pm b/Config.pm
index 8d71f4a..a73a6be 100644
--- a/Config.pm
+++ b/Config.pm
@@ -302,7 +302,7 @@ my $confdesc = {
ostype => {
optional => 1,
type => 'string',
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)],
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.",
},
console => {
diff --git a/Setup.pm b/Setup.pm
index 9b91539..672ed02 100644
--- a/Setup.pm
+++ b/Setup.pm
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE;
use PVE::LXC::Setup::ArchLinux;
use PVE::LXC::Setup::Alpine;
use PVE::LXC::Setup::Gentoo;
+use PVE::LXC::Setup::ALTLinux;
my $plugins = {
debian => 'PVE::LXC::Setup::Debian',
@@ -23,6 +24,7 @@ my $plugins = {
archlinux => 'PVE::LXC::Setup::ArchLinux',
alpine => 'PVE::LXC::Setup::Alpine',
gentoo => 'PVE::LXC::Setup::Gentoo',
+ altlinux => 'PVE::LXC::Setup::ALTLinux',
};
# a map to allow supporting related distro flavours
@@ -53,6 +55,8 @@ my $autodetect_type = sub {
return "debian";
} 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") {
@@ -229,7 +233,12 @@ sub rewrite_ssh_host_keys {
my $plugin = $self->{plugin};
my $rootdir = $self->{rootdir};
- return if ! -d "$rootdir/etc/ssh";
+ my $sshdir = "/etc/ssh";
+ if ( ! -d "$rootdir$sshdir" ) {
+ if ( ! -d "$rootdir/etc/openssh" ) {
+ return;
+ } $sshdir = "/etc/openssh";
+ }
my $keynames = {
rsa => 'ssh_host_rsa_key',
@@ -246,8 +255,7 @@ sub rewrite_ssh_host_keys {
my $line = shift;
print "done: $line\n"
- if $line =~ m/^(?:[0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i ||
- $line =~ m/^SHA256:[0-9a-z+\/]{43}\s+\Q$ssh_comment\E$/i;
+ if ($line =~ m/^([0-9a-f]{2}:)+[0-9a-f]{2}\s+\Q$ssh_comment\E$/i);
};
# Create temporary keys in /tmp on the host
@@ -257,10 +265,10 @@ sub rewrite_ssh_host_keys {
my $file = "/tmp/$$.$basename";
print "Creating SSH host key '$basename' - this may take some time ...\n";
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype,
- '-N', '', '-E', 'sha256', '-C', $ssh_comment];
+ '-N', '', '-C', $ssh_comment];
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc);
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
unlink $file;
unlink "$file.pub";
}
diff --git a/Setup/ALTLinux.pm b/Setup/ALTLinux.pm
new file mode 100644
index 0000000..177b617
--- /dev/null
+++ b/Setup/ALTLinux.pm
@@ -0,0 +1,57 @@
+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->setup_systemd_console($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 lxc/console));
+}
+
+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;
Затем выполнить следующие команды:
cd /usr/share/perl5/PVE/LXC
patch -p1 -i <path_to>/pve5-alt-lxc.patch
После изменения скриптов (вручную или патчем) необходимо перезапустить PVE API Daemon:
service pvedaemon restart
Теперь можно спокойно разворачивать контейнер из шаблона с ALT Linux.
Proxmox VE 4.4
Проверено на свежих версиях - 4.4-18 и 4.4-20.
Необходимо внести изменения в следующие файлы:
- /usr/share/perl5/PVE/LXC/Config.pm - аналогично 5 версии (см. выше);
- /usr/share/perl5/PVE/LXC/Setup.pm - есть немного отличий;
diff --git a/LXC/Setup.pm b/LXC/Setup.pm
index 1baeaa2..04fc082 100644
--- a/LXC/Setup.pm
+++ b/LXC/Setup.pm
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE;
use PVE::LXC::Setup::ArchLinux;
use PVE::LXC::Setup::Alpine;
use PVE::LXC::Setup::Gentoo;
+use PVE::LXC::Setup::ALTLinux;
my $plugins = {
debian => 'PVE::LXC::Setup::Debian',
@@ -23,6 +24,7 @@ my $plugins = {
archlinux => 'PVE::LXC::Setup::ArchLinux',
alpine => 'PVE::LXC::Setup::Alpine',
gentoo => 'PVE::LXC::Setup::Gentoo',
+ altlinux => 'PVE::LXC::Setup::ALTLinux',
};
my $autodetect_type = sub {
@@ -40,6 +42,8 @@ my $autodetect_type = sub {
return "debian";
} 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") {
@@ -206,7 +210,12 @@ sub rewrite_ssh_host_keys {
my $plugin = $self->{plugin};
my $rootdir = $self->{rootdir};
- return if ! -d "$rootdir/etc/ssh";
+ my $sshdir = "/etc/ssh";
+ if ( ! -d "$rootdir$sshdir" ) {
+ if ( ! -d "$rootdir/etc/openssh" ) {
+ return;
+ } $sshdir = "/etc/openssh";
+ }
my $keynames = {
rsa1 => 'ssh_host_key',
@@ -236,8 +245,8 @@ sub rewrite_ssh_host_keys {
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype,
'-N', '', '-C', $ssh_comment];
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc);
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
unlink $file;
unlink "$file.pub";
}
- /usr/share/perl5/PVE/LXC/Setup/ALTLinux.pm - аналогично 5 версии (см. выше).
Для 4-ой версии Proxmox VE также необходимо подправить LXC.pm:
- /usr/share/perl5/PVE/LXC.pm
diff --git a/LXC.pm b/LXC.pm
index 9413308..947786b 100644
--- a/LXC.pm
+++ b/LXC.pm
@@ -366,7 +366,7 @@ sub update_lxc_config {
my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}};
my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error";
- if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | unmanaged)$/x) {
+ if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | altlinux | unmanaged)$/x) {
my $inc ="/usr/share/lxc/config/$ostype.common.conf";
$inc ="/usr/share/lxc/config/common.conf" if !-f $inc;
$raw .= "lxc.include = $inc\n";
Данные файлы можно поправить вручную, а можно с помощью патча. Необходимо создать файл со следующим содержимым (TODO: добавить ссылку на ftp):
pve4-alt-lxc.patch
diff --git a/LXC.pm b/LXC.pm
index 9413308..947786b 100644
--- a/LXC.pm
+++ b/LXC.pm
@@ -366,7 +366,7 @@ sub update_lxc_config {
my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}};
my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error";
- if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | unmanaged)$/x) {
+ if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | altlinux | unmanaged)$/x) {
my $inc ="/usr/share/lxc/config/$ostype.common.conf";
$inc ="/usr/share/lxc/config/common.conf" if !-f $inc;
$raw .= "lxc.include = $inc\n";
diff --git a/LXC/Config.pm b/LXC/Config.pm
index 05cd970..397f72a 100644
--- a/LXC/Config.pm
+++ b/LXC/Config.pm
@@ -296,7 +296,7 @@ my $confdesc = {
ostype => {
optional => 1,
type => 'string',
- enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)],
+ enum => [qw(debian 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/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.",
},
console => {
diff --git a/LXC/Setup.pm b/LXC/Setup.pm
index 1baeaa2..04fc082 100644
--- a/LXC/Setup.pm
+++ b/LXC/Setup.pm
@@ -13,6 +13,7 @@ use PVE::LXC::Setup::SUSE;
use PVE::LXC::Setup::ArchLinux;
use PVE::LXC::Setup::Alpine;
use PVE::LXC::Setup::Gentoo;
+use PVE::LXC::Setup::ALTLinux;
my $plugins = {
debian => 'PVE::LXC::Setup::Debian',
@@ -23,6 +24,7 @@ my $plugins = {
archlinux => 'PVE::LXC::Setup::ArchLinux',
alpine => 'PVE::LXC::Setup::Alpine',
gentoo => 'PVE::LXC::Setup::Gentoo',
+ altlinux => 'PVE::LXC::Setup::ALTLinux',
};
my $autodetect_type = sub {
@@ -40,6 +42,8 @@ my $autodetect_type = sub {
return "debian";
} 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") {
@@ -206,7 +210,12 @@ sub rewrite_ssh_host_keys {
my $plugin = $self->{plugin};
my $rootdir = $self->{rootdir};
- return if ! -d "$rootdir/etc/ssh";
+ my $sshdir = "/etc/ssh";
+ if ( ! -d "$rootdir$sshdir" ) {
+ if ( ! -d "$rootdir/etc/openssh" ) {
+ return;
+ } $sshdir = "/etc/openssh";
+ }
my $keynames = {
rsa1 => 'ssh_host_key',
@@ -236,8 +245,8 @@ sub rewrite_ssh_host_keys {
my $cmd = ['ssh-keygen', '-f', $file, '-t', $keytype,
'-N', '', '-C', $ssh_comment];
PVE::Tools::run_command($cmd, outfunc => $keygen_outfunc);
- $keyfiles->{"/etc/ssh/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
- $keyfiles->{"/etc/ssh/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
+ $keyfiles->{"$sshdir/$basename"} = [PVE::Tools::file_get_contents($file), 0600];
+ $keyfiles->{"$sshdir/$basename.pub"} = [PVE::Tools::file_get_contents("$file.pub"), 0644];
unlink $file;
unlink "$file.pub";
}
diff --git a/LXC/Setup/ALTLinux.pm b/LXC/Setup/ALTLinux.pm
new file mode 100644
index 0000000..177b617
--- /dev/null
+++ b/LXC/Setup/ALTLinux.pm
@@ -0,0 +1,57 @@
+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->setup_systemd_console($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 lxc/console));
+}
+
+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;
Затем выполнить следующие команды:
cd /usr/share/perl5/PVE #обратите внимание - запуск патча происходит из отличной от 5-ой версии директории
patch -p1 -i <path_to>/pve4-alt-lxc.patch
После изменения скриптов (вручную или патчем) необходимо перезапустить PVE API Daemon:
service pvedaemon restart
Теперь можно спокойно разворачивать контейнер из шаблона с ALT Linux.
Создание CT
Подробнее об этом читайте тут. Отличий нет.