def undump_instance(self): """ Take the pieces of a dump archive and put them back in place. """ # If a non-root user was used to transfer the files then we # need to move everything to where it is expected to be. LOG.debug(_('Restoring action scripts from archive: %s') % self.dumpdir_tarfile) self.untar_dumpdir() LOG.debug(_('Restoring action scripts for %s') % self.container.ovz_id) self.restore_action_scripts() if self.live_migration: LOG.debug(_('Restoring container state from dump for %s') % self.container.ovz_id) self.undump() LOG.debug(_('Resuming container: %s') % self.container.ovz_id) self.resume() else: LOG.debug(_('Restoring container from tar: %s') % self.container.ovz_id) self.untar_instance() root_dir = os.path.join(CONF.ovz_ve_root_dir, self.container.ovz_id) if os.path.exists(root_dir) is False: ovz_utils.execute('mkdir', '-p', root_dir, run_as_root=True) # ensure we can interact with the new instance via its uuid self.container.save_ovz_metadata() LOG.debug(_('Done restoring instance %s') % self.container.ovz_id)
def create(cls, image, **kwargs): """ Create an OpenVZ container with the specified arguments. """ # TODO(imsplitbit): This needs to set an os template for the image # as well as an actual OS template for OpenVZ to know what config # scripts to use. This can be problematic because there is no concept # of OS name, it is arbitrary so we will need to find a way to # correlate this to what type of disto the image actually is because # this is the clue for openvz's utility scripts. For now we will have # to set it to 'ubuntu' container = OvzContainer(ovz_id=cls.get_next_id(), **kwargs) create_cmd = ['vzctl', 'create', container.ovz_id, '--ostemplate', image] if CONF.ovz_layout: create_cmd.append('--layout') create_cmd.append(CONF.ovz_layout) ovz_utils.execute(*create_cmd, run_as_root=True) container.save_ovz_metadata() return container
def test_get_cpuunits_capability(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'vzcpucheck', run_as_root=True).AndReturn('') self.mox.ReplayAll() self.assertRaises( exception.InvalidCPUInfo, ovz_utils.get_cpuunits_capability)
def set_vz_os_hint(self, ostemplate='ubuntu'): """ This exists as a stopgap because currently there are no os hints in the image managment of nova. There are ways of hacking it in via image_properties but this requires special case code just for this driver. Run the command: vzctl set <ctid> --save --ostemplate <ostemplate> Currently ostemplate defaults to ubuntu. This facilitates setting the ostemplate setting in OpenVZ to allow the OpenVz helper scripts to setup networking, nameserver and hostnames. Because of this, the openvz driver only works with debian based distros. If this fails to run an exception is raised as this is a critical piece in making openvz run a container. """ # This sets the distro hint for OpenVZ to later use for the setting # of resolver, hostname and the like # TODO(imsplitbit): change the ostemplate default value to a flag ovz_utils.execute('vzctl', 'set', self.ovz_id, '--save', '--ostemplate', ostemplate, run_as_root=True)
def test_set_permissions(self): perms = 755 filename = '/tmp/testfile' self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute('chmod', perms, filename, run_as_root=True) self.mox.ReplayAll() ovz_utils.set_permissions(filename, perms)
def _partition_disk(self): """ Openvz requires that we pass in not only the root device but if the user is to access partitions on that disk we need also to pass in the major/minor numbers for each partition. Given that requirement we're making the assumption for now that volumes are going to be presented as one partition. This will partition the root device so we can later get the information on both the major and minor numbers. If the disk contains a valid partition table then we just return :return: """ # We need potentially need to give the device time to settle self._let_disk_settle() dev = self._find_device() part_table = self._list_partition_table() LOG.debug(_('Partition table for %(dev)s: %(part_table)s') % locals()) # If the volume is partitioned we're assuming this is a reconnect of # a volume and we won't partition anything. if not part_table: commands = ['o,w', 'n,p,1,,,t,1,83,w'] for command in commands: command = command.replace(',', '\n') ovz_utils.execute( 'fdisk', dev, process_input=command, run_as_root=True) time.sleep(3)
def prep_for_migration(self): # this only really happens in development VMs, but we can't have two # containers with the same name, so we need to rename the old one temp_name = '%s-migrated' % self.uuid ovz_utils.execute( 'vzctl', 'set', self.ovz_id, '--save', '--name', temp_name, run_as_root=True)
def quota_init(self): """ Initialize quotas for instance """ LOG.debug(_('Initializing quotas for %s') % self.instance['id']) ovz_utils.execute('vzctl', 'quotainit', self.instance['id']) LOG.debug(_('Initialized quotas for %s') % self.instance['id'])
def _delete_device(self, device): """ Utility method for deleting/removing device file :param device """ ovz_utils.execute('rm', '-f', device, run_as_root=True)
def test_delete_path_good(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'rmdir', CONF.ovz_ve_private_dir, run_as_root=True).AndReturn(('', '')) self.mox.ReplayAll() self.assertTrue(ovz_utils.delete_path(CONF.ovz_ve_private_dir))
def quota_on(self): """ Turn on quotas for instance """ LOG.debug(_('Turning on quotas for %s') % self.instance['id']) ovz_utils.execute('vzctl', 'quotaon', self.instance['id'], run_as_root=True) LOG.debug(_('Turned on quotas for %s') % self.instance['id'])
def quotaenable(self): """ enable quotas for a given container """ LOG.debug(_('Enabling quotas for %s') % self.instance['id']) ovz_utils.execute('vzquota', 'reload2', self.instance['id'], run_as_root=True) LOG.debug(_('Enabled quotas for %s') % self.instance['id'])
def quotaload(self): """ Load quotas from quota file """ LOG.debug(_('Loading quotas for %s') % self.instance['id']) ovz_utils.execute('vzdqload', self.instance['id'], '-U', '-G', '-T', '<', self.qdumpfile, run_as_root=True) LOG.debug(_('Loaded quotas for %s') % self.instance['id'])
def quotadump(self): """ Dump the quotas for containers """ LOG.debug(_('Dumping quotas for %s') % self.instance['id']) ovz_utils.execute('vzdqdump', self.instance['id'], '-U', '-G', '-T', '>', self.qdumpfile, run_as_root=True) LOG.debug(_('Dumped quotas for %s') % self.instance['id'])
def resume(self): """ Resume a container from an undumped migration """ LOG.debug(_('Resuming instance %s') % self.instance['id']) ovz_utils.execute('vzctl', 'restore', self.instance['id'], '--resume', run_as_root=True) LOG.debug(_('Resumed instance %s') % self.instance['id'])
def test_delete_path_bad(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'rmdir', CONF.ovz_ve_private_dir, run_as_root=True).AndRaise(exception.InstanceUnacceptable( fakes.ERRORMSG)) self.mox.ReplayAll() self.assertFalse(ovz_utils.delete_path(CONF.ovz_ve_private_dir))
def quotaload(self): """ Load quotas from quota file """ LOG.debug(_('Loading quotas for %s') % self.container.ovz_id) ovz_utils.execute('vzdqload', self.container.ovz_id, '-U', '-G', '-T', '<', self.qdumpfile, run_as_root=True) LOG.debug(_('Loaded quotas for %s') % self.container.ovz_id)
def test_set_perms_success(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'chmod', 755, fakes.TEMPFILE, run_as_root=True).AndReturn( ('', fakes.ERRORMSG)) self.mox.ReplayAll() fh = ovzfile.OVZFile(fakes.TEMPFILE, 755) fh.set_permissions(755)
def test_mkfs_uuid(self): fs_uuid = uuid.uuid4() path = '/dev/sdgg' self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'mkfs', '-F', '-t', 'ext3', '-U', fs_uuid, path, run_as_root=True) self.mox.ReplayAll() ovz_utils.mkfs(path, 'ext3', fs_uuid)
def test_execute_process_execution_error_no_raise_on_error(self): self.mox.StubOutWithMock(ovz_utils.utils, 'execute') ovz_utils.utils.execute( 'cat', '/proc/cpuinfo', run_as_root=False).AndRaise( processutils.ProcessExecutionError) self.mox.ReplayAll() ovz_utils.execute( 'cat', '/proc/cpuinfo', run_as_root=False, raise_on_error=False)
def test_set_perms_failure(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'chmod', 755, fakes.TEMPFILE, run_as_root=True).AndRaise( exception.InstanceUnacceptable(fakes.ERRORMSG)) self.mox.ReplayAll() fh = ovzfile.OVZFile(fakes.TEMPFILE, 755) self.assertRaises( exception.InstanceUnacceptable, fh.set_permissions, 755)
def kill(self): """ This is used to stop a container once it's suspended without having to resume it to properly destroy it """ LOG.debug(_('Killing instance %s') % self.instance['id']) ovz_utils.execute('vzctl', 'chkpnt', self.instance['id'], '--kill', run_as_root=True) LOG.debug(_('Killed instance %s') % self.instance['id'])
def test_get_fs_uuid_failure(self): dev = '/dev/sdgg' self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'blkid', '-o', 'value', '-s', 'UUID', dev, raise_on_error=False, run_as_root=True).AndReturn('\n') self.mox.ReplayAll() fs_uuid = ovz_utils.get_fs_uuid(dev) self.assertFalse(fs_uuid)
def test_get_fs_uuid_success(self): dev = '/dev/sdgg' self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'blkid', '-o', 'value', '-s', 'UUID', dev, raise_on_error=False, run_as_root=True).AndReturn(fakes.BLKID) self.mox.ReplayAll() fs_uuid = ovz_utils.get_fs_uuid(dev) self.assertEqual(fs_uuid, fakes.BLKID.strip())
def test_mkfs_label(self): path = '/dev/sdgg' fs_label = 'STORAGE' self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'mkfs', '-F', '-t', 'ext3', '-U', mox.IgnoreArg(), '-L', fs_label, path, run_as_root=True) self.mox.ReplayAll() ovz_utils.mkfs(path, 'ext3', None, fs_label)
def test_touch_file_failure(self): fh = ovzfile.OVZFile(fakes.TEMPFILE, 755) self.mox.StubOutWithMock(fh, 'make_path') fh.make_path() self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'touch', fakes.TEMPFILE, run_as_root=True).AndRaise( exception.InstanceUnacceptable(fakes.ERRORMSG)) self.mox.ReplayAll() self.assertRaises(exception.InstanceUnacceptable, fh.touch)
def test_touch_file_success(self): fh = ovzfile.OVZFile(fakes.TEMPFILE, 755) self.mox.StubOutWithMock(fh, 'make_path') fh.make_path() self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'touch', fakes.TEMPFILE, run_as_root=True).AndReturn( ('', fakes.ERRORMSG)) self.mox.ReplayAll() fh.touch()
def test_make_path_and_dir_success(self): self.mox.StubOutWithMock(ovz_utils, 'execute') ovz_utils.execute( 'mkdir', '-p', mox.IgnoreArg(), run_as_root=True).AndReturn( ('', fakes.ERRORMSG)) self.mox.StubOutWithMock(openvz_conn.os.path, 'exists') openvz_conn.os.path.exists(mox.IgnoreArg()).AndReturn(False) self.mox.ReplayAll() fh = ovzfile.OVZFile(fakes.TEMPFILE, 755) fh.make_path()
def set_numfiles(self, max_file_descriptors): """ Run the command: vzctl set <ctid> --save --numfile <number> """ ovz_utils.execute('vzctl', 'set', self.ovz_id, '--save', '--numfile', max_file_descriptors, run_as_root=True)
def undump(self): """ Restore a VZ from a dump file """ LOG.debug(_('Undumping instance %s') % self.instance['id']) ovz_utils.execute('vzctl', 'restore', self.instance['id'], '--undump', '--dumpfile', self.dumpfile, '--skip_arpdetect', run_as_root=True) LOG.debug(_('Undumped instance %(instance_id)s from %(dumpfile)s') % {'instance_id': self.instance['id'], 'dumpfile': self.dumpfile})