optional => 1,
type => 'string',
description => "Sets root password inside container.",
+ minLength => 5,
},
storage => get_standard_option('pve-storage-id', {
description => "Target storage.",
my $cmd = ['lxc-create', '-f', $temp_conf_fn, '-t', 'pve', '-n', $vmid,
'--', '--archive', $archive];
+ if (defined($password)) {
+ push $cmd, '--password', $password
+ }
+
eval { PVE::Tools::run_command($cmd); };
my $err = $@;
$self->{plugin}->setup_init($self->{conf});
}
-sub set_user_passwort {
- die "fixme";
+sub set_user_password {
+ my ($self, $user, $pw) = @_;
+
+ $self->{plugin}->set_user_password($self->{conf}, $user, $pw);
}
sub pre_start_hook {
}
sub post_create_hook {
- my ($self) = @_;
+ my ($self, $root_password) = @_;
- $self->{plugin}->post_create_hook($self->{conf});
+ $self->{plugin}->post_create_hook($self->{conf}, $root_password);
}
1;
use strict;
use warnings;
+use File::stat;
+use Digest::SHA;
+use IO::File;
+use Encode;
+
use PVE::Tools;
my $update_etc_hosts = sub {
die "please implement this inside subclass"
}
+my $replacepw = sub {
+ my ($file, $user, $epw) = @_;
+
+ my $tmpfile = "$file.$$";
+
+ eval {
+ my $src = IO::File->new("<$file") ||
+ die "unable to open file '$file' - $!";
+
+ my $st = File::stat::stat($src) ||
+ die "unable to stat file - $!";
+
+ my $dst = IO::File->new(">$tmpfile") ||
+ die "unable to open file '$tmpfile' - $!";
+
+ # copy owner and permissions
+ chmod $st->mode, $dst;
+ chown $st->uid, $st->gid, $dst;
+
+ while (defined (my $line = <$src>)) {
+ $line =~ s/^${user}:[^:]*:/${user}:${epw}:/;
+ print $dst $line;
+ }
+
+ $src->close() || die "close '$file' failed - $!\n";
+ $dst->close() || die "close '$tmpfile' failed - $!\n";
+ };
+ if (my $err = $@) {
+ unlink $tmpfile;
+ } else {
+ rename $tmpfile, $file;
+ unlink $tmpfile; # in case rename fails
+ }
+};
+
+sub set_user_password {
+ my ($class, $conf, $user, $opt_password) = @_;
+
+ my $rootfs = $conf->{'lxc.rootfs'};
+
+ my $pwfile = "$rootfs/etc/passwd";
+
+ return if ! -f $pwfile;
+
+ my $shadow = "$rootfs/etc/shadow";
+
+ if (defined($opt_password)) {
+ if ($opt_password !~ m/^\$/) {
+ my $time = substr (Digest::SHA::sha1_base64 (time), 0, 8);
+ $opt_password = crypt(encode("utf8", $opt_password), "\$1\$$time\$");
+ };
+ } else {
+ $opt_password = '*';
+ }
+
+ if (-f $shadow) {
+ &$replacepw ($shadow, $user, $opt_password);
+ &$replacepw ($pwfile, $user, 'x');
+ } else {
+ &$replacepw ($pwfile, $user, $opt_password);
+ }
+}
+
sub pre_start_hook {
my ($class, $conf) = @_;
}
sub post_create_hook {
- my ($class, $conf) = @_;
+ my ($class, $conf, $root_password) = @_;
+ $class->set_user_password($conf, 'root', $root_password);
$class->setup_init($conf);
$class->setup_network($conf);
$class->set_hostname($conf);
$class->set_dns($conf);
-
+
# fixme: what else ?
}
description => "Path to the template tar file.",
type => 'string',
},
+ password => {
+ optional => 1,
+ type => 'string',
+ description => "Sets root password inside container.",
+ },
'mapped-uid' => {
description => " A uid map (user namespaces - LXC internal argument - do not pass manually!)",
type => 'string',
# fixme: use correct dist
my $lxc_setup = PVE::LXCSetup->new($conf);
- $lxc_setup->post_create_hook();
+ $lxc_setup->post_create_hook($param->{password});
return undef;
}});
for (my $i = 0; $i < 2; $i++) {
# run tests twice, to make sure scripts are idempotent
- $lxc_setup->post_create_hook();
+ $lxc_setup->post_create_hook('$TEST$ABCDEF');
- my @testfiles = qw(/etc/hostname /etc/hosts /etc/inittab /etc/network/interfaces /etc/resolv.conf);
+ my @testfiles = qw(/etc/hostname /etc/hosts /etc/inittab /etc/network/interfaces /etc/resolv.conf /etc/passwd /etc/shadow);
foreach my $fn (@testfiles) {
next if !-f "$testdir/$fn.exp";
test_file("$testdir/$fn.exp", "$rootfs/$fn");
--- /dev/null
+lxc.utsname = test9
--- /dev/null
+127.0.0.1 localhost.localnet localhost
+127.0.1.1 test9
--- /dev/null
+root:x:0:0:root:/root:/bin/bash
+daemon:x:1:1:daemon:/usr/sbin:/bin/sh
+bin:x:2:2:bin:/bin:/bin/sh
+sys:x:3:3:sys:/dev:/bin/sh
+sync:x:4:65534:sync:/bin:/bin/sync
+games:x:5:60:games:/usr/games:/bin/sh
+man:x:6:12:man:/var/cache/man:/bin/sh
+lp:x:7:7:lp:/var/spool/lpd:/bin/sh
+mail:x:8:8:mail:/var/mail:/bin/sh
+news:x:9:9:news:/var/spool/news:/bin/sh
+uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
+proxy:x:13:13:proxy:/bin:/bin/sh
+www-data:x:33:33:www-data:/var/www:/bin/sh
+backup:x:34:34:backup:/var/backups:/bin/sh
+list:x:38:38:Mailing List Manager:/var/list:/bin/sh
+irc:x:39:39:ircd:/var/run/ircd:/bin/sh
+gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
+nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
+libuuid:x:100:101::/var/lib/libuuid:/bin/sh
+postfix:x:101:104::/var/spool/postfix:/bin/false
+sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin
--- /dev/null
+root:x:0:0:root:/root:/bin/bash
+daemon:x:1:1:daemon:/usr/sbin:/bin/sh
+bin:x:2:2:bin:/bin:/bin/sh
+sys:x:3:3:sys:/dev:/bin/sh
+sync:x:4:65534:sync:/bin:/bin/sync
+games:x:5:60:games:/usr/games:/bin/sh
+man:x:6:12:man:/var/cache/man:/bin/sh
+lp:x:7:7:lp:/var/spool/lpd:/bin/sh
+mail:x:8:8:mail:/var/mail:/bin/sh
+news:x:9:9:news:/var/spool/news:/bin/sh
+uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
+proxy:x:13:13:proxy:/bin:/bin/sh
+www-data:x:33:33:www-data:/var/www:/bin/sh
+backup:x:34:34:backup:/var/backups:/bin/sh
+list:x:38:38:Mailing List Manager:/var/list:/bin/sh
+irc:x:39:39:ircd:/var/run/ircd:/bin/sh
+gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
+nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
+libuuid:x:100:101::/var/lib/libuuid:/bin/sh
+postfix:x:101:104::/var/spool/postfix:/bin/false
+sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin
--- /dev/null
+root:!*:15908:0:99999:7:::
+daemon:*:15908:0:99999:7:::
+bin:*:15908:0:99999:7:::
+sys:*:15908:0:99999:7:::
+sync:*:15908:0:99999:7:::
+games:*:15908:0:99999:7:::
+man:*:15908:0:99999:7:::
+lp:*:15908:0:99999:7:::
+mail:*:15908:0:99999:7:::
+news:*:15908:0:99999:7:::
+uucp:*:15908:0:99999:7:::
+proxy:*:15908:0:99999:7:::
+www-data:*:15908:0:99999:7:::
+backup:*:15908:0:99999:7:::
+list:*:15908:0:99999:7:::
+irc:*:15908:0:99999:7:::
+gnats:*:15908:0:99999:7:::
+nobody:*:15908:0:99999:7:::
+libuuid:!:15908:0:99999:7:::
+postfix:*:15908:0:99999:7:::
+sshd:*:15908:0:99999:7:::
--- /dev/null
+root:$TEST$ABCDEF:15908:0:99999:7:::
+daemon:*:15908:0:99999:7:::
+bin:*:15908:0:99999:7:::
+sys:*:15908:0:99999:7:::
+sync:*:15908:0:99999:7:::
+games:*:15908:0:99999:7:::
+man:*:15908:0:99999:7:::
+lp:*:15908:0:99999:7:::
+mail:*:15908:0:99999:7:::
+news:*:15908:0:99999:7:::
+uucp:*:15908:0:99999:7:::
+proxy:*:15908:0:99999:7:::
+www-data:*:15908:0:99999:7:::
+backup:*:15908:0:99999:7:::
+list:*:15908:0:99999:7:::
+irc:*:15908:0:99999:7:::
+gnats:*:15908:0:99999:7:::
+nobody:*:15908:0:99999:7:::
+libuuid:!:15908:0:99999:7:::
+postfix:*:15908:0:99999:7:::
+sshd:*:15908:0:99999:7:::