Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / management / commands / server-inspect.py @ cf1984d8

History | View | Annotate | Download (6.4 kB)

1
# Copyright 2012 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 datetime import datetime
35
from optparse import make_option
36
from django.core.management.base import BaseCommand, CommandError
37

    
38
from synnefo.lib.utils import merge_time
39
from synnefo.logic.rapi import GanetiApiError
40
from synnefo.management.common import Omit
41
from synnefo.management import common
42

    
43

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

    
50
# Fields to print from a gnt-job info
51
GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
52
                     'oplog', 'start_ts', 'end_ts')
53

    
54

    
55
class Command(BaseCommand):
56
    help = "Inspect a server on DB and Ganeti"
57
    args = "<server ID>"
58

    
59
    option_list = BaseCommand.option_list + (
60
        make_option(
61
            '--jobs',
62
            action='store_true',
63
            dest='jobs',
64
            default=False,
65
            help="Show non-archived jobs concerning server."),
66
        make_option(
67
            '--displayname',
68
            action='store_true',
69
            dest='displayname',
70
            default=False,
71
            help="Display both uuid and display name"),
72
    )
73

    
74
    def handle(self, *args, **options):
75
        if len(args) != 1:
76
            raise CommandError("Please provide a server ID")
77

    
78
        vm = common.get_vm(args[0])
79

    
80
        displayname = options['displayname']
81

    
82
        ucache = common.UserCache()
83

    
84
        try:
85
            image = common.get_image(vm.imageid, vm.userid)['name']
86
        except:
87
            image = vm.imageid
88

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

    
97
        uuid = vm.userid
98
        if displayname:
99
            dname = ucache.get_name(uuid)
100

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

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

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

    
141
        if not options['jobs']:
142
            return
143

    
144
        self.stdout.write('\n')
145
        self.stdout.write(sep)
146
        self.stdout.write('Non-archived jobs concerning Server in Ganeti\n')
147
        self.stdout.write(sep)
148
        jobs = client.GetJobs()
149
        for j in jobs:
150
            info = client.GetJobStatus(j)
151
            summary = ' '.join(info['summary'])
152
            job_is_relevant = summary.startswith("INSTANCE") and\
153
                (summary.find(vm.backend_vm_id) != -1)
154
            if job_is_relevant:
155
                for i in GANETI_JOB_FIELDS:
156
                    value = info[i]
157
                    if i.find('_ts') != -1:
158
                        value = merge_time(value)
159
                    try:
160
                        self.stdout.write(i.ljust(14) + ': ' + str(value) +
161
                                          '\n')
162
                    except KeyError:
163
                        pass
164
                self.stdout.write('\n' + sep)
165
        # Return the RAPI client to pool
166
        vm.put_client(client)