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