Commit bec1da7a authored by Dietmar Maurer's avatar Dietmar Maurer

support more than 'local' storage for openvz.

It is now possible to use NFS or other directory type storages.
parent 6ea2c67c
......@@ -87,16 +87,16 @@ __PACKAGE__->register_method({
}});
my $restore_openvz = sub {
my ($archive, $vmid, $force) = @_;
my ($private, $archive, $vmid, $force) = @_;
my $vzconf = PVE::OpenVZ::read_global_vz_config ();
my $conffile = PVE::OpenVZ::config_file($vmid);
my $cfgdir = dirname($conffile);
my $private = $vzconf->{privatedir};
$private =~ s/\$VEID/$vmid/;
my $root = $vzconf->{rootdir};
$root =~ s/\$VEID/$vmid/;
my $default_private = $vzconf->{privatedir};
$default_private =~ s/\$VEID/$vmid/;
print "you choose to force overwriting VPS config file, private and root directories.\n" if $force;
......@@ -112,8 +112,15 @@ my $restore_openvz = sub {
my $conf;
eval {
rmtree $private if -d $private;
rmtree $root if -d $root;
if ($force && -f $conffile) {
my $conf = PVE::OpenVZ::load_config($vmid);
my $oldprivate = $conf->{ve_private} ? $conf->{ve_private}->{value} : $default_private;
rmtree $oldprivate if -d $oldprivate;
my $oldroot = $conf->{ve_root} ? $conf->{ve_root}->{value} : $root;
rmtree $oldroot if -d $oldroot;
};
mkpath $private || die "unable to create private dir '$private'";
mkpath $root || die "unable to create private dir '$private'";
......@@ -191,6 +198,11 @@ __PACKAGE__->register_method({
type => 'string',
description => "Sets root password inside container.",
},
storage => get_standard_option('pve-storage-id', {
description => "Target storage.",
default => 'local',
optional => 1,
}),
force => {
optional => 1,
type => 'boolean',
......@@ -219,7 +231,18 @@ __PACKAGE__->register_method({
my $password = extract_param($param, 'password');
my $stcfg = cfs_read_file("storage.cfg");
my $storage = extract_param($param, 'storage') || 'local';
my $storage_cfg = cfs_read_file("storage.cfg");
my $scfg = PVE::Storage::storage_check_node($storage_cfg, $storage, $node);
raise_param_exc({ storage => "storage '$storage' does not support openvz root directories"})
if !$scfg->{content}->{rootdir};
my $private = PVE::Storage::get_private_dir($storage_cfg, $storage, $vmid);
PVE::Storage::activate_storage($storage_cfg, $storage);
my $conf = PVE::OpenVZ::parse_ovz_config("/tmp/openvz/$vmid.conf", $pve_base_ovz_config);
......@@ -245,7 +268,7 @@ __PACKAGE__->register_method({
$archive = '-';
} else {
if (PVE::Storage::parse_volume_id($ostemplate, 1)) {
$archive = PVE::Storage::path($stcfg, $ostemplate);
$archive = PVE::Storage::path($storage_cfg, $ostemplate);
} else {
raise_param_exc({ archive => "Only root can pass arbitrary paths." })
if $user ne 'root@pam';
......@@ -275,6 +298,7 @@ __PACKAGE__->register_method({
$conf->{ostemplate}->{value} = $archive;
$conf->{ostemplate}->{value} =~ s|^.*/||;
$conf->{ostemplate}->{value} =~ s/\.tar\.(gz|bz2)$//;
$conf->{ve_private}->{value} = $private;
}
my $rawconf = PVE::OpenVZ::generate_raw_config($pve_base_ovz_config, $conf);
......@@ -282,14 +306,14 @@ __PACKAGE__->register_method({
PVE::Cluster::check_cfs_quorum();
my $realcmd = sub {
&$restore_openvz($archive, $vmid, $param->{force});
&$restore_openvz($private, $archive, $vmid, $param->{force});
PVE::Tools::file_set_contents($basecfg_fn, $rawconf)
if !$param->{restore};
# hack: vzctl '--userpasswd' starts the CT, but we want
# to avoid that for create
PVE::OpenVZ::set_rootpasswd($vmid, $password) if defined($password);
PVE::OpenVZ::set_rootpasswd($private, $password) if defined($password);
};
return $rpcenv->fork_worker($param->{restore} ? 'vzrestore' : 'vzcreate',
......
......@@ -197,7 +197,7 @@ sub vmstatus {
if (my $fh = IO::File->new ("/proc/mounts", "r")) {
while (defined (my $line = <$fh>)) {
if ($line =~ m|^/var/lib/vz/private/(\d+)\s+/var/lib/vz/root/|) {
if ($line =~ m|/private/(\d+)\s+/var/lib/vz/root/\d+\s|) {
$list->{$1}->{status} = 'mounted' if defined($list->{$1});
}
}
......@@ -219,7 +219,7 @@ sub vmstatus {
if (my $fh = IO::File->new ("/proc/vz/vzquota", "r")) {
while (defined (my $line = <$fh>)) {
if ($line =~ m|^(\d+):\s+/var/lib/vz/private/\d+$|) {
if ($line =~ m|^(\d+):\s+\S+/private/\d+$|) {
my $vmid = $1;
my $d = $list->{$vmid};
if ($d && defined($d->{status})) {
......@@ -1173,16 +1173,13 @@ sub replacepw {
}
sub set_rootpasswd {
my ($vmid, $opt_rootpasswd) = @_;
my ($privatedir, $opt_rootpasswd) = @_;
my $vmdir = $global_vzconf->{privatedir};
$vmdir =~ s/\$VEID/$vmid/;
my $pwfile = "$vmdir/etc/passwd";
my $pwfile = "$privatedir/etc/passwd";
return if ! -f $pwfile;
my $shadow = "$vmdir/etc/shadow";
my $shadow = "$privatedir/etc/shadow";
if ($opt_rootpasswd !~ m/^\$/) {
my $time = substr (Digest::SHA1::sha1_base64 (time), 0, 8);
......
......@@ -564,6 +564,8 @@ Ext.define('PVE.Utils', { statics: {
cta.push('Templates');
} else if (ct === 'iso') {
cta.push('ISO');
} else if (ct === 'rootdir') {
cta.push('Containers');
}
});
......
......@@ -5,12 +5,12 @@ Ext.define('PVE.form.ContentTypeSelector', {
initComponent: function() {
var me = this;
me.data = [
['images', 'Images'],
['iso', 'ISO'],
['vztmpl', 'Templates'],
['backup', 'Backups']
];
me.data = [];
var cts = ['images', 'iso', 'vztmpl', 'backup', 'rootdir'];
Ext.Array.each(cts, function(ct) {
me.data.push([ct, PVE.Utils.format_content_types(ct)]);
});
me.callParent();
}
......
......@@ -80,16 +80,23 @@ Ext.define('PVE.grid.BackupView', {
text: 'Restore',
disabled: true,
selModel: sm,
confirmMsg: function(rec) {
return 'Are you sure you want to restore from "' + rec.data.volid + '"? ' +
'This will permanently erase current VM data.';
},
enableFn: function(rec) {
return !!rec;
},
handler: function(b, e, rec) {
var volid = rec.data.volid;
var win = Ext.create('PVE.window.Restore', {
nodename: nodename,
vmid: vmid,
volid: rec.data.volid,
volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
vmtype: vmtype
});
win.show();
win.on('destroy', reload);
return;
var url;
var params = {
vmid: vmid,
......
......@@ -20,6 +20,14 @@ Ext.define('PVE.openvz.CreateWizard', {
]
});
var storagesel = Ext.create('PVE.form.StorageSelector', {
name: 'storage',
fieldLabel: 'Storage',
storageContent: 'rootdir',
autoSelect: true,
allowBlank: false
});
var tmplsel = Ext.create('PVE.form.FileSelector', {
name: 'ostemplate',
storageContent: 'vztmpl',
......@@ -53,6 +61,7 @@ Ext.define('PVE.openvz.CreateWizard', {
change: function(f, value) {
tmplsel.setStorage('local', value);
bridgesel.setNodename(value);
storagesel.setNodename(value);
}
}
},
......@@ -72,6 +81,7 @@ Ext.define('PVE.openvz.CreateWizard', {
}
],
column2: [
storagesel,
{
xtype: 'textfield',
inputType: 'password',
......
......@@ -42,9 +42,10 @@ Ext.define('PVE.window.Restore', {
},
storagesel,
{
xtype: 'pveVMIDSelector',
xtype: me.vmid ? 'displayfield' : 'pveVMIDSelector',
name: 'vmid',
value: PVE.data.ResourceStore.findNextVMID(),
fieldLabel: 'VM ID',
value: me.vmid || PVE.data.ResourceStore.findNextVMID(),
validateExists: false
}
]
......@@ -56,6 +57,26 @@ Ext.define('PVE.window.Restore', {
submitBtn.setDisabled(!valid);
});
var doRestore = function(url, params) {
PVE.Utils.API2Request({
url: url,
params: params,
method: 'POST',
failure: function (response, opts) {
Ext.Msg.alert('Error', response.htmlStatus);
},
success: function(response, options) {
var upid = response.result.data;
var win = Ext.create('PVE.window.TaskViewer', {
upid: upid
});
win.show();
me.close();
}
});
};
var submitBtn = Ext.create('Ext.Button', {
text: 'Restore',
handler: function(){
......@@ -64,36 +85,33 @@ Ext.define('PVE.window.Restore', {
var params = {
storage: storage,
vmid: values.vmid
vmid: me.vmid ? me.vmid : values.vmid,
force: me.vmid ? 1 : 0
};
if (me.vmtype === 'openvz') {
url = '/nodes/' + me.nodename + '/openvz';
params.ostemplate = me.volid;
params.restore = 1;
} else if (me.vmtype === 'qemu') {
url = '/nodes/' + me.nodename + '/qemu';
params.archive = me.volid;
} else {
throw 'unknown VM type';
}
PVE.Utils.API2Request({
url: url,
params: params,
method: 'POST',
failure: function (response, opts) {
Ext.Msg.alert('Error',response.htmlStatus);
},
success: function(response, options) {
var upid = response.result.data;
var win = Ext.create('PVE.window.TaskViewer', {
upid: upid
});
win.show();
me.close();
}
});
if (me.vmid) {
var msg = 'Are you sure you want to restore this VM"? ' +
'This will permanently erase current VM data.';
Ext.Msg.confirm('Confirmation', msg, function(btn) {
if (btn !== 'yes') {
return;
}
doRestore(url, params);
});
} else {
doRestore(url, params);
}
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment