~ubuntu-branches/ubuntu/quantal/virtinst/quantal-proposed

« back to all changes in this revision

Viewing changes to virtinst/CloneManager.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2011-02-01 15:40:11 UTC
  • mfrom: (1.3.16 experimental)
  • Revision ID: james.westby@ubuntu.com-20110201154011-op0nusgc240xajvb
Tags: 0.500.5-1ubuntu1
* Merge from debian experimental. Remaining changes:
  - debian/patches/9001_Ubuntu.patch:
     + Updated to add maverick and natty to OS list and enable virtio
       for them.
  - debian/patches/9003-fix-path-to-hvmloader-in-testsuite.patch: adjust
    testsuite for 0001-fix-path-to-hvmloader.patch and
    0002-Fix-path-to-pygrub.patch. (refreshed)
  - debian/control: added acl package to depends.
  - Demote virt-viewer to Suggests, as it's in universe.
  - Recommends libvirt-bin
* Removed patches:
  - debian/patches/9002-libvirt_disk_format.patch: Upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
import logging
36
36
import re
 
37
import os
37
38
 
38
39
import libxml2
39
40
import urlgrabber.progress as progress
55
56
    else:
56
57
        return False, [val]
57
58
 
58
 
def generate_clone_disk_path(origpath, design):
59
 
    basename = origpath
 
59
def generate_clone_disk_path(origpath, design, newname=None):
 
60
    origname = design.original_guest
 
61
    newname = newname or design.clone_name
 
62
    path = origpath
60
63
    suffix = ""
61
64
 
62
65
    # Try to split the suffix off the existing disk name. Ex.
65
68
    # If the suffix is greater than 7 characters, assume it isn't
66
69
    # a file extension and is part of the disk name, at which point
67
70
    # just stick '-clone' on the end.
68
 
    if basename.count(".") and len(basename.rsplit(".", 1)[1]) <= 7:
69
 
        basename, suffix = basename.rsplit(".", 1)
 
71
    if origpath.count(".") and len(origpath.rsplit(".", 1)[1]) <= 7:
 
72
        path, suffix = origpath.rsplit(".", 1)
70
73
        suffix = "." + suffix
71
74
 
72
 
    return _util.generate_name(basename + "-clone",
73
 
                               lambda p: VirtualDisk.path_exists(design.original_conn, p),
74
 
                               suffix,
75
 
                               lib_collision=False)
 
75
    dirname = os.path.dirname(path)
 
76
    basename = os.path.basename(path)
 
77
 
 
78
    clonebase = basename + "-clone"
 
79
    if origname and basename == origname:
 
80
        clonebase = newname
 
81
 
 
82
    clonebase = os.path.join(dirname, clonebase)
 
83
    return _util.generate_name(
 
84
                    clonebase,
 
85
                    lambda p: VirtualDisk.path_exists(design.original_conn, p),
 
86
                    suffix,
 
87
                    lib_collision=False)
76
88
 
77
89
def generate_clone_name(design):
78
90
    # If the orig name is "foo-clone", we don't want the clone to be
119
131
        self._clone_name         = None
120
132
        self._clone_devices      = []
121
133
        self._clone_virtual_disks = []
122
 
        self._clone_bs           = 1024*1024*10
 
134
        self._clone_bs           = 1024 * 1024 * 10
123
135
        self._clone_mac          = []
124
136
        self._clone_uuid         = None
125
137
        self._clone_sparse       = True
128
140
        self._force_target       = []
129
141
        self._skip_target        = []
130
142
        self._preserve           = True
 
143
        self._clone_running      = False
131
144
 
132
145
        # Default clone policy for back compat: don't clone readonly,
133
146
        # shareable, or empty disks
174
187
        try:
175
188
            self._valid_guest.set_name(name)
176
189
        except ValueError, e:
177
 
            raise ValueError, _("Invalid name for new guest: %s") % (str(e),)
 
190
            raise ValueError(_("Invalid name for new guest: %s") % e)
178
191
 
179
192
        # Make sure new VM name isn't taken.
180
193
        try:
192
205
        try:
193
206
            self._valid_guest.set_uuid(uuid)
194
207
        except ValueError, e:
195
 
            raise ValueError, _("Invalid uuid for new guest: %s") % (str(e),)
 
208
            raise ValueError(_("Invalid uuid for new guest: %s") % e)
196
209
 
197
210
        if _util.vm_uuid_collision(self._hyper_conn, uuid):
198
211
            raise ValueError(_("UUID '%s' is in use by another guest.") %
368
381
                            doc="List of policy rules for determining which "
369
382
                                "vm disks to clone. See CLONE_POLICY_*")
370
383
 
 
384
    def get_clone_running(self):
 
385
        return self._clone_running
 
386
    def set_clone_running(self, val):
 
387
        self._clone_running = bool(val)
 
388
    clone_running = property(get_clone_running, set_clone_running,
 
389
                             doc="Allow cloning a running VM. If enabled, "
 
390
                                 "domain state is not checked before "
 
391
                                 "cloning.")
 
392
 
371
393
    # Functional methods
372
394
 
373
395
    def setup_original(self):
390
412
        logging.debug("Original sizes: %s" % (self.original_devices_size))
391
413
 
392
414
        # If domain has devices to clone, it must be 'off' or 'paused'
393
 
        if self._original_dom and len(self.original_devices) != 0:
 
415
        if (not self.clone_running and
 
416
            (self._original_dom and len(self.original_devices) != 0)):
394
417
            status = self._original_dom.info()[0]
395
418
 
396
419
            if status not in [libvirt.VIR_DOMAIN_SHUTOFF,
397
420
                              libvirt.VIR_DOMAIN_PAUSED]:
398
 
                raise RuntimeError, _("Domain with devices to clone must be "
399
 
                                      "paused or shutoff.")
 
421
                raise RuntimeError(_("Domain with devices to clone must be "
 
422
                                     "paused or shutoff."))
400
423
 
401
424
 
402
425
    def setup_clone(self):
426
449
 
427
450
        # changing mac
428
451
        count = ctx.xpathEval("count(/domain/devices/interface/mac)")
429
 
        for i in range(1, int(count+1)):
 
452
        for i in range(1, int(count + 1)):
430
453
            base_xpath = "/domain/devices/interface[%d]" % i
431
454
            base_node = ctx.xpathEval(base_xpath)[0]
432
455
            node = ctx.xpathEval(base_xpath + "/mac/@address")
439
462
 
440
463
            mac = None
441
464
            try:
442
 
                mac = self._clone_mac[i-1]
 
465
                mac = self._clone_mac[i - 1]
443
466
            except Exception:
444
467
                while 1:
445
468
                    mac = _util.randomMAC(typ)
452
475
            node.setContent(mac)
453
476
 
454
477
        if len(self.clone_virtual_disks) < len(self.original_virtual_disks):
455
 
            raise ValueError(_("More disks to clone that new paths specified. "
 
478
            raise ValueError(_("More disks to clone than new paths specified. "
456
479
                               "(%(passed)d specified, %(need)d needed") %
457
480
                               {"passed" : len(self.clone_virtual_disks),
458
481
                                "need"   : len(self.original_virtual_disks) })
561
584
        lst     = []
562
585
 
563
586
        count = _util.get_xml_path(xml, "count(/domain/devices/disk)")
564
 
        for i in range(1, int(count+1)):
 
587
        for i in range(1, int(count + 1)):
565
588
            # Check if the disk needs cloning
566
589
            (path, target) = self._do_we_clone_device(xml, i)
567
590
            if target == None:
680
703
 
681
704
        # VirtualDisk.setup handles everything
682
705
        dst_dev.setup(meter)
683