86
84
{"method": "get_network_topic", "args": {'fake': 1}})
88
86
def _check_injected_file_quota(self, context, injected_files):
90
Enforce quota limits on injected files
92
Raises a QuotaError if any limit is exceeded
87
"""Enforce quota limits on injected files.
89
Raises a QuotaError if any limit is exceeded.
94
92
if injected_files is None:
111
109
key_name=None, key_data=None, security_group='default',
112
110
availability_zone=None, user_data=None, metadata=[],
113
111
injected_files=None):
114
"""Create the number of instances requested if quota and
115
other arguments check out ok."""
112
"""Create the number and type of instances requested.
114
Verifies that quota and other arguments are valid.
117
118
if not instance_type:
118
119
instance_type = instance_types.get_default_instance_type()
262
263
return [dict(x.iteritems()) for x in instances]
264
265
def has_finished_migration(self, context, instance_id):
265
"""Retrieves whether or not a finished migration exists for
266
"""Returns true if an instance has a finished migration."""
268
268
db.migration_get_by_instance_and_status(context, instance_id,
274
274
def ensure_default_security_group(self, context):
275
""" Create security group for the security context if it
276
does not already exist
275
"""Ensure that a context has a security group.
277
Creates a security group for the security context if it does not
278
280
:param context: the security context
289
291
db.security_group_create(context, values)
291
293
def trigger_security_group_rules_refresh(self, context, security_group_id):
292
"""Called when a rule is added to or removed from a security_group"""
294
"""Called when a rule is added to or removed from a security_group."""
294
296
security_group = self.db.security_group_get(context, security_group_id)
305
307
"args": {"security_group_id": security_group.id}})
307
309
def trigger_security_group_members_refresh(self, context, group_id):
308
"""Called when a security group gains a new or loses a member
310
"""Called when a security group gains a new or loses a member.
310
312
Sends an update request to each compute node for whom this is
313
316
# First, we get the security group rules that reference this group as
315
318
security_group_rules = \
363
366
@scheduler_api.reroute_compute("delete")
364
367
def delete(self, context, instance_id):
368
"""Terminate an instance."""
365
369
LOG.debug(_("Going to try to terminate %s"), instance_id)
367
371
instance = self.get(context, instance_id)
393
397
self.db.instance_destroy(context, instance_id)
395
399
def get(self, context, instance_id):
396
"""Get a single instance with the given ID."""
400
"""Get a single instance with the given instance_id."""
397
401
rv = self.db.instance_get(context, instance_id)
398
402
return dict(rv.iteritems())
400
404
@scheduler_api.reroute_compute("get")
401
405
def routing_get(self, context, instance_id):
402
"""Use this method instead of get() if this is the only
403
operation you intend to to. It will route to novaclient.get
404
if the instance is not found."""
406
"""A version of get with special routing characteristics.
408
Use this method instead of get() if this is the only operation you
409
intend to to. It will route to novaclient.get if the instance is not
405
413
return self.get(context, instance_id)
407
415
def get_all(self, context, project_id=None, reservation_id=None,
409
"""Get all instances, possibly filtered by one of the
410
given parameters. If there is no filter and the context is
411
an admin, it will retreive all instances in the system.
417
"""Get all instances filtered by one of the given parameters.
419
If there is no filter and the context is an admin, it will retreive
420
all instances in the system.
413
423
if reservation_id is not None:
414
424
return self.db.instance_get_all_by_reservation(
469
480
return rpc.call(context, queue, kwargs)
471
482
def _cast_scheduler_message(self, context, args):
472
"""Generic handler for RPC calls to the scheduler"""
483
"""Generic handler for RPC calls to the scheduler."""
473
484
rpc.cast(context, FLAGS.scheduler_topic, args)
475
486
def snapshot(self, context, instance_id, name):
476
487
"""Snapshot the given instance.
478
:retval: A dict containing image metadata
489
:returns: A dict containing image metadata
480
492
properties = {'instance_id': str(instance_id),
481
493
'user_id': str(context.user_id)}
492
504
self._cast_compute_message('reboot_instance', context, instance_id)
494
506
def revert_resize(self, context, instance_id):
495
"""Reverts a resize, deleting the 'new' instance in the process"""
507
"""Reverts a resize, deleting the 'new' instance in the process."""
496
508
context = context.elevated()
497
509
migration_ref = self.db.migration_get_by_instance_and_status(context,
498
510
instance_id, 'finished')
507
519
{'status': 'reverted'})
509
521
def confirm_resize(self, context, instance_id):
510
"""Confirms a migration/resize, deleting the 'old' instance in the
522
"""Confirms a migration/resize and deletes the 'old' instance."""
512
523
context = context.elevated()
513
524
migration_ref = self.db.migration_get_by_instance_and_status(context,
514
525
instance_id, 'finished')
568
579
@scheduler_api.reroute_compute("diagnostics")
569
580
def get_diagnostics(self, context, instance_id):
570
581
"""Retrieve diagnostics for the given instance."""
571
return self._call_compute_message(
582
return self._call_compute_message("get_diagnostics",
576
586
def get_actions(self, context, instance_id):
577
587
"""Retrieve actions for the given instance."""
580
590
@scheduler_api.reroute_compute("suspend")
581
591
def suspend(self, context, instance_id):
582
"""suspend the instance with instance_id"""
592
"""Suspend the given instance."""
583
593
self._cast_compute_message('suspend_instance', context, instance_id)
585
595
@scheduler_api.reroute_compute("resume")
586
596
def resume(self, context, instance_id):
587
"""resume the instance with instance_id"""
597
"""Resume the given instance."""
588
598
self._cast_compute_message('resume_instance', context, instance_id)
590
600
@scheduler_api.reroute_compute("rescue")
600
610
def set_admin_password(self, context, instance_id, password=None):
601
611
"""Set the root/admin password for the given instance."""
602
self._cast_compute_message('set_admin_password', context, instance_id,
612
self._cast_compute_message(
613
'set_admin_password', context, instance_id, password)
605
615
def inject_file(self, context, instance_id):
606
616
"""Write a file to the given instance."""
607
617
self._cast_compute_message('inject_file', context, instance_id)
609
619
def get_ajax_console(self, context, instance_id):
610
"""Get a url to an AJAX Console"""
620
"""Get a url to an AJAX Console."""
611
621
output = self._call_compute_message('get_ajax_console',
616
626
'args': {'token': output['token'], 'host': output['host'],
617
627
'port': output['port']}})
618
628
return {'url': '%s/?token=%s' % (FLAGS.ajax_console_proxy_url,
621
631
def get_vnc_console(self, context, instance_id):
622
632
"""Get a url to a VNC Console."""
640
650
def get_console_output(self, context, instance_id):
641
"""Get console output for an an instance"""
651
"""Get console output for an an instance."""
642
652
return self._call_compute_message('get_console_output',
646
656
def lock(self, context, instance_id):
647
"""lock the instance with instance_id"""
657
"""Lock the given instance."""
648
658
self._cast_compute_message('lock_instance', context, instance_id)
650
660
def unlock(self, context, instance_id):
651
"""unlock the instance with instance_id"""
661
"""Unlock the given instance."""
652
662
self._cast_compute_message('unlock_instance', context, instance_id)
654
664
def get_lock(self, context, instance_id):
655
"""return the boolean state of (instance with instance_id)'s lock"""
665
"""Return the boolean state of given instance's lock."""
656
666
instance = self.get(context, instance_id)
657
667
return instance['locked']
659
669
def reset_network(self, context, instance_id):
661
Reset networking on the instance.
670
"""Reset networking on the instance."""
664
671
self._cast_compute_message('reset_network', context, instance_id)
666
673
def inject_network_info(self, context, instance_id):
668
Inject network info for the instance.
674
"""Inject network info for the instance."""
671
675
self._cast_compute_message('inject_network_info', context, instance_id)
673
677
def attach_volume(self, context, instance_id, volume_id, device):
678
"""Attach an existing volume to an existing instance."""
674
679
if not re.match("^/dev/[a-z]d[a-z]+$", device):
675
680
raise exception.ApiError(_("Invalid device specified: %s. "
676
681
"Example device: /dev/vdb") % device)
685
690
"mountpoint": device}})
687
692
def detach_volume(self, context, volume_id):
693
"""Detach a volume from an instance."""
688
694
instance = self.db.volume_get_instance(context.elevated(), volume_id)
690
696
raise exception.ApiError(_("Volume isn't attached to anything!"))
700
706
def associate_floating_ip(self, context, instance_id, address):
707
"""Associate a floating ip with an instance."""
701
708
instance = self.get(context, instance_id)
702
709
self.network_api.associate_floating_ip(context,
703
710
floating_ip=address,
709
716
return dict(rv.iteritems())
711
718
def delete_instance_metadata(self, context, instance_id, key):
712
"""Delete the given metadata item"""
719
"""Delete the given metadata item from an instance."""
713
720
self.db.instance_metadata_delete(context, instance_id, key)
715
722
def update_or_create_instance_metadata(self, context, instance_id,
717
"""Updates or creates instance metadata"""
724
"""Updates or creates instance metadata."""
718
725
self.db.instance_metadata_update_or_create(context, instance_id,