Revision ac6a221f
b/snf-cyclades-app/synnefo/logic/reconciliation.py | ||
---|---|---|
479 | 479 |
return nics |
480 | 480 |
|
481 | 481 |
|
482 |
def disks_from_instance(i): |
|
483 |
sizes = zip(itertools.repeat('size'), i['disk.sizes']) |
|
484 |
names = zip(itertools.repeat('name'), i['disk.names']) |
|
485 |
uuids = zip(itertools.repeat('uuid'), i['disk.uuids']) |
|
486 |
disks = zip(sizes, names, uuids) |
|
487 |
disks = map(lambda x: dict(x), disks) |
|
488 |
#disks = dict(enumerate(disks)) |
|
489 |
return disks |
|
490 |
|
|
491 |
|
|
482 | 492 |
def get_ganeti_jobs(backend): |
483 | 493 |
gnt_jobs = backend_mod.get_jobs(backend) |
484 | 494 |
return dict([(int(j["id"]), j) for j in gnt_jobs]) |
485 | 495 |
|
486 | 496 |
|
487 |
def disks_from_instance(i): |
|
488 |
return dict([(index, {"size": size}) |
|
489 |
for index, size in enumerate(i["disk.sizes"])]) |
|
490 |
|
|
491 |
|
|
492 | 497 |
class NetworkReconciler(object): |
493 | 498 |
def __init__(self, logger, fix=False): |
494 | 499 |
self.log = logger |
b/snf-cyclades-app/synnefo/management/common.py | ||
---|---|---|
35 | 35 |
from synnefo.db.models import (Backend, VirtualMachine, Network, |
36 | 36 |
Flavor, IPAddress, Subnet, |
37 | 37 |
BridgePoolTable, MacPrefixPoolTable, |
38 |
NetworkInterface, IPAddressLog) |
|
38 |
NetworkInterface, IPAddressLog, Volume)
|
|
39 | 39 |
from functools import wraps |
40 | 40 |
|
41 | 41 |
from snf_django.lib.api import faults |
... | ... | |
177 | 177 |
objs = objs.select_for_update() |
178 | 178 |
return objs.get(id=flavor_id) |
179 | 179 |
except ValueError: |
180 |
raise CommandError("Invalid flavor ID: %s", flavor_id)
|
|
180 |
raise CommandError("Invalid flavor ID: %s" % flavor_id)
|
|
181 | 181 |
except Flavor.DoesNotExist: |
182 | 182 |
raise CommandError("Flavor with ID %s not found in DB." |
183 | 183 |
" Use snf-manage flavor-list to find out" |
... | ... | |
218 | 218 |
raise CommandError("Floating IP %s does not exist." % floating_ip_id) |
219 | 219 |
|
220 | 220 |
|
221 |
def get_volume(volume_id, for_update=False): |
|
222 |
try: |
|
223 |
volume_id = int(volume_id) |
|
224 |
objs = Volume.objects |
|
225 |
if for_update: |
|
226 |
objs = objs.select_for_update() |
|
227 |
return objs.get(id=volume_id) |
|
228 |
except ValueError: |
|
229 |
raise CommandError("Invalid volume ID: %s" % volume_id) |
|
230 |
except Volume.DoesNotExist: |
|
231 |
raise CommandError("Volume with ID %s not found in DB." |
|
232 |
" Use snf-manage volume-list to find out" |
|
233 |
" available volume IDs." % volume_id) |
|
234 |
|
|
235 |
|
|
221 | 236 |
def check_backend_credentials(clustername, port, username, password): |
222 | 237 |
try: |
223 | 238 |
client = GanetiRapiClient(clustername, port, username, password) |
b/snf-cyclades-app/synnefo/management/pprint.py | ||
---|---|---|
41 | 41 |
from synnefo.db.pools import bitarray_to_map |
42 | 42 |
|
43 | 43 |
from synnefo.logic.rapi import GanetiApiError |
44 |
from synnefo.logic.reconciliation import nics_from_instance |
|
44 |
from synnefo.logic.reconciliation import (nics_from_instance, |
|
45 |
disks_from_instance) |
|
45 | 46 |
from synnefo.management.common import get_image |
46 | 47 |
|
47 | 48 |
|
... | ... | |
259 | 260 |
return |
260 | 261 |
raise e |
261 | 262 |
|
262 |
nics = nics_from_instance(vm_info)
|
|
263 |
disks = disks_from_instance(vm_info)
|
|
263 | 264 |
try: |
264 |
gnt_nic = filter(lambda nic: nic.get("name") == port.backend_uuid,
|
|
265 |
nics)[0]
|
|
266 |
gnt_nic["instance"] = vm_info["name"]
|
|
265 |
gnt_disk = filter(lambda disk: disk.get("name") == port.backend_uuid,
|
|
266 |
disks)[0]
|
|
267 |
gnt_disk["instance"] = vm_info["name"]
|
|
267 | 268 |
except IndexError: |
268 | 269 |
stdout.write("Port %s is not attached to instance %s\n" % |
269 | 270 |
(port.id, vm.id)) |
270 | 271 |
return |
271 |
pprint_table(stdout, gnt_nic.items(), None, separator=" | ",
|
|
272 |
pprint_table(stdout, gnt_disk.items(), None, separator=" | ",
|
|
272 | 273 |
title=title) |
273 | 274 |
|
274 | 275 |
vm.put_client(client) |
... | ... | |
382 | 383 |
separator=" | ", |
383 | 384 |
title="Ganeti Job %s" % server_job["id"]) |
384 | 385 |
server.put_client(client) |
386 |
|
|
387 |
|
|
388 |
def pprint_volume(volume, display_mails=False, stdout=None, title=None): |
|
389 |
if stdout is None: |
|
390 |
stdout = sys.stdout |
|
391 |
if title is None: |
|
392 |
title = "State of volume %s in DB" % volume.id |
|
393 |
|
|
394 |
ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN) |
|
395 |
userid = volume.userid |
|
396 |
|
|
397 |
volume_dict = OrderedDict([ |
|
398 |
("id", volume.id), |
|
399 |
("size", volume.size), |
|
400 |
("disk_template", volume.disk_template), |
|
401 |
("disk_provider", volume.disk_provider), |
|
402 |
("server_id", volume.machine_id), |
|
403 |
("userid", volume.userid), |
|
404 |
("username", ucache.get_name(userid) if display_mails else None), |
|
405 |
("name", volume.name), |
|
406 |
("state", volume.status), |
|
407 |
("deleted", volume.deleted), |
|
408 |
("backendjobid", volume.backendjobid), |
|
409 |
]) |
|
410 |
|
|
411 |
pprint_table(stdout, volume_dict.items(), None, separator=" | ", |
|
412 |
title=title) |
|
413 |
|
|
414 |
|
|
415 |
def pprint_volume_in_ganeti(volume, stdout=None, title=None): |
|
416 |
if stdout is None: |
|
417 |
stdout = sys.stdout |
|
418 |
if title is None: |
|
419 |
title = "State of volume %s in Ganeti" % volume.id |
|
420 |
|
|
421 |
vm = volume.machine |
|
422 |
if vm is None: |
|
423 |
stdout.write("volume is not attached to any instance.\n") |
|
424 |
return |
|
425 |
|
|
426 |
client = vm.get_client() |
|
427 |
try: |
|
428 |
vm_info = client.GetInstance(vm.backend_vm_id) |
|
429 |
except GanetiApiError as e: |
|
430 |
if e.code == 404: |
|
431 |
stdout.write("Volume seems attached to server %s, but" |
|
432 |
" server does not exist in backend.\n" |
|
433 |
% vm) |
|
434 |
return |
|
435 |
raise e |
|
436 |
|
|
437 |
disks = disks_from_instance(vm_info) |
|
438 |
try: |
|
439 |
gnt_disk = filter(lambda disk: |
|
440 |
disk.get("name") == volume.backend_volume_uuid, |
|
441 |
disks)[0] |
|
442 |
gnt_disk["instance"] = vm_info["name"] |
|
443 |
except IndexError: |
|
444 |
stdout.write("Volume %s is not attached to instance %s\n" % (volume.id, |
|
445 |
vm.id)) |
|
446 |
return |
|
447 |
pprint_table(stdout, gnt_disk.items(), None, separator=" | ", |
|
448 |
title=title) |
|
449 |
|
|
450 |
vm.put_client(client) |
b/snf-cyclades-app/synnefo/volume/management/commands/snapshot-create.py | ||
---|---|---|
1 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from optparse import make_option |
|
35 |
|
|
36 |
from django.core.management.base import BaseCommand, CommandError |
|
37 |
from synnefo.management import common |
|
38 |
#from snf_django.management.utils import parse_bool |
|
39 |
from synnefo.volume import snapshots |
|
40 |
|
|
41 |
|
|
42 |
class Command(BaseCommand): |
|
43 |
args = "<volume ID>" |
|
44 |
help = "Create a snapshot from the specified volume" |
|
45 |
|
|
46 |
option_list = BaseCommand.option_list + ( |
|
47 |
make_option( |
|
48 |
'--wait', |
|
49 |
dest='wait', |
|
50 |
default="True", |
|
51 |
choices=["True", "False"], |
|
52 |
metavar="True|False", |
|
53 |
help="Wait for Ganeti job to complete."), |
|
54 |
make_option( |
|
55 |
"--name", |
|
56 |
dest="name", |
|
57 |
default=None, |
|
58 |
help="Display name of the snapshot"), |
|
59 |
make_option( |
|
60 |
"--description", |
|
61 |
dest="description", |
|
62 |
default=None, |
|
63 |
help="Display description of the snapshot"), |
|
64 |
) |
|
65 |
|
|
66 |
@common.convert_api_faults |
|
67 |
def handle(self, *args, **options): |
|
68 |
if len(args) != 1: |
|
69 |
raise CommandError("Please provide a volume ID") |
|
70 |
|
|
71 |
volume = common.get_volume(args[0]) |
|
72 |
|
|
73 |
name = options.get("name") |
|
74 |
if name is None: |
|
75 |
raise CommandError("'name' option is required") |
|
76 |
|
|
77 |
description = options.get("description") |
|
78 |
if description is None: |
|
79 |
description = "Snapshot of Volume '%s" % volume.id |
|
80 |
|
|
81 |
snapshot = snapshots.create(volume.userid, |
|
82 |
volume, |
|
83 |
name=name, |
|
84 |
description=description, |
|
85 |
metadata={}) |
|
86 |
|
|
87 |
msg = ("Created snapshot of volume '%s' with ID %s\n" |
|
88 |
% (volume.id, snapshot["uuid"])) |
|
89 |
self.stdout.write(msg) |
b/snf-cyclades-app/synnefo/volume/management/commands/snapshot-list.py | ||
---|---|---|
1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or without |
|
4 |
# modification, are permitted provided that the following conditions |
|
5 |
# are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above copyright |
|
8 |
# notice, this list of conditions and the following disclaimer. |
|
9 |
# |
|
10 |
# 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
# notice, this list of conditions and the following disclaimer in the |
|
12 |
# documentation and/or other materials provided with the distribution. |
|
13 |
# |
|
14 |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
15 |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
16 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
17 |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
18 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
19 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
20 |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
21 |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
22 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
23 |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
24 |
# SUCH DAMAGE. |
|
25 |
# |
|
26 |
# The views and conclusions contained in the software and documentation are |
|
27 |
# those of the authors and should not be interpreted as representing official |
|
28 |
# policies, either expressed or implied, of GRNET S.A. |
|
29 |
# |
|
30 |
|
|
31 |
from django.core.management.base import BaseCommand |
|
32 |
from optparse import make_option |
|
33 |
|
|
34 |
from snf_django.management.utils import pprint_table |
|
35 |
from synnefo.plankton.utils import image_backend |
|
36 |
|
|
37 |
|
|
38 |
class Command(BaseCommand): |
|
39 |
help = "List public snapshots or snapshots available to a user." |
|
40 |
option_list = BaseCommand.option_list + ( |
|
41 |
make_option( |
|
42 |
'--user-id', |
|
43 |
dest='userid', |
|
44 |
default=None, |
|
45 |
help="List all snapshots available to that user." |
|
46 |
" If no user is specified, only public snapshots" |
|
47 |
" are displayed."), |
|
48 |
) |
|
49 |
|
|
50 |
def handle(self, **options): |
|
51 |
user = options['userid'] |
|
52 |
|
|
53 |
with image_backend(user) as backend: |
|
54 |
snapshots = backend.list_snapshots(user) |
|
55 |
|
|
56 |
headers = ("id", "name", "volume_id", "size", "map") |
|
57 |
table = [] |
|
58 |
for snap in snapshots: |
|
59 |
fields = (snap["uuid"], snap["name"], snap["volume_id"], |
|
60 |
snap["size"], snap["map"]) |
|
61 |
table.append(fields) |
|
62 |
pprint_table(self.stdout, table, headers) |
b/snf-cyclades-app/synnefo/volume/management/commands/snapshot-remove.py | ||
---|---|---|
1 |
# Copyright 2011-2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or without |
|
4 |
# modification, are permitted provided that the following conditions |
|
5 |
# are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above copyright |
|
8 |
# notice, this list of conditions and the following disclaimer. |
|
9 |
# |
|
10 |
# 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
# notice, this list of conditions and the following disclaimer in the |
|
12 |
# documentation and/or other materials provided with the distribution. |
|
13 |
# |
|
14 |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
15 |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
16 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
17 |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
18 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
19 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
20 |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
21 |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
22 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
23 |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
24 |
# SUCH DAMAGE. |
|
25 |
# |
|
26 |
# The views and conclusions contained in the software and documentation are |
|
27 |
# those of the authors and should not be interpreted as representing official |
|
28 |
# policies, either expressed or implied, of GRNET S.A. |
|
29 |
# |
|
30 |
from optparse import make_option |
|
31 |
from django.core.management.base import CommandError |
|
32 |
from synnefo.volume import snapshots, util |
|
33 |
from synnefo.management import common |
|
34 |
from snf_django.management.commands import RemoveCommand |
|
35 |
|
|
36 |
|
|
37 |
class Command(RemoveCommand): |
|
38 |
args = "<Snapshot ID> [<Snapshot ID> ...]" |
|
39 |
help = "Remove a snapshot" |
|
40 |
option_list = RemoveCommand.option_list + ( |
|
41 |
make_option( |
|
42 |
"--user_id", |
|
43 |
dest="user_id", |
|
44 |
default=None, |
|
45 |
help="UUID of the owner of the snapshot"), |
|
46 |
) |
|
47 |
|
|
48 |
@common.convert_api_faults |
|
49 |
def handle(self, *args, **options): |
|
50 |
if not args: |
|
51 |
raise CommandError("Please provide a snapshot ID") |
|
52 |
|
|
53 |
force = options['force'] |
|
54 |
message = "snapshots" if len(args) > 1 else "snapshot" |
|
55 |
self.confirm_deletion(force, message, args) |
|
56 |
user_id = self.options["user_id"] |
|
57 |
|
|
58 |
for snapshot_id in args: |
|
59 |
self.stdout.write("\n") |
|
60 |
try: |
|
61 |
snapshot = util.get_snapshot(user_id, snapshot_id) |
|
62 |
|
|
63 |
snapshots.delete(snapshot) |
|
64 |
self.stdout.write("Successfully removed snapshot %s\n" |
|
65 |
% snapshot) |
|
66 |
except CommandError as e: |
|
67 |
self.stdout.write("Error -- %s\n" % e.message) |
b/snf-cyclades-app/synnefo/volume/management/commands/volume-create.py | ||
---|---|---|
1 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from optparse import make_option |
|
35 |
|
|
36 |
from django.core.management.base import BaseCommand, CommandError |
|
37 |
|
|
38 |
from snf_django.management.utils import parse_bool |
|
39 |
from synnefo.management import common, pprint |
|
40 |
from synnefo.volume import volumes |
|
41 |
|
|
42 |
HELP_MSG = """Create a new volume.""" |
|
43 |
|
|
44 |
|
|
45 |
class Command(BaseCommand): |
|
46 |
help = HELP_MSG |
|
47 |
|
|
48 |
option_list = BaseCommand.option_list + ( |
|
49 |
make_option( |
|
50 |
"--name", |
|
51 |
dest="name", |
|
52 |
default=None, |
|
53 |
help="Display name of the volume."), |
|
54 |
make_option( |
|
55 |
"--description", |
|
56 |
dest="description", |
|
57 |
default=None, |
|
58 |
help="Display description of the volume."), |
|
59 |
make_option( |
|
60 |
"--owner", |
|
61 |
dest="user_id", |
|
62 |
default=None, |
|
63 |
help="UUID of the owner of the volume."), |
|
64 |
make_option( |
|
65 |
"-s", "--size", |
|
66 |
dest="size", |
|
67 |
default=None, |
|
68 |
help="Size of the new volume in GB"), |
|
69 |
make_option( |
|
70 |
"--server", |
|
71 |
dest="server_id", |
|
72 |
default=None, |
|
73 |
help="The ID of the server that the volume will be connected to."), |
|
74 |
make_option( |
|
75 |
"--wait", |
|
76 |
dest="wait", |
|
77 |
default="True", |
|
78 |
choices=["True", "False"], |
|
79 |
metavar="True|False", |
|
80 |
help="Wait for Ganeti jobs to complete."), |
|
81 |
) |
|
82 |
|
|
83 |
@common.convert_api_faults |
|
84 |
def handle(self, *args, **options): |
|
85 |
if args: |
|
86 |
raise CommandError("Command doesn't accept any arguments") |
|
87 |
|
|
88 |
size = options.get("size") |
|
89 |
user_id = options.get("user_id") |
|
90 |
server_id = options.get("server_id") |
|
91 |
wait = parse_bool(options["wait"]) |
|
92 |
|
|
93 |
display_name = options.get("name", "") |
|
94 |
display_description = options.get("description", "") |
|
95 |
|
|
96 |
if size is None: |
|
97 |
raise CommandError("Please specify the size of the volume") |
|
98 |
|
|
99 |
if server_id is None: |
|
100 |
raise CommandError("Please specify the server to attach the" |
|
101 |
" volume.") |
|
102 |
|
|
103 |
vm = common.get_vm(server_id) |
|
104 |
|
|
105 |
if user_id is None: |
|
106 |
user_id = vm.userid |
|
107 |
|
|
108 |
source_image_id = source_volume_id = source_snapshot_id = None |
|
109 |
volume = volumes.create(user_id, size, server_id, |
|
110 |
name=display_name, |
|
111 |
description=display_description, |
|
112 |
source_image_id=source_image_id, |
|
113 |
source_snapshot_id=source_snapshot_id, |
|
114 |
source_volume_id=source_volume_id, |
|
115 |
metadata={}) |
|
116 |
|
|
117 |
self.stdout.write("Created volume '%s' in DB:\n" % volume.id) |
|
118 |
|
|
119 |
pprint.pprint_volume(volume, stdout=self.stdout) |
|
120 |
self.stdout.write("\n") |
|
121 |
if volume.machine is not None: |
|
122 |
volume.machine.task_job_id = volume.backendjobid |
|
123 |
common.wait_server_task(volume.machine, wait, stdout=self.stdout) |
b/snf-cyclades-app/synnefo/volume/management/commands/volume-inspect.py | ||
---|---|---|
1 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from optparse import make_option |
|
35 |
from django.core.management.base import BaseCommand, CommandError |
|
36 |
|
|
37 |
from synnefo.management.common import convert_api_faults |
|
38 |
from synnefo.management import pprint, common |
|
39 |
|
|
40 |
|
|
41 |
class Command(BaseCommand): |
|
42 |
help = "Inspect a Volume on DB and Ganeti" |
|
43 |
args = "<volume ID>" |
|
44 |
|
|
45 |
option_list = BaseCommand.option_list + ( |
|
46 |
make_option( |
|
47 |
'--displayname', |
|
48 |
action='store_true', |
|
49 |
dest='displayname', |
|
50 |
default=False, |
|
51 |
help="Display both uuid and display name"), |
|
52 |
) |
|
53 |
|
|
54 |
@convert_api_faults |
|
55 |
def handle(self, *args, **options): |
|
56 |
if len(args) != 1: |
|
57 |
raise CommandError("Please provide a volume ID") |
|
58 |
|
|
59 |
volume = common.get_volume(args[0]) |
|
60 |
|
|
61 |
pprint.pprint_volume(volume, stdout=self.stdout) |
|
62 |
self.stdout.write('\n\n') |
|
63 |
|
|
64 |
pprint.pprint_volume_in_ganeti(volume, stdout=self.stdout) |
b/snf-cyclades-app/synnefo/volume/management/commands/volume-list.py | ||
---|---|---|
1 |
# Copyright 2012-2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
#from optparse import make_option |
|
35 |
|
|
36 |
from snf_django.management.commands import ListCommand |
|
37 |
from synnefo.db.models import Volume |
|
38 |
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN, |
|
39 |
ASTAKOS_AUTH_URL) |
|
40 |
from logging import getLogger |
|
41 |
log = getLogger(__name__) |
|
42 |
|
|
43 |
|
|
44 |
class Command(ListCommand): |
|
45 |
help = "List Volumes" |
|
46 |
|
|
47 |
option_list = ListCommand.option_list |
|
48 |
|
|
49 |
object_class = Volume |
|
50 |
deleted_field = "deleted" |
|
51 |
user_uuid_field = "userid" |
|
52 |
astakos_auth_url = ASTAKOS_AUTH_URL |
|
53 |
astakos_token = ASTAKOS_TOKEN |
|
54 |
|
|
55 |
FIELDS = { |
|
56 |
"id": ("id", "ID of the server"), |
|
57 |
"name": ("name", "Name of the server"), |
|
58 |
"user.uuid": ("userid", "The UUID of the server's owner"), |
|
59 |
"server_id": ("machine_id", ""), |
|
60 |
"source": ("source", ""), |
|
61 |
"status": ("status", ""), |
|
62 |
"created": ("created", "The date the server was created"), |
|
63 |
"deleted": ("deleted", "Whether the server is deleted or not"), |
|
64 |
} |
|
65 |
|
|
66 |
fields = ["id", "name", "user.uuid", "status", "source", "server_id"] |
b/snf-cyclades-app/synnefo/volume/management/commands/volume-remove.py | ||
---|---|---|
1 |
# Copyright 2011-2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or without |
|
4 |
# modification, are permitted provided that the following conditions |
|
5 |
# are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above copyright |
|
8 |
# notice, this list of conditions and the following disclaimer. |
|
9 |
# |
|
10 |
# 2. Redistributions in binary form must reproduce the above copyright |
|
11 |
# notice, this list of conditions and the following disclaimer in the |
|
12 |
# documentation and/or other materials provided with the distribution. |
|
13 |
# |
|
14 |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
15 |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
16 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
17 |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
18 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
19 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
20 |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
21 |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
22 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
23 |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
24 |
# SUCH DAMAGE. |
|
25 |
# |
|
26 |
# The views and conclusions contained in the software and documentation are |
|
27 |
# those of the authors and should not be interpreted as representing official |
|
28 |
# policies, either expressed or implied, of GRNET S.A. |
|
29 |
# |
|
30 |
|
|
31 |
from optparse import make_option |
|
32 |
from django.core.management.base import CommandError |
|
33 |
from synnefo.volume import volumes |
|
34 |
from synnefo.management import common |
|
35 |
from snf_django.management.utils import parse_bool |
|
36 |
from snf_django.management.commands import RemoveCommand |
|
37 |
|
|
38 |
|
|
39 |
class Command(RemoveCommand): |
|
40 |
can_import_settings = True |
|
41 |
args = "<Volume ID> [<Volume ID> ...]" |
|
42 |
help = "Remove a volume from the Database and from the VM attached to" |
|
43 |
option_list = RemoveCommand.option_list + ( |
|
44 |
make_option( |
|
45 |
"--wait", |
|
46 |
dest="wait", |
|
47 |
default="True", |
|
48 |
choices=["True", "False"], |
|
49 |
metavar="True|False", |
|
50 |
help="Wait for Ganeti jobs to complete."), |
|
51 |
) |
|
52 |
|
|
53 |
@common.convert_api_faults |
|
54 |
def handle(self, *args, **options): |
|
55 |
if not args: |
|
56 |
raise CommandError("Please provide a volume ID") |
|
57 |
|
|
58 |
force = options['force'] |
|
59 |
message = "volumes" if len(args) > 1 else "volume" |
|
60 |
self.confirm_deletion(force, message, args) |
|
61 |
|
|
62 |
for volume_id in args: |
|
63 |
self.stdout.write("\n") |
|
64 |
try: |
|
65 |
volume = common.get_volume(volume_id, for_update=True) |
|
66 |
|
|
67 |
volumes.delete(volume) |
|
68 |
|
|
69 |
wait = parse_bool(options["wait"]) |
|
70 |
if volume.machine is not None: |
|
71 |
volume.machine.task_job_id = volume.backendjobid |
|
72 |
common.wait_server_task(volume.machine, wait, |
|
73 |
stdout=self.stdout) |
|
74 |
else: |
|
75 |
self.stdout.write("Successfully removed volume %s\n" |
|
76 |
% volume) |
|
77 |
except CommandError as e: |
|
78 |
self.stdout.write("Error -- %s\n" % e.message) |
b/snf-cyclades-app/synnefo/volume/management/commands/volume-show.py | ||
---|---|---|
1 |
# Copyright 2013 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
from optparse import make_option |
|
35 |
from django.core.management.base import BaseCommand, CommandError |
|
36 |
|
|
37 |
from synnefo.management.common import convert_api_faults |
|
38 |
from synnefo.management import pprint, common |
|
39 |
|
|
40 |
|
|
41 |
class Command(BaseCommand): |
|
42 |
help = "Show Volume information" |
|
43 |
args = "<volume ID>" |
|
44 |
|
|
45 |
option_list = BaseCommand.option_list + ( |
|
46 |
make_option( |
|
47 |
'--displayname', |
|
48 |
action='store_true', |
|
49 |
dest='displayname', |
|
50 |
default=False, |
|
51 |
help="Display both uuid and display name"), |
|
52 |
) |
|
53 |
|
|
54 |
@convert_api_faults |
|
55 |
def handle(self, *args, **options): |
|
56 |
if len(args) != 1: |
|
57 |
raise CommandError("Please provide a volume ID") |
|
58 |
|
|
59 |
volume = common.get_volume(args[0]) |
|
60 |
|
|
61 |
pprint.pprint_volume(volume, stdout=self.stdout) |
|
62 |
self.stdout.write('\n\n') |
Also available in: Unified diff