254
255
return [dict(x.iteritems()) for x in instances]
257
def has_finished_migration(self, context, instance_id):
258
"""Retrieves whether or not a finished migration exists for
261
db.migration_get_by_instance_and_status(context, instance_id,
264
except exception.NotFound:
256
267
def ensure_default_security_group(self, context):
257
268
""" Create security group for the security context if it
258
269
does not already exist
374
386
rv = self.db.instance_get(context, instance_id)
375
387
return dict(rv.iteritems())
389
@scheduler_api.reroute_compute("get")
390
def routing_get(self, context, instance_id):
391
"""Use this method instead of get() if this is the only
392
operation you intend to to. It will route to novaclient.get
393
if the instance is not found."""
394
return self.get(context, instance_id)
377
396
def get_all(self, context, project_id=None, reservation_id=None,
379
398
"""Get all instances, possibly filtered by one of the
380
399
given parameters. If there is no filter and the context is
381
an admin, it will retreive all instances in the system."""
400
an admin, it will retreive all instances in the system.
382
402
if reservation_id is not None:
383
return self.db.instance_get_all_by_reservation(context,
403
return self.db.instance_get_all_by_reservation(
404
context, reservation_id)
385
406
if fixed_ip is not None:
386
407
return self.db.fixed_ip_get_instance(context, fixed_ip)
387
409
if project_id or not context.is_admin:
388
410
if not context.project:
389
return self.db.instance_get_all_by_user(context,
411
return self.db.instance_get_all_by_user(
412
context, context.user_id)
391
414
if project_id is None:
392
415
project_id = context.project_id
393
return self.db.instance_get_all_by_project(context,
417
return self.db.instance_get_all_by_project(
395
420
return self.db.instance_get_all(context)
397
422
def _cast_compute_message(self, method, context, instance_id, host=None,
442
467
:retval: A dict containing image metadata
444
data = {'name': name, 'is_public': False}
445
image_meta = self.image_service.create(context, data)
446
params = {'image_id': image_meta['id']}
469
properties = {'instance_id': str(instance_id),
470
'user_id': str(context.user_id)}
471
sent_meta = {'name': name, 'is_public': False,
472
'properties': properties}
473
recv_meta = self.image_service.create(context, sent_meta)
474
params = {'image_id': recv_meta['id']}
447
475
self._cast_compute_message('snapshot_instance', context, instance_id,
451
479
def reboot(self, context, instance_id):
452
480
"""Reboot the given instance."""
464
492
params = {'migration_id': migration_ref['id']}
465
493
self._cast_compute_message('revert_resize', context, instance_id,
466
494
migration_ref['dest_compute'], params=params)
495
self.db.migration_update(context, migration_ref['id'],
496
{'status': 'reverted'})
468
498
def confirm_resize(self, context, instance_id):
469
499
"""Confirms a migration/resize, deleting the 'old' instance in the
479
509
self._cast_compute_message('confirm_resize', context, instance_id,
480
510
migration_ref['source_compute'], params=params)
482
self.db.migration_update(context, migration_id,
512
self.db.migration_update(context, migration_ref['id'],
483
513
{'status': 'confirmed'})
484
514
self.db.instance_update(context, instance_id,
485
515
{'host': migration_ref['dest_compute'], })
487
def resize(self, context, instance_id, flavor):
517
def resize(self, context, instance_id, flavor_id):
488
518
"""Resize a running instance."""
519
instance = self.db.instance_get(context, instance_id)
520
current_instance_type = self.db.instance_type_get_by_name(
521
context, instance['instance_type'])
523
new_instance_type = self.db.instance_type_get_by_flavor_id(
525
current_instance_type_name = current_instance_type['name']
526
new_instance_type_name = new_instance_type['name']
527
LOG.debug(_("Old instance type %(current_instance_type_name)s, "
528
" new instance type %(new_instance_type_name)s") % locals())
529
if not new_instance_type:
530
raise exception.ApiError(_("Requested flavor %(flavor_id)d "
531
"does not exist") % locals())
533
current_memory_mb = current_instance_type['memory_mb']
534
new_memory_mb = new_instance_type['memory_mb']
535
if current_memory_mb > new_memory_mb:
536
raise exception.ApiError(_("Invalid flavor: cannot downsize"
538
if current_memory_mb == new_memory_mb:
539
raise exception.ApiError(_("Invalid flavor: cannot use"
540
"the same flavor. "))
489
542
self._cast_scheduler_message(context,
490
543
{"method": "prep_resize",
491
544
"args": {"topic": FLAGS.compute_topic,
492
"instance_id": instance_id, }},)
545
"instance_id": instance_id,
546
"flavor_id": flavor_id}})
548
@scheduler_api.reroute_compute("pause")
494
549
def pause(self, context, instance_id):
495
550
"""Pause the given instance."""
496
551
self._cast_compute_message('pause_instance', context, instance_id)
553
@scheduler_api.reroute_compute("unpause")
498
554
def unpause(self, context, instance_id):
499
555
"""Unpause the given instance."""
500
556
self._cast_compute_message('unpause_instance', context, instance_id)
558
@scheduler_api.reroute_compute("diagnostics")
502
559
def get_diagnostics(self, context, instance_id):
503
560
"""Retrieve diagnostics for the given instance."""
504
561
return self._call_compute_message(
510
567
"""Retrieve actions for the given instance."""
511
568
return self.db.instance_get_actions(context, instance_id)
570
@scheduler_api.reroute_compute("suspend")
513
571
def suspend(self, context, instance_id):
514
572
"""suspend the instance with instance_id"""
515
573
self._cast_compute_message('suspend_instance', context, instance_id)
575
@scheduler_api.reroute_compute("resume")
517
576
def resume(self, context, instance_id):
518
577
"""resume the instance with instance_id"""
519
578
self._cast_compute_message('resume_instance', context, instance_id)
580
@scheduler_api.reroute_compute("rescue")
521
581
def rescue(self, context, instance_id):
522
582
"""Rescue the given instance."""
523
583
self._cast_compute_message('rescue_instance', context, instance_id)
585
@scheduler_api.reroute_compute("unrescue")
525
586
def unrescue(self, context, instance_id):
526
587
"""Unrescue the given instance."""
527
588
self._cast_compute_message('unrescue_instance', context, instance_id)
548
608
return {'url': '%s/?token=%s' % (FLAGS.ajax_console_proxy_url,
549
609
output['token'])}
611
def get_vnc_console(self, context, instance_id):
612
"""Get a url to a VNC Console."""
613
instance = self.get(context, instance_id)
614
output = self._call_compute_message('get_vnc_console',
617
rpc.call(context, '%s' % FLAGS.vncproxy_topic,
618
{'method': 'authorize_vnc_console',
619
'args': {'token': output['token'],
620
'host': output['host'],
621
'port': output['port']}})
623
# hostignore and portignore are compatability params for noVNC
624
return {'url': '%s/vnc_auto.html?token=%s&host=%s&port=%s' % (
551
630
def get_console_output(self, context, instance_id):
552
631
"""Get console output for an an instance"""
553
632
return self._call_compute_message('get_console_output',
611
690
def associate_floating_ip(self, context, instance_id, address):
612
691
instance = self.get(context, instance_id)
613
self.network_api.associate_floating_ip(context, address,
614
instance['fixed_ip'])
692
self.network_api.associate_floating_ip(context,
694
fixed_ip=instance['fixed_ip'])
696
def get_instance_metadata(self, context, instance_id):
697
"""Get all metadata associated with an instance."""
698
rv = self.db.instance_metadata_get(context, instance_id)
699
return dict(rv.iteritems())
701
def delete_instance_metadata(self, context, instance_id, key):
702
"""Delete the given metadata item"""
703
self.db.instance_metadata_delete(context, instance_id, key)
705
def update_or_create_instance_metadata(self, context, instance_id,
707
"""Updates or creates instance metadata"""
708
self.db.instance_metadata_update_or_create(context, instance_id,