diff options
| author | jaypipes@gmail.com <> | 2010-12-21 10:25:39 -0500 |
|---|---|---|
| committer | jaypipes@gmail.com <> | 2010-12-21 10:25:39 -0500 |
| commit | 887ee0aae54fc51124bb869af2bfee055a46d27a (patch) | |
| tree | 3554feb1fba402ad064a4ac0b154d34f998040ff /nova/compute | |
| parent | 1b4b36cec4d82009d595a601c408e2f582ef790c (diff) | |
| parent | 086f2d87be3c56ac8dafaf4551096868d57454db (diff) | |
Merge trunk and resolve conflicts
Diffstat (limited to 'nova/compute')
| -rw-r--r-- | nova/compute/api.py | 35 | ||||
| -rw-r--r-- | nova/compute/disk.py | 22 | ||||
| -rw-r--r-- | nova/compute/manager.py | 41 |
3 files changed, 89 insertions, 9 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index e701e540e..a33ed2dc4 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -73,14 +73,19 @@ class ComputeAPI(base.Base): is_vpn = image_id == FLAGS.vpn_image_id if not is_vpn: image = self.image_service.show(context, image_id) + + # If kernel_id/ramdisk_id isn't explicitly set in API call + # we take the defaults from the image's metadata if kernel_id is None: - kernel_id = image.get('kernelId', FLAGS.default_kernel) + kernel_id = image.get('kernelId', None) if ramdisk_id is None: - ramdisk_id = image.get('ramdiskId', FLAGS.default_ramdisk) + ramdisk_id = image.get('ramdiskId', None) # Make sure we have access to kernel and ramdisk - self.image_service.show(context, kernel_id) - self.image_service.show(context, ramdisk_id) + if kernel_id: + self.image_service.show(context, kernel_id) + if ramdisk_id: + self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ['default'] @@ -103,8 +108,8 @@ class ComputeAPI(base.Base): base_options = { 'reservation_id': utils.generate_uid('r'), 'image_id': image_id, - 'kernel_id': kernel_id, - 'ramdisk_id': ramdisk_id, + 'kernel_id': kernel_id or '', + 'ramdisk_id': ramdisk_id or '', 'state_description': 'scheduling', 'user_id': context.user_id, 'project_id': context.project_id, @@ -275,6 +280,24 @@ class ComputeAPI(base.Base): {"method": "reboot_instance", "args": {"instance_id": instance['id']}}) + def pause(self, context, instance_id): + """Pause the given instance.""" + instance = self.db.instance_get_by_internal_id(context, instance_id) + host = instance['host'] + rpc.cast(context, + self.db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "pause_instance", + "args": {"instance_id": instance['id']}}) + + def unpause(self, context, instance_id): + """Unpause the given instance.""" + instance = self.db.instance_get_by_internal_id(context, instance_id) + host = instance['host'] + rpc.cast(context, + self.db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "unpause_instance", + "args": {"instance_id": instance['id']}}) + def rescue(self, context, instance_id): """Rescue the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) diff --git a/nova/compute/disk.py b/nova/compute/disk.py index 4263ae117..814a258cd 100644 --- a/nova/compute/disk.py +++ b/nova/compute/disk.py @@ -106,6 +106,13 @@ def partition(infile, outfile, local_bytes=0, resize=True, % (outfile, local_type, local_first, local_last)) +def extend(image, size, execute): + file_size = os.path.getsize(image) + if file_size >= size: + return + return execute('truncate -s size %s' % (image,)) + + def inject_data(image, key=None, net=None, partition=None, execute=None): """Injects a ssh key and optionally net data into a disk image. @@ -115,7 +122,7 @@ def inject_data(image, key=None, net=None, partition=None, execute=None): If partition is not specified it mounts the image as a single partition. """ - out, err = execute('sudo losetup -f --show %s' % image) + out, err = execute('sudo losetup --find --show %s' % image) if err: raise exception.Error(_('Could not attach image to loopback: %s') % err) @@ -130,6 +137,15 @@ def inject_data(image, key=None, net=None, partition=None, execute=None): partition) else: mapped_device = device + + # We can only loopback mount raw images. If the device isn't there, + # it's normally because it's a .vmdk or a .vdi etc + if not os.path.exists(mapped_device): + raise exception.Error('Mapped device was not found (we can' + ' only inject raw disk images): %s' % + mapped_device) + + # Configure ext2fs so that it doesn't auto-check every N boots out, err = execute('sudo tune2fs -c 0 -i 0 %s' % mapped_device) tmpdir = tempfile.mkdtemp() @@ -158,7 +174,7 @@ def inject_data(image, key=None, net=None, partition=None, execute=None): execute('sudo kpartx -d %s' % device) finally: # remove loopback - execute('sudo losetup -d %s' % device) + execute('sudo losetup --detach %s' % device) def _inject_key_into_fs(key, fs, execute=None): @@ -167,7 +183,7 @@ def _inject_key_into_fs(key, fs, execute=None): key is an ssh key string. fs is the path to the base of the filesystem into which to inject the key. """ - sshdir = os.path.join(os.path.join(fs, 'root'), '.ssh') + sshdir = os.path.join(fs, 'root', '.ssh') execute('sudo mkdir -p %s' % sshdir) # existing dir doesn't matter execute('sudo chown root %s' % sshdir) execute('sudo chmod 700 %s' % sshdir) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 7d18d0eff..135663ab5 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -186,6 +186,47 @@ class ComputeManager(manager.Manager): self.driver.unrescue(instance_ref) self._update_state(context, instance_id) + @staticmethod + def _update_state_callback(self, context, instance_id, result): + """Update instance state when async task completes.""" + self._update_state(context, instance_id) + + @exception.wrap_exception + def pause_instance(self, context, instance_id): + """Pause an instance on this server.""" + context = context.elevated() + instance_ref = self.db.instance_get(context, instance_id) + + logging.debug('instance %s: pausing', + instance_ref['internal_id']) + self.db.instance_set_state(context, + instance_id, + power_state.NOSTATE, + 'pausing') + self.driver.pause(instance_ref, + lambda result: self._update_state_callback(self, + context, + instance_id, + result)) + + @exception.wrap_exception + def unpause_instance(self, context, instance_id): + """Unpause a paused instance on this server.""" + context = context.elevated() + instance_ref = self.db.instance_get(context, instance_id) + + logging.debug('instance %s: unpausing', + instance_ref['internal_id']) + self.db.instance_set_state(context, + instance_id, + power_state.NOSTATE, + 'unpausing') + self.driver.unpause(instance_ref, + lambda result: self._update_state_callback(self, + context, + instance_id, + result)) + @exception.wrap_exception def get_console_output(self, context, instance_id): """Send the console output for an instance.""" |
