~hudson-openstack/nova/trunk

« back to all changes in this revision

Viewing changes to bin/nova-manage

  • Committer: vladimir.p
  • Date: 2011-08-26 01:38:35 UTC
  • mto: This revision was merged to the branch mainline in revision 1502.
  • Revision ID: vladimir@zadarastorage.com-20110826013835-sk22ic51cwbt0xa5
VSA code redesign. Drive types completely replaced by Volume types

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
  CLI interface for nova management.
54
54
"""
55
55
 
 
56
import ast
56
57
import gettext
57
58
import glob
58
59
import json
64
65
 
65
66
from optparse import OptionParser
66
67
 
67
 
import ast
68
 
 
69
68
# If ../nova/__init__.py exists, add ../ to Python search path, so that
70
69
# it will override what happens to be installed in /usr/(local/)lib/python...
71
70
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
87
86
from nova import rpc
88
87
from nova import utils
89
88
from nova import version
 
89
from nova import vsa
90
90
from nova.api.ec2 import ec2utils
91
91
from nova.auth import manager
92
92
from nova.cloudpipe import pipelib
93
93
from nova.compute import instance_types
94
94
from nova.db import migration
95
 
from nova import compute
96
 
from nova import volume
97
 
from nova import vsa
98
 
from nova.vsa import drive_types
 
95
from nova.volume import volume_types
99
96
 
100
97
FLAGS = flags.FLAGS
101
98
flags.DECLARE('fixed_range', 'nova.network.manager')
1076
1073
    def __init__(self, *args, **kwargs):
1077
1074
        self.manager = manager.AuthManager()
1078
1075
        self.vsa_api = vsa.API()
1079
 
        self.compute_api = compute.API()
1080
 
        self.volume_api = volume.API()
1081
1076
        self.context = context.get_admin_context()
1082
1077
 
1083
1078
        self._format_str_vsa = "%-5s %-15s %-25s %-10s %-6s "\
1084
1079
                               "%-9s %-10s %-10s %10s"
1085
1080
        self._format_str_volume = "\t%-4s %-15s %-5s %-10s %-20s %s"
1086
 
        self._format_str_drive = "\t%-4s %-15s %-5s %-10s %-20s %s"
 
1081
        self._format_str_drive = "\t%-4s %-15s %-5s %-10s %-20s %-4s %-10s %s"
1087
1082
        self._format_str_instance = "\t%-4s %-10s %-20s %-12s %-10s "\
1088
1083
                                    "%-15s %-15s %-10s %-15s %s"
1089
1084
 
1124
1119
    def _print_volume(self, vol):
1125
1120
        print self._format_str_volume %\
1126
1121
            (vol['id'],
1127
 
             vol['display_name'],
 
1122
             vol['display_name'] or vol['name'],
1128
1123
             vol['size'],
1129
1124
             vol['status'],
1130
1125
             vol['attach_status'],
1138
1133
                _('size'),
1139
1134
                _('status'),
1140
1135
                _('host'),
 
1136
                _('type'),
 
1137
                _('typeName'),
1141
1138
                _('createTime'))
1142
1139
 
1143
1140
    def _print_drive(self, drive):
1144
 
        print self._format_str_volume %\
 
1141
        if drive['volume_type_id'] is not None and drive.get('volume_type'):
 
1142
            drive_type_name = drive['volume_type'].get('name')
 
1143
        else:
 
1144
            drive_type_name = ''
 
1145
 
 
1146
        print self._format_str_drive %\
1145
1147
            (drive['id'],
1146
1148
             drive['display_name'],
1147
1149
             drive['size'],
1148
1150
             drive['status'],
1149
1151
             drive['host'],
 
1152
             drive['volume_type_id'],
 
1153
             drive_type_name,
1150
1154
             str(drive['created_at']))
1151
1155
 
1152
1156
    def _print_instance_header(self):
1196
1200
            vsa_id = vsa.get('id')
1197
1201
 
1198
1202
            if print_instances:
1199
 
                instances = self.compute_api.get_all(context,
1200
 
                                    search_opts={'metadata':
1201
 
                                                 dict(vsa_id=str(vsa_id))})
 
1203
                instances = self.vsa_api.get_all_vsa_instances(context, vsa_id)
1202
1204
                if instances:
1203
1205
                    print
1204
1206
                    self._print_instance_header()
1207
1209
                    print
1208
1210
 
1209
1211
            if print_drives:
1210
 
                drives = self.volume_api.get_all_by_vsa(context,
1211
 
                                                        vsa_id, "to")
 
1212
                drives = self.vsa_api.get_all_vsa_drives(context, vsa_id)
1212
1213
                if drives:
1213
1214
                    self._print_drive_header()
1214
1215
                    for drive in drives:
1216
1217
                    print
1217
1218
 
1218
1219
            if print_volumes:
1219
 
                volumes = self.volume_api.get_all_by_vsa(context,
1220
 
                                                         vsa_id, "from")
 
1220
                volumes = self.vsa_api.get_all_vsa_volumes(context, vsa_id)
1221
1221
                if volumes:
1222
1222
                    self._print_volume_header()
1223
1223
                    for volume in volumes:
1344
1344
 
1345
1345
    @args('--id', dest='vsa_id', metavar="<vsa_id>",
1346
1346
        help='VSA ID (optional)')
1347
 
    @args('--all', dest='all', action="store_true",
 
1347
    @args('--all', dest='all', action="store_true", default=False,
1348
1348
        help='Show all available details')
1349
1349
    @args('--drives', dest='drives', action="store_true",
1350
1350
        help='Include drive-level details')
1384
1384
    def __init__(self, *args, **kwargs):
1385
1385
        super(VsaDriveTypeCommands, self).__init__(*args, **kwargs)
1386
1386
        self.context = context.get_admin_context()
 
1387
        self._drive_type_template = '%s_%sGB_%sRPM'
1387
1388
 
1388
1389
    def _list(self, drives):
1389
1390
        format_str = "%-5s %-30s %-10s %-10s %-10s %-20s %-10s %s"
1398
1399
                    _('visible'),
1399
1400
                    _('createTime'))
1400
1401
 
1401
 
        for drive in drives:
 
1402
        for name, vol_type in drives.iteritems():
 
1403
            drive = vol_type.get('extra_specs')
1402
1404
            print format_str %\
1403
 
                (str(drive['id']),
1404
 
                drive['name'],
1405
 
                drive['type'],
1406
 
                str(drive['size_gb']),
1407
 
                drive['rpm'],
1408
 
                drive['capabilities'],
1409
 
                str(drive['visible']),
1410
 
                str(drive['created_at']))
 
1405
                (str(vol_type['id']),
 
1406
                drive['drive_name'],
 
1407
                drive['drive_type'],
 
1408
                drive['drive_size'],
 
1409
                drive['drive_rpm'],
 
1410
                drive.get('capabilities', ''),
 
1411
                str(drive.get('visible', '')),
 
1412
                str(vol_type['created_at']))
1411
1413
 
1412
1414
    @args('--type', dest='type', metavar="<type>",
1413
1415
        help='Drive type (SATA, SAS, SSD, etc.)')
1414
1416
    @args('--size', dest='size_gb', metavar="<gb>", help='Drive size in GB')
1415
1417
    @args('--rpm', dest='rpm', metavar="<rpm>", help='RPM')
1416
 
    @args('--capabilities', dest='capabilities', metavar="<string>",
1417
 
        help='Different capabilities')
1418
 
    @args('--visible', dest='visible', metavar="<show|hide>",
 
1418
    @args('--capabilities', dest='capabilities', default=None,
 
1419
        metavar="<string>", help='Different capabilities')
 
1420
    @args('--hide', dest='hide', action="store_true", default=False,
1419
1421
        help='Show or hide drive')
1420
1422
    @args('--name', dest='name', metavar="<name>", help='Drive name')
1421
 
    def create(self, type, size_gb, rpm, capabilities='',
1422
 
                     visible=None, name=None):
 
1423
    def create(self, type, size_gb, rpm, capabilities=None,
 
1424
                     hide=False, name=None):
1423
1425
        """Create drive type."""
1424
1426
 
1425
 
        if visible in [None, "--show", "show"]:
1426
 
            visible = True
1427
 
        elif visible in ["--hide", "hide"]:
1428
 
            visible = False
 
1427
        hide = True if hide in [True, "True", "--hide", "hide"] else False
 
1428
 
 
1429
        if name is None:
 
1430
            name = self._drive_type_template % (type, size_gb, rpm)
 
1431
 
 
1432
        extra_specs = {'type': 'vsa_drive',
 
1433
                       'drive_name': name,
 
1434
                       'drive_type': type,
 
1435
                       'drive_size': size_gb,
 
1436
                       'drive_rpm': rpm,
 
1437
                       'visible': True,
 
1438
                       }
 
1439
        if hide:
 
1440
            extra_specs['visible'] = False
 
1441
 
 
1442
        if capabilities is not None and capabilities != '':
 
1443
            extra_specs['capabilities'] = capabilities
 
1444
 
 
1445
        volume_types.create(self.context, name, extra_specs)
 
1446
        result = volume_types.get_volume_type_by_name(self.context, name)
 
1447
        self._list({name: result})
 
1448
 
 
1449
    @args('--name', dest='name', metavar="<name>", help='Drive name')
 
1450
    @args('--purge', action="store_true", dest='purge', default=False,
 
1451
            help='purge record from database')
 
1452
    def delete(self, name, purge):
 
1453
        """Marks instance types / flavors as deleted"""
 
1454
        try:
 
1455
            if purge:
 
1456
                volume_types.purge(self.context, name)
 
1457
                verb = "purged"
 
1458
            else:
 
1459
                volume_types.destroy(self.context, name)
 
1460
                verb = "deleted"
 
1461
        except exception.ApiError:
 
1462
            print "Valid volume type name is required"
 
1463
            sys.exit(1)
 
1464
        except exception.DBError, e:
 
1465
            print "DB Error: %s" % e
 
1466
            sys.exit(2)
 
1467
        except:
 
1468
            sys.exit(3)
1429
1469
        else:
1430
 
            raise ValueError(_('Visible parameter should be set to --show '\
1431
 
                               'or --hide'))
1432
 
 
1433
 
        result = drive_types.create(self.context,
1434
 
                                type, int(size_gb), rpm,
1435
 
                                capabilities, visible, name)
1436
 
        self._list([result])
1437
 
 
1438
 
    @args('--name', dest='name', metavar="<name>", help='Drive name')
1439
 
    def delete(self, name):
1440
 
        """Delete drive type."""
1441
 
 
1442
 
        dtype = drive_types.get_by_name(self.context, name)
1443
 
        drive_types.delete(self.context, dtype['id'])
1444
 
 
1445
 
    @args('--name', dest='name', metavar="<name>", help='Drive name')
1446
 
    @args('--new_name', dest='new_name', metavar="<name>",
1447
 
        help='New Drive name (optional)')
1448
 
    def rename(self, name, new_name=None):
1449
 
        """Rename drive type."""
1450
 
 
1451
 
        dtype = drive_types.rename(self.context,
1452
 
                                   name, new_name)
1453
 
        self._list([dtype])
1454
 
 
1455
 
    @args('--all', dest='visible', action="store_false",
1456
 
        help='Show all drives')
 
1470
            print "%s %s" % (name, verb)
 
1471
 
 
1472
    @args('--all', dest='all', action="store_true", default=False,
 
1473
        help='Show all drives (including invisible)')
1457
1474
    @args('--name', dest='name', metavar="<name>",
1458
1475
        help='Show only specified drive')
1459
 
    def list(self, visible=None, name=None):
 
1476
    def list(self, all=False, name=None):
1460
1477
        """Describe all available VSA drive types (or particular one)."""
1461
1478
 
1462
 
        visible = False if visible in ["--all", False] else True
 
1479
        all = False if all in ["--all", False, "False"] else True
1463
1480
 
 
1481
        search_opts = {'extra_specs': {'type': 'vsa_drive'}}
1464
1482
        if name is not None:
1465
 
            drive = drive_types.get_by_name(self.context, name)
1466
 
            drives = [drive]
1467
 
        else:
1468
 
            drives = drive_types.get_all(self.context, visible)
1469
 
 
 
1483
            search_opts['extra_specs']['name'] = name
 
1484
 
 
1485
        if all == False:
 
1486
            search_opts['extra_specs']['visible'] = '1'
 
1487
 
 
1488
        drives = volume_types.get_all_types(self.context,
 
1489
                                            search_opts=search_opts)
1470
1490
        self._list(drives)
1471
1491
 
1472
1492
    @args('--name', dest='name', metavar="<name>", help='Drive name')
1474
1494
        help='Drive type (SATA, SAS, SSD, etc.)')
1475
1495
    @args('--size', dest='size_gb', metavar="<gb>", help='Drive size in GB')
1476
1496
    @args('--rpm', dest='rpm', metavar="<rpm>", help='RPM')
1477
 
    @args('--capabilities', dest='capabilities', metavar="<string>",
1478
 
        help='Different capabilities')
1479
 
    @args('--visible', dest='visible', metavar="<show|hide>",
1480
 
        help='Show or hide drive')
 
1497
    @args('--capabilities', dest='capabilities', default=None,
 
1498
        metavar="<string>", help='Different capabilities')
 
1499
    @args('--visible', dest='visible',
 
1500
        metavar="<show|hide>", help='Show or hide drive')
1481
1501
    def update(self, name, type=None, size_gb=None, rpm=None,
1482
 
                     capabilities='', visible=None):
 
1502
                     capabilities=None, visible=None):
1483
1503
        """Update drive type."""
1484
1504
 
1485
 
        values = {
1486
 
            'type': type,
1487
 
            'size_gb': size_gb,
1488
 
            'rpm': rpm,
1489
 
            'capabilities': capabilities,
1490
 
            }
1491
 
        if visible:
1492
 
            if visible in ["--show", "show"]:
1493
 
                values['visible'] = True
1494
 
            elif visible in ["--hide", "hide"]:
1495
 
                values['visible'] = False
 
1505
        volume_type = volume_types.get_volume_type_by_name(self.context, name)
 
1506
 
 
1507
        extra_specs = {'type': 'vsa_drive'}
 
1508
 
 
1509
        if type:
 
1510
            extra_specs['drive_type'] = type
 
1511
 
 
1512
        if size_gb:
 
1513
            extra_specs['drive_size'] = size_gb
 
1514
 
 
1515
        if rpm:
 
1516
            extra_specs['drive_rpm'] = rpm
 
1517
 
 
1518
        if capabilities:
 
1519
            extra_specs['capabilities'] = capabilities
 
1520
 
 
1521
        if visible is not None:
 
1522
            if visible in ["show", True, "True"]:
 
1523
                extra_specs['visible'] = True
 
1524
            elif visible in ["hide", False, "False"]:
 
1525
                extra_specs['visible'] = False
1496
1526
            else:
1497
 
                raise ValueError(_("Visible parameter should be set to "\
1498
 
                                   "--show or --hide"))
 
1527
                raise ValueError(_('visible parameter should be set to '\
 
1528
                                   'show or hide'))
1499
1529
 
1500
 
        dtype = drive_types.get_by_name(self.context, name)
1501
 
        dtype = drive_types.update(self.context, dtype['id'], **values)
1502
 
        self._list([dtype])
 
1530
        db.api.volume_type_extra_specs_update_or_create(self.context,
 
1531
                    volume_type['id'],
 
1532
                    extra_specs)
 
1533
        result = volume_types.get_volume_type_by_name(self.context, name)
 
1534
        self._list({name: result})
1503
1535
 
1504
1536
 
1505
1537
class VolumeCommands(object):