Revision 8b178e6b

b/snf-cyclades-app/synnefo/api/management/commands/server-create.py
34 34
from optparse import make_option
35 35

  
36 36
from django.core.management.base import BaseCommand, CommandError
37
from synnefo.management import common
37
from synnefo.management import common, pprint
38
from snf_django.management.utils import parse_bool
38 39

  
39 40
from synnefo.logic import servers
40 41

  
......
67 68
                         " Use snf-manage flavor-list to find out"
68 69
                         " available flavors."),
69 70
        make_option("--password", dest="password",
70
                    help="Password for the new server")
71
                    help="Password for the new server"),
72
        make_option(
73
            '--wait',
74
            dest='wait',
75
            default="True",
76
            choices=["True", "False"],
77
            metavar="True|False",
78
            help="Wait for Ganeti job to complete."),
79

  
71 80
    )
72 81

  
73 82
    @common.convert_api_faults
......
100 109
        else:
101 110
            backend = None
102 111

  
103
        servers.create(user_id, name, password, flavor, image,
104
                       use_backend=backend)
112
        server = servers.create(user_id, name, password, flavor, image,
113
                                use_backend=backend)
114
        pprint.pprint_server(server, stdout=self.stdout)
115

  
116
        wait = parse_bool(options["wait"])
117
        common.wait_server_task(server, wait, self.stdout)
b/snf-cyclades-app/synnefo/api/management/commands/server-inspect.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
......
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from datetime import datetime
35 34
from optparse import make_option
36 35
from django.core.management.base import BaseCommand, CommandError
37 36

  
38
from synnefo.lib.utils import merge_time
39
from snf_django.lib.astakos import UserCache
40
from synnefo.logic.rapi import GanetiApiError
41
from synnefo.management.common import Omit
42 37
from synnefo.management import common
43
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
44
                              ASTAKOS_BASE_URL)
45

  
46

  
47
# Fields to print from a gnt-instance info
48
GANETI_INSTANCE_FIELDS = ('name', 'oper_state', 'admin_state', 'status',
49
                          'pnode', 'snode', 'network_port', 'disk_template',
50
                          'disk_usage', 'oper_ram', 'oper_vcpus', 'mtime',
51
                          'nic.ips', 'nic.macs', 'nic.networks', 'nic.modes')
52

  
53
# Fields to print from a gnt-job info
54
GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
55
                     'oplog', 'start_ts', 'end_ts')
38
from synnefo.management import pprint
56 39

  
57 40

  
58 41
class Command(BaseCommand):
......
82 65

  
83 66
        displayname = options['displayname']
84 67

  
85
        ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
86

  
87
        try:
88
            image = common.get_image(vm.imageid, vm.userid)['name']
89
        except:
90
            image = vm.imageid
91

  
92
        sep = '-' * 80 + '\n'
93
        labels = filter(lambda x: x is not Omit,
94
                        ['name', 'owner_uuid',
95
                         'owner_name' if displayname else Omit,
96
                         'flavor', 'image', 'state', 'backend', 'deleted',
97
                         'action', 'task', 'task_job', 'backendjobid',
98
                         'backendopcode', 'backendjobstatus', 'backend_time'])
99

  
100
        uuid = vm.userid
101
        if displayname:
102
            dname = ucache.get_name(uuid)
103

  
104
        fields = filter(lambda x: x is not Omit,
105
                        [vm.name, uuid, dname if displayname else Omit,
106
                         vm.flavor.name, image, common.format_vm_state(vm),
107
                         str(vm.backend), str(vm.deleted), str(vm.action),
108
                         str(vm.task), str(vm.task_job_id),
109
                         str(vm.backendjobid), str(vm.backendopcode),
110
                         str(vm.backendjobstatus), str(vm.backendtime)])
111

  
112
        self.stdout.write(sep)
113
        self.stdout.write('State of Server in DB\n')
114
        self.stdout.write(sep)
115
        for l, f in zip(labels, fields):
116
            self.stdout.write(l.ljust(18) + ': ' + f.ljust(20) + '\n')
117
        self.stdout.write('\n')
118
        for nic in vm.nics.all():
119
            params = (nic.index, nic.ipv4, nic.mac, nic.ipv6,  nic.network)
120
            self.stdout.write("nic/%d: IPv4: %s, MAC: %s, IPv6:%s,"
121
                              " Network: %s\n" % params)
122

  
123
        client = vm.get_client()
124
        try:
125
            g_vm = client.GetInstance(vm.backend_vm_id)
126
            self.stdout.write('\n')
127
            self.stdout.write(sep)
128
            self.stdout.write('State of Server in Ganeti\n')
129
            self.stdout.write(sep)
130
            for i in GANETI_INSTANCE_FIELDS:
131
                try:
132
                    value = g_vm[i]
133
                    if i.find('time') != -1:
134
                        value = datetime.fromtimestamp(value)
135
                    self.stdout.write(i.ljust(14) + ': ' + str(value) + '\n')
136
                except KeyError:
137
                    pass
138
        except GanetiApiError as e:
139
            if e.code == 404:
140
                self.stdout.write('Server does not exist in backend %s\n' %
141
                                  vm.backend.clustername)
142
            else:
143
                raise e
144

  
145
        if not options['jobs']:
146
            return
147

  
148
        self.stdout.write('\n')
149
        self.stdout.write(sep)
150
        self.stdout.write('Non-archived jobs concerning Server in Ganeti\n')
151
        self.stdout.write(sep)
152
        jobs = client.GetJobs()
153
        for j in jobs:
154
            info = client.GetJobStatus(j)
155
            summary = ' '.join(info['summary'])
156
            job_is_relevant = summary.startswith("INSTANCE") and\
157
                (summary.find(vm.backend_vm_id) != -1)
158
            if job_is_relevant:
159
                for i in GANETI_JOB_FIELDS:
160
                    value = info[i]
161
                    if i.find('_ts') != -1:
162
                        value = merge_time(value)
163
                    try:
164
                        self.stdout.write(i.ljust(14) + ': ' + str(value) +
165
                                          '\n')
166
                    except KeyError:
167
                        pass
168
                self.stdout.write('\n' + sep)
169
        # Return the RAPI client to pool
170
        vm.put_client(client)
68
        pprint.pprint_server(vm, display_mails=displayname, stdout=self.stdout)
69
        self.stdout.write("\n")
70
        pprint.pprint_server_nics(vm, stdout=self.stdout)
71
        self.stdout.write("\n")
72
        pprint.pprint_server_in_ganeti(vm, print_jobs=options["jobs"],
73
                                       stdout=self.stdout)
74
        self.stdout.write("\n")
b/snf-cyclades-app/synnefo/management/pprint.py
40 40
from synnefo.db.models import Backend, pooled_rapi_client
41 41
from synnefo.logic.rapi import GanetiApiError
42 42
from synnefo.logic.reconciliation import nics_from_instance
43
from synnefo.management.common import get_image
43 44

  
44 45

  
45 46
def pprint_network(network, display_mails=False, stdout=None, title=None):
......
56 57
        ("backend-name", network.backend_id),
57 58
        ("state", network.state),
58 59
        ("userid", userid),
59
        ("username", ucache.get_name(userid) if display_mails else userid),
60
        ("username", ucache.get_name(userid) if display_mails else None),
60 61
        ("public", network.public),
61 62
        ("floating_ip_pool", network.floating_ip_pool),
62 63
        ("external_router", network.external_router),
......
214 215
                 title=title)
215 216

  
216 217
    vm.put_client(client)
218

  
219

  
220
def pprint_server(server, display_mails=False, stdout=None, title=None):
221
    if stdout is None:
222
        stdout = sys.stdout
223
    if title is None:
224
        title = "State of Server %s in DB" % server.id
225

  
226
    ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
227
    userid = server.userid
228

  
229
    try:
230
        image = get_image(server.imageid, server.userid)['name']
231
    except:
232
        image = server.imageid
233

  
234
    server_dict = OrderedDict([
235
        ("id", server.id),
236
        ("name", server.name),
237
        ("userid", server.userid),
238
        ("username", ucache.get_name(userid) if display_mails else None),
239
        ("flavor_id", server.flavor_id),
240
        ("flavor_name", server.flavor.name),
241
        ("imageid", server.imageid),
242
        ("image_name", image),
243
        ("state", server.operstate),
244
        ("backend", server.backend),
245
        ("deleted", server.deleted),
246
        ("action", server.action),
247
        ("task", server.task),
248
        ("task_job_id", server.task_job_id),
249
        ("backendjobid", server.backendjobid),
250
        ("backendopcode", server.backendopcode),
251
        ("backendjobstatus", server.backendjobstatus),
252
        ("backend_time", server.backendtime),
253
        ])
254

  
255
    pprint_table(stdout, server_dict.items(), None, separator=" | ",
256
                 title=title)
257

  
258

  
259
def pprint_server_nics(server, stdout=None, title=None):
260
    if title is None:
261
        title = "NICs of Server %s" % server.id
262
    if stdout is None:
263
        stdout = sys.stdout
264

  
265
    nics = []
266
    for nic in server.nics.all():
267
        nics.append((nic.name, nic.index, nic.mac, nic.ipv4_address,
268
                     nic.ipv6_address, nic.network, nic.firewall_profile,
269
                     nic.state))
270

  
271
    headers = ["Name", "Index", "MAC", "IPv4 Address", "IPv6 Address",
272
               "Network", "Firewall", "State"]
273
    pprint_table(stdout, nics, headers, separator=" | ",
274
                 title=title)
275

  
276

  
277
def pprint_server_in_ganeti(server, print_jobs=False, stdout=None, title=None):
278
    if stdout is None:
279
        stdout = sys.stdout
280
    if title is None:
281
        title = "State of Server %s in Ganeti" % server.id
282

  
283
    client = server.get_client()
284
    try:
285
        server_info = client.GetInstance(server.backend_vm_id)
286
    except GanetiApiError as e:
287
        if e.code == 404:
288
            stdout.write("NIC seems attached to server %s, but"
289
                         " server does not exist in backend.\n"
290
                         % server)
291
            return
292
        raise e
293
    server.put_client(client)
294

  
295
    GANETI_INSTANCE_FIELDS = ('name', 'oper_state', 'admin_state', 'status',
296
                              'pnode', 'snode', 'network_port',
297
                              'disk_template', 'disk_usage',
298
                              'oper_ram', 'oper_vcpus', 'mtime')
299
    server_dict = OrderedDict([(k, server_info.get(k))
300
                              for k in GANETI_INSTANCE_FIELDS])
301

  
302
    pprint_table(stdout, server_dict.items(), None, separator=" | ",
303
                 title="NICs of Server %s in Ganeti" % server.id)
304
    stdout.write("\n")
305

  
306
    nics = nics_from_instance(server_info)
307
    nics_keys = ["ip", "mac", "name", "network"]
308
    nics_values = [[nic[key] for key in nics_keys] for nic in nics]
309
    pprint_table(stdout, nics_values, nics_keys, separator=" | ",
310
                 title=title)
311

  
312
    if not print_jobs:
313
        return
314

  
315
    client = server.get_client()
316
    jobs = client.GetJobs(bulk=True)
317
    server_jobs = filter(
318
        lambda x: server.backend_vm_id in (" ".join(x.get("summary"))), jobs)
319

  
320
    GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
321
                         'oplog', 'start_ts', 'end_ts')
322
    for server_job in server_jobs:
323
        stdout.write("\n")
324
        values = [server_job.get(k) for k in GANETI_JOB_FIELDS]
325
        pprint_table(stdout, zip(GANETI_JOB_FIELDS, values), None,
326
                     separator=" | ",
327
                     title="Ganeti Job %s" % server_job["id"])
328
    server.put_client(client)

Also available in: Unified diff