]> git.proxmox.com Git - pve-manager.git/commitdiff
support more than 'local' storage for openvz.
authorDietmar Maurer <dietmar@proxmox.com>
Mon, 7 Nov 2011 11:35:38 +0000 (12:35 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Mon, 7 Nov 2011 11:35:38 +0000 (12:35 +0100)
It is now possible to use NFS or other directory type storages.

PVE/API2/OpenVZ.pm
PVE/OpenVZ.pm
www/manager/Utils.js
www/manager/form/ContentTypeSelector.js
www/manager/grid/BackupView.js
www/manager/openvz/CreateWizard.js
www/manager/window/Restore.js

index 1017845e6d70fc025f50e043668e7491697958e5..c55c501e61aa1e3e52dfd7eeebb6f4f9baeb37c3 100644 (file)
@@ -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', 
index d42cbd203cb485d15e059f54128bc1ed400f0cc5..db5791faabab0eb653997a35c559d0fbb670764e 100644 (file)
@@ -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);
index b5a83f95e1f2483fb35060e3b06da99dcc5b365f..9722d11e318553ec8e25821427a4306892e484a6 100644 (file)
@@ -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');
            }
        });
 
index 0d808b36e8d33324a95f1d634c73b45c1f144717..297754cf35ee201322c175bb4b9cef7f0f5857ad 100644 (file)
@@ -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();
     }
index 2fbd99194d8553aa4c0a5b1346d629a5e1bdbf78..27d408544e18ca95ef842b405f399bcf48a44b25 100644 (file)
@@ -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, 
index fe74ab048ca583be037a64cec03cac06b57245bc..4bcafd3134435b18bfe0f482aed8ad9d9c7b180e 100644 (file)
@@ -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',
index 481d6246c2f13bc5d29e7a078782c82215cd1c83..240c2f3b1ff8e4cdf3faedd828432e3277987557 100644 (file)
@@ -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);
+               }
            }
        });