diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py index 99a00cec404b56bbec5436927c3778039b421eba..ecf82c78900a2bd61506d56af37a30f4e5da780d 100644 --- a/lib/rapi/connector.py +++ b/lib/rapi/connector.py @@ -142,5 +142,9 @@ CONNECTOR.update({ re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags, re.compile(r'^/2/instances/([\w\._-]+)/reboot$'): rlib2.R_2_instances_name_reboot, + re.compile(r'^/2/instances/([\w\._-]+)/shutdown$'): + rlib2.R_2_instances_name_shutdown, + re.compile(r'^/2/instances/([\w\._-]+)/startup$'): + rlib2.R_2_instances_name_startup, re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): rlib2.R_2_jobs_id, }) diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py index 1556cfbf98b0ec0c0e905d90e6514ffb50f500e8..1484c2b14c47435d862930fdaaa6216bb0b4bc18 100644 --- a/lib/rapi/rlib2.py +++ b/lib/rapi/rlib2.py @@ -257,11 +257,15 @@ class R_2_instances_name_reboot(baserlib.R_Generic): def GET(self): """Reboot an instance. + The URI takes type=[hard|soft|full] and + ignore_secondaries=[False|True] parameters. + """ instance_name = self.items[0] - reboot_type = self.queryargs.get('reboot_type', - constants.INSTANCE_REBOOT_HARD) - ignore_secondaries = self.queryargs.get('ignore_secondaries', False) + reboot_type = self.queryargs.get('type', + [constants.INSTANCE_REBOOT_HARD])[0] + ignore_secondaries = bool(self.queryargs.get('ignore_secondaries', + [False])[0]) op = ganeti.opcodes.OpRebootInstance( instance_name=instance_name, reboot_type=reboot_type, @@ -272,6 +276,53 @@ class R_2_instances_name_reboot(baserlib.R_Generic): return job_id +class R_2_instances_name_startup(baserlib.R_Generic): + """/2/instances/[instance_name]/startup resource. + + Implements an instance startup. + + """ + + DOC_URI = "/2/instances/[instance_name]/startup" + + def GET(self): + """Startup an instance. + + The URI takes force=[False|True] parameter to start the instance if even if + secondary disks are failing. + + """ + instance_name = self.items[0] + force_startup = bool(self.queryargs.get('force', [False])[0]) + op = ganeti.opcodes.OpStartupInstance(instance_name=instance_name, + force=force_startup) + + job_id = ganeti.cli.SendJob([op]) + + return job_id + + +class R_2_instances_name_shutdown(baserlib.R_Generic): + """/2/instances/[instance_name]/shutdown resource. + + Implements an instance shutdown. + + """ + + DOC_URI = "/2/instances/[instance_name]/shutdown" + + def GET(self): + """Shutdown an instance. + + """ + instance_name = self.items[0] + op = ganeti.opcodes.OpShutdownInstance(instance_name=instance_name) + + job_id = ganeti.cli.SendJob([op]) + + return job_id + + class R_2_instances_name_tags(baserlib.R_Generic): """/2/instances/[instance_name]/tags resource. @@ -291,7 +342,7 @@ class R_2_instances_name_tags(baserlib.R_Generic): def POST(self): """Add a set of tags to the instance. - The reqest as a list of strings should be POST to this URI. And you'll have + The request as a list of strings should be POST to this URI. And you'll have back a job id. """