diff --git a/cloudcontrol/cli/commands/allocate.py b/cloudcontrol/cli/commands/allocate.py deleted file mode 100644 index 5b6d462ea95db93cc216d05898db13cad6932df5..0000000000000000000000000000000000000000 --- a/cloudcontrol/cli/commands/allocate.py +++ /dev/null @@ -1,56 +0,0 @@ -#coding=utf8 - -# This file is part of CloudControl. -# -# CloudControl is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# CloudControl is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with CloudControl. If not, see . - -""" -CloudControl server command -""" - -import json - -from cloudcontrol.cli.exception import cmdBadArgument -from cloudcontrol.cli.printer import color -from cloudcontrol.cli.command import RemoteCommand - - -class Command_allocate(RemoteCommand): - """VM allocation command""" - - def __init__(self, cli, argv0): - RemoteCommand.__init__(self, cli, argv0) - self.set_usage("%prog [options] ") - self.add_option("-t", dest="target", default="id", help="target on which to spawn VMs") - - def __call__(self, argv): - self.parse_args(argv) - if len(self.args) != 1: - raise cmdBadArgument() - - # Load vmspec - try: - vmspec = json.load(open(self.args[0])) - except IOError as err: - self.printer.error("Unable to load vmspec: %s" % err.args[1]) - else: - job_id = self.rpc.call("allocate", vmspec, self.options.target) - - self.printer.out("\n%sA job doing this allocation has been started.%s" % (color["light"], color["reset"])) - self.printer.out("%sWatch it%s: watch list id:%s$duration$state$status$title" % (color["light"], color["reset"], job_id)) - self.printer.out("%sGet logs:%s attachment id:%s logs" % (color["light"], color["reset"], job_id)) - self.printer.out("%sGet results:%s attachment id:%s results\n" % (color["light"], color["reset"], job_id)) - - def remote_functions(self): - return set(("allocate",)) diff --git a/cloudcontrol/cli/commands/migrate.py b/cloudcontrol/cli/commands/migrate.py deleted file mode 100644 index 2baa64c49b49ae1aa7ea33aebefff1a9a4629087..0000000000000000000000000000000000000000 --- a/cloudcontrol/cli/commands/migrate.py +++ /dev/null @@ -1,126 +0,0 @@ -#coding=utf8 - -# This file is part of CloudControl. -# -# CloudControl is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# CloudControl is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with CloudControl. If not, see . - -''' -CloudControl migrate command -''' - -from cloudcontrol.cli.exception import * -from sjrpc.core.exceptions import * -from cloudcontrol.cli.printer import Printer, color -from cloudcontrol.cli.command import TqlCommand - -class Command_migrate(TqlCommand): - '''Migrate vm''' - - def __init__(self, cli, argv0): - TqlCommand.__init__(self, cli, argv0) - self.set_usage("%prog [options] ") - self.remove_option("--direct") - self.remove_option("--raw") - self.remove_option("--print-tql") - self.add_option("-l", "--list", action="store_true", dest="list", default=False, - help="List migration types and algo") - self.add_option("-t", "--type", action="store", dest="type", default="", - help="Selection migration type") - self.add_option("-a", "--algo", action="store", dest="algo", default="", - help="Select migration algorithm") - - def __call__(self, argv): - # Parse argline - self.parse_args(argv) - # Retrieve election types - self.etypes = self.get_electiontypes() - # Check args and do listings - if self.options.list: - self.list() - return - elif self.options.type not in self.etypes: - raise cmdBadArgument("No such type: %s"%self.options.type) - elif self.options.algo not in self.etypes[self.options.type]: - raise cmdBadArgument("No such algo: %s for type: %s"%(self.options.algo, self.options.type)) - elif len(self.args) != 2: - raise cmdBadArgument() - stql = self.args[0] - dtql = self.args[1] - # election(query_vm, query_dest, mtype='cold', algo='fair', **kwargs) - scrutin = self.rpccall("election", stql, dtql, - mtype=self.options.type, - algo=self.options.algo, - _direct=True, _status=False) - # check election result - if len(scrutin) == 0: - raise cmdError("No migration plan found") - # print election - for (i,o) in enumerate(scrutin): - if self.options.index: - self.printer.out("[%d] "%i, nl="") - self.printer.out("%s%s %s-> %s%s%s (%s)"%( - self.tdc("id"), - o["sid"], - color["reset"], - self.tdc("id"), - o["did"], - color["reset"], - o["type"])) - # ask confirmation - if self.printer.ask("Do you confirm election? (Yes baby) ") != "Yes baby": - raise cmdWarning("User resign") - # run migration - self.rpccall("migrate", scrutin, _direct=True) - - def remote_functions(self): - return set(("migrate", "electiontypes", "election")) - - def get_electiontypes(self): - '''Return a list of migration type''' - try: - return self.cli.rpc.call("electiontypes") - except RpcError as e: - raise cmdError(e) - - def list(self): - '''Print a list of migration type''' - for t in self.etypes.keys(): - self.printer.out("migrate -t %s -a %s"%(t, ",".join(self.etypes[t]))) - - -class Command_migrate2(TqlCommand): - '''New generation VM migration.''' - - def __init__(self, cli, argv0): - TqlCommand.__init__(self, cli, argv0) - self.set_usage("%prog [options] ") - self.add_option("-l", "--live", action="store_true", default=False, - help="Do a live migration") - self.add_option("-b", "--batch", help="Name of this batch") - self.add_option("-f", "--flag", action="append", - help="Migration or allocation flags") - - def __call__(self, argv): - self.parse_args(argv) - if self.options.live: - self.tql_filter += "&r=vm&status=running" - else: - self.tql_filter += "&r=vm&status=stopped" - if len(self.args) != 2: - raise cmdBadArgument() - self.rpccall("migrate2", self.args[0], self.args[1], - live=self.options.live, flags=self.options.flag) - - def remote_functions(self): - return set(("migrate2",)) diff --git a/cloudcontrol/cli/commands/vm.py b/cloudcontrol/cli/commands/vm.py index 23289fa4bc3ffbb903d64cb0a437b5eced976735..b440dd6fc7d46cd5a82472338b86f2d8add7da1c 100644 --- a/cloudcontrol/cli/commands/vm.py +++ b/cloudcontrol/cli/commands/vm.py @@ -22,10 +22,40 @@ CloudControl VM related commands from cloudcontrol.cli.exception import * from sjrpc.core.exceptions import * from cloudcontrol.cli.printer import Printer, color -from cloudcontrol.cli.command import TqlCommand +from cloudcontrol.cli.command import RemoteCommand, TqlCommand + +import json + + +class Command_allocate(RemoteCommand): + """Create VMs""" + + def __init__(self, cli, argv0): + RemoteCommand.__init__(self, cli, argv0) + self.set_usage("%prog [options] ") + self.add_option("-t", dest="target", default="id", + help="target on which to spawn VMs") + + def __call__(self, argv): + self.parse_args(argv) + if len(self.args) != 1: + raise cmdBadArgument() + try: + allocation_plan = json.load(open(self.args[0])) + except IOError as err: + raise cmdError("Unable to load allocation plan: %s" % err) + job_id = self.rpc.call("allocate", allocation_plan, self.options.target) + self.printer.out("\n%sA job doing this allocation has been started.%s" % (color["light"], color["reset"])) + self.printer.out("%sWatch it%s: watch list id:%s$duration$state$status$title" % (color["light"], color["reset"], job_id)) + self.printer.out("%sGet logs:%s attachment id:%s logs" % (color["light"], color["reset"], job_id)) + self.printer.out("%sGet results:%s attachment id:%s results\n" % (color["light"], color["reset"], job_id)) + + def remote_functions(self): + return set(("allocate",)) + class Command_start(TqlCommand): - '''Start a stopped vm''' + '''Start stopped VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -46,7 +76,7 @@ class Command_start(TqlCommand): class Command_stop(TqlCommand): - '''Stop a running vm''' + '''Stop running VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -65,7 +95,7 @@ class Command_stop(TqlCommand): class Command_destroy(TqlCommand): - '''Force a vm to stop''' + '''Force VMs to stop''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -84,7 +114,7 @@ class Command_destroy(TqlCommand): class Command_pause(TqlCommand): - '''Pause a running vm''' + '''Pause running VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -103,7 +133,7 @@ class Command_pause(TqlCommand): class Command_resume(TqlCommand): - '''Resume a paused vm''' + '''Resume paused VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -121,7 +151,7 @@ class Command_resume(TqlCommand): return set(("resume",)) class Command_reset(TqlCommand): - '''Reset a running vm''' + '''Reset running VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -139,7 +169,7 @@ class Command_reset(TqlCommand): return set(("reset",)) class Command_cycle(TqlCommand): - '''Destroy and start a running vm''' + '''Destroy and start again running VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -197,7 +227,7 @@ class Command_autostart(TqlCommand): return set(("autostart",)) class Command_undefine(TqlCommand): - '''Undefine a stopped vm''' + '''Remove stopped VMs''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -217,7 +247,7 @@ class Command_undefine(TqlCommand): return set(("undefine",)) class Command_clone(TqlCommand): - '''Clone vm''' + '''Clone a VM''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -266,7 +296,7 @@ class Command_clone(TqlCommand): return set(("clone",)) class Command_rescue(TqlCommand): - '''Switch a vm to rescue mode''' + '''Switch VMs to rescue mode''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -284,7 +314,7 @@ class Command_rescue(TqlCommand): return set(("rescue",)) class Command_unrescue(TqlCommand): - '''Switch a vm back from rescue mode''' + '''Switch VMs back from rescue mode''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -302,7 +332,7 @@ class Command_unrescue(TqlCommand): return set(("unrescue",)) class Command_title(TqlCommand): - '''Set a vm title''' + '''Set a VM title''' def __init__(self, cli, argv0): TqlCommand.__init__(self, cli, argv0) @@ -320,3 +350,104 @@ class Command_title(TqlCommand): def remote_functions(self): return set(("title",)) + +class Command_migrate(TqlCommand): + '''Migrate VMs''' + + def __init__(self, cli, argv0): + TqlCommand.__init__(self, cli, argv0) + self.set_usage("%prog [options] ") + self.remove_option("--direct") + self.remove_option("--raw") + self.remove_option("--print-tql") + self.add_option("-l", "--list", action="store_true", dest="list", default=False, + help="List migration types and algo") + self.add_option("-t", "--type", action="store", dest="type", default="", + help="Selection migration type") + self.add_option("-a", "--algo", action="store", dest="algo", default="", + help="Select migration algorithm") + + def __call__(self, argv): + # Parse argline + self.parse_args(argv) + # Retrieve election types + self.etypes = self.get_electiontypes() + # Check args and do listings + if self.options.list: + self.list() + return + elif self.options.type not in self.etypes: + raise cmdBadArgument("No such type: %s"%self.options.type) + elif self.options.algo not in self.etypes[self.options.type]: + raise cmdBadArgument("No such algo: %s for type: %s"%(self.options.algo, self.options.type)) + elif len(self.args) != 2: + raise cmdBadArgument() + stql = self.args[0] + dtql = self.args[1] + # election(query_vm, query_dest, mtype='cold', algo='fair', **kwargs) + scrutin = self.rpccall("election", stql, dtql, + mtype=self.options.type, + algo=self.options.algo, + _direct=True, _status=False) + # check election result + if len(scrutin) == 0: + raise cmdError("No migration plan found") + # print election + for (i,o) in enumerate(scrutin): + if self.options.index: + self.printer.out("[%d] "%i, nl="") + self.printer.out("%s%s %s-> %s%s%s (%s)"%( + self.tdc("id"), + o["sid"], + color["reset"], + self.tdc("id"), + o["did"], + color["reset"], + o["type"])) + # ask confirmation + if self.printer.ask("Do you confirm election? (Yes baby) ") != "Yes baby": + raise cmdWarning("User resign") + # run migration + self.rpccall("migrate", scrutin, _direct=True) + + def remote_functions(self): + return set(("migrate", "electiontypes", "election")) + + def get_electiontypes(self): + '''Return a list of migration type''' + try: + return self.cli.rpc.call("electiontypes") + except RpcError as e: + raise cmdError(e) + + def list(self): + '''Print a list of migration type''' + for t in self.etypes.keys(): + self.printer.out("migrate -t %s -a %s"%(t, ",".join(self.etypes[t]))) + + +class Command_migrate2(TqlCommand): + '''Migrate VMs, version 2''' + + def __init__(self, cli, argv0): + TqlCommand.__init__(self, cli, argv0) + self.set_usage("%prog [options] ") + self.add_option("-l", "--live", action="store_true", default=False, + help="Do a live migration") + self.add_option("-b", "--batch", help="Name of this batch") + self.add_option("-f", "--flag", action="append", + help="Migration or allocation flags") + + def __call__(self, argv): + self.parse_args(argv) + if self.options.live: + self.tql_filter += "&r=vm&status=running" + else: + self.tql_filter += "&r=vm&status=stopped" + if len(self.args) != 2: + raise cmdBadArgument() + self.rpccall("migrate2", self.args[0], self.args[1], + live=self.options.live, flags=self.options.flag) + + def remote_functions(self): + return set(("migrate2",))