Revision 4cf8adf8

b/README.develop
169 169
	$ ./bin/python manage.py loaddata db/fixtures/flavors.json
170 170
	$ ./bin/python manage.py loaddata db/fixtures/images.json
171 171

  
172
The following fictures can be loaded optionally depending on
172
The following fixtures can be loaded optionally depending on
173 173
testing requirements:
174 174

  
175 175
	$ ./bin/python manage.py loaddata db/fixtures/vms.json
176
	$ ./bin/python manage.py loaddata db/fixtures/initial_data.json
177 176
	$ ./bin/python manage.py loaddata db/fixtures/disks.json
178 177

  
179 178
7. Set the BACKEND_PREFIX_ID variable to some unique prefix, e.g. your commit
180 179
username 
181 180

  
182 181
8. Start the system
183
    $ ./bin/python db/db_controller.py  #DB synch daemon
184
    $ ./bin/python manage.py runserver  #Django
182
    $ ./bin/python db/db_controller.py  # DB synch daemon
183
    $ ./bin/python manage.py runserver  # Django
185 184

  
186 185
9. (Hopefully) Done
187 186

  
b/api/actions.py
38 38
    """Arrange for an OOB console of the specified type
39 39

  
40 40
    This method arranges for an OOB console of the specified type.
41
    Only "vnc" type consoles are supported for now.
41
    Only consoles of type "vnc" are supported for now.
42
    
42 43
    It uses a running instance of vncauthproxy to setup proper
43 44
    VNC forwarding with a random password, then returns the necessary
44 45
    VNC connection info to the caller.
45 46

  
47
    JSON Request: {
48
        "console": {
49
            "type": "vnc"
50
        }
51
    }
52

  
53
    JSON Reply: {
54
        "vnc": {
55
            "host": "fqdn_here",
56
            "port": a_port_here,
57
            "password": "a_password_here"
58
        }
59
    }
60

  
46 61
    """
47 62
    # Normal Response Code: 200
48 63
    # Error Response Codes: computeFault (400, 500),
......
55 70
    #                       overLimit (413)
56 71
    try:
57 72
        console_type = args.get('type', '')
58
        if console_type != 'VNC':
59
            raise BadRequest(message="type can only be 'VNC'")
73
        if console_type != 'vnc':
74
            raise BadRequest(message="type can only be 'vnc'")
60 75
    except KeyError:
61 76
        raise BadRequest()
62 77

  
63 78
    # Use RAPI to get VNC console information for this instance
64 79
    if get_rsapi_state(vm) != 'ACTIVE':
65 80
        raise BadRequest(message="Server not in ACTIVE state")
66
    console_data = rapi.GetInstanceConsole(vm.backend_id)
81
    if settings.TEST:
82
        console_data = { 'kind': 'vnc', 'host': 'ganeti_node', 'port': 1000 }
83
    else:
84
        console_data = rapi.GetInstanceConsole(vm.backend_id)
67 85
    if console_data['kind'] != 'vnc':
68 86
        raise ServiceUnavailable()
69 87

  
70 88
    # Let vncauthproxy decide on the source port.
71 89
    # The alternative: static allocation, e.g.
72
    # sport = console_data['port'] - 1000]
90
    # sport = console_data['port'] - 1000
73 91
    sport = 0
74 92
    daddr = console_data['host']
75 93
    dport = console_data['port']
76 94
    passwd = random_password()
77 95

  
78 96
    try:
79
        fwd = request_vnc_forwarding(sport, daddr, dport, passwd)
97
        if settings.TEST:
98
            fwd = { 'source_port': 1234, 'status': 'OK' }
99
        else:
100
            fwd = request_vnc_forwarding(sport, daddr, dport, passwd)
80 101
        if fwd['status'] != "OK":
81
            raise ServiceUnavailable("Could not allocate VNC console port")
102
            raise ServiceUnavailable()
82 103
        vnc = { 'host': getfqdn(), 'port': fwd['source_port'], 'password': passwd }
83 104
    except Exception:
84
        #raise ServiceUnavailable("Could not allocate VNC console port")
85
        raise
105
        raise ServiceUnavailable("Could not allocate VNC console port")
86 106

  
87 107
    # Format to be reviewed by [verigak], FIXME
88 108
    if request.serialization == 'xml':
......
90 110
        data = render_to_string('vnc.xml', {'vnc': vnc})
91 111
    else:
92 112
        mimetype = 'application/json'
93
        data = json.dumps(vnc)
113
        data = json.dumps({'vnc': vnc})
94 114

  
95 115
    return HttpResponse(data, mimetype=mimetype, status=200)
96 116

  
b/api/servers.py
178 178
    # so that it gets a vm.id and vm.backend_id is valid.
179 179
    vm.save() 
180 180
                
181
    if request.META.get('SERVER_NAME', None) == 'testserver':
182
        backend_name = 'test-server'
183
        dry_run = True
184
    else:
185
        backend_name = vm.backend_id
186
        dry_run = False
187
    
188 181
    try:
189 182
        jobId = rapi.CreateInstance(
190 183
            mode='create',
191
            name=backend_name,
184
            name=vm.backend_id,
192 185
            disk_template='plain',
193 186
            disks=[{"size": 2000}],         #FIXME: Always ask for a 2GB disk for now
194 187
            nics=[{}],
......
196 189
            ip_check=False,
197 190
            name_check=False,
198 191
            pnode=rapi.GetNodes()[0],       #TODO: verify if this is necessary
199
            dry_run=dry_run,
192
            dry_run=settings.TEST,
200 193
            beparams=dict(auto_balance=True, vcpus=flavor.cpu, memory=flavor.ram))
201 194
    except GanetiApiError:
202 195
        vm.delete()
b/api/tests.py
694 694
            data = json.dumps({'metadata': {'Key1': 'A Value'}})
695 695
            response = self.client.post(path, data, content_type='application/json')
696 696
            self.assertItemNotFound(response)
697

  
698

  
699
class ServerVNCConsole(BaseTestCase):
700
    SERVERS = 1
701

  
702
    def test_not_active_server(self):
703
        """Test console req for server not in ACTIVE state returns badRequest"""
704
        server_id = choice(VirtualMachine.objects.all()).id
705
        path = '/api/v1.1/servers/%d/action' % server_id
706
        data = json.dumps({'console': {'type': 'vnc'}})
707
        response = self.client.post(path, data, content_type='application/json')
708
        self.assertBadRequest(response)
709

  
710
    def test_active_server(self):
711
        """Test console req for ACTIVE server"""
712
        server_id = choice(VirtualMachine.objects.all()).id
713
        # FIXME: Start the server properly, instead of tampering with the DB
714
        vm = choice(VirtualMachine.objects.all())
715
        vm.operstate = 'STARTED'
716
        vm.save()
717
        server_id = vm.id
718
	
719
        path = '/api/v1.1/servers/%d/action' % server_id
720
        data = json.dumps({'console': {'type': 'vnc'}})
721
        response = self.client.post(path, data, content_type='application/json')
722
        self.assertEqual(response.status_code, 200)
723
        reply = json.loads(response.content)
724
        self.assertEqual(reply.keys(), ['vnc'])
725
        self.assertEqual(set(reply['vnc'].keys()), set(['host', 'port', 'password']))
726

  
b/api/util.py
132 132
    else:
133 133
        response['Content-Type'] = 'application/json'
134 134
    
135
    if request.META.get('SERVER_NAME') == 'testserver':
135
    if settings.TEST:
136 136
        response['Date'] = format_date_time(time())
137 137

  
138 138
def render_metadata(request, metadata, use_values=False, status=200):
......
151 151
    return HttpResponse(data, status=status)
152 152

  
153 153
def render_fault(request, fault):
154
    if settings.DEBUG or request.META.get('SERVER_NAME') == 'testserver':
154
    if settings.DEBUG or settings.TEST:
155 155
        fault.details = format_exc(fault)
156 156
    
157 157
    if request.serialization == 'xml':
b/settings.py.dist
8 8
DEBUG = True
9 9
TEMPLATE_DEBUG = DEBUG
10 10

  
11
# A quick-n-dirty way to know if we're running unit tests
12
import sys
13
if len(sys.argv) >= 2:
14
    TEST = ('manage.py', 'test') == (os.path.basename(sys.argv[0]), sys.argv[1])
15
else:
16
    TEST = False
17

  
11 18
ADMINS = (
12 19
    # ('Your Name', 'your_email@domain.com'),
13 20
)
b/tools/cloud
82 82
        buf = resp.read() or '{}'
83 83
        reply = json.loads(buf)
84 84

  
85
        # If the response status is not the expected one,
86
        # assume an error has occured and treat the body
87
        # as a cloudfault.
85 88
        if resp.status != expected_status:
86 89
            if len(reply) == 1:
87 90
                key = reply.keys()[0]
......
241 244
    
242 245
    def execute(self, server_id):
243 246
        path = '/api/%s/servers/%d/action' % (self.api, int(server_id))
244
        body = json.dumps({'console':{'type':'VNC'}})
245
        reply = self.http_post(path, body)
246
        print_dict(reply)
247
        body = json.dumps({'console':{'type':'vnc'}})
248
        reply = self.http_cmd('POST', path, body, 200)
249
        print_dict(reply['vnc'])
247 250

  
248 251

  
249 252
@command_name('lsaddr')

Also available in: Unified diff