Merge lp:~verterok/ols-vms/lxd-5.0-support into lp:ols-vms

Proposed by Guillermo Gonzalez
Status: Merged
Approved by: Guillermo Gonzalez
Approved revision: 308
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: lp:~verterok/ols-vms/lxd-5.0-support
Merge into: lp:ols-vms
Diff against target: 274 lines (+147/-84)
2 files modified
olsvms/tests/test_lxd.py (+125/-49)
olsvms/vms/lxd.py (+22/-35)
To merge this branch: bzr merge lp:~verterok/ols-vms/lxd-5.0-support
Reviewer Review Type Date Requested Status
Wouter van Bommel (community) Approve
Review via email: mp+435163@code.launchpad.net

Commit message

Add support for lxc info output from LXD 5.0

To post a comment you must log in.
Revision history for this message
Wouter van Bommel (woutervb) wrote :

lgtm

review: Approve
Revision history for this message
Wouter van Bommel (woutervb) wrote :

Thanks the query rewrite is fancy

review: Approve
Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
lp:~verterok/ols-vms/lxd-5.0-support updated
308. By Guillermo Gonzalez

don't call lxd on the unittest

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'olsvms/tests/test_lxd.py'
2--- olsvms/tests/test_lxd.py 2017-03-15 16:25:51 +0000
3+++ olsvms/tests/test_lxd.py 2023-01-05 04:22:59 +0000
4@@ -39,70 +39,146 @@
5 class TestInfo(unittest.TestCase):
6
7 def test_unknown(self):
8- info = lxd.lxd_info('idontexist', '')
9+ info = lxd.lxd_info('idontexist', None, '["/1.0/instances/foo"]')
10 self.assertEqual('UNKNOWN', info['state'])
11
12 def test_running(self):
13 info = lxd.lxd_info('foo', '''
14-Name: foo
15-Architecture: x86_64
16-Created: 2016/03/23 09:35 UTC
17-Status: Running
18-Type: persistent
19-Profiles: default
20-Pid: 7821
21-Processes: 20
22-Ips:
23- eth0: inet 192.168.0.177 vethMBG5X5
24- eth0: inet6 fe80::216:3eff:fe1e:be0f vethMBG5X5
25- lo: inet 127.0.0.1
26- lo: inet6 ::1
27- lxcbr0: inet 10.0.3.1
28- lxcbr0: inet6 fe80::1833:eff:fe84:a812
29-Resources:
30- Processes: 18
31- Disk usage:
32- root: 11.24MB
33- Memory usage:
34- Memory (current): 77.34MB
35- Memory (peak): 200.96MB
36- Network usage:
37- eth0:
38- Bytes received: 130.75kB
39- Bytes sent: 1.30kB
40- Packets received: 885
41- Packets sent: 885
42- lo:
43- Bytes received: 1.22kB
44- Bytes sent: 1.22kB
45- Packets received: 16
46- Packets sent: 16
47- lxcbr0:
48- Bytes received: 0 bytes
49- Bytes sent: 570 bytes
50- Packets received: 0
51- Packets sent: 0
52+{
53+ "cpu": {
54+ "usage": 4929337284
55+ },
56+ "disk": {},
57+ "memory": {
58+ "swap_usage": 0,
59+ "swap_usage_peak": 0,
60+ "usage": 54198272,
61+ "usage_peak": 259719168
62+ },
63+ "network": {
64+ "eth0": {
65+ "addresses": [
66+ {
67+ "address": "10.124.1.54",
68+ "family": "inet",
69+ "netmask": "24",
70+ "scope": "global"
71+ },
72+ {
73+ "address": "fd42:afef:e136:6ac3:216:3eff:fe47:971c",
74+ "family": "inet6",
75+ "netmask": "64",
76+ "scope": "global"
77+ },
78+ {
79+ "address": "fe80::216:3eff:fe47:971c",
80+ "family": "inet6",
81+ "netmask": "64",
82+ "scope": "link"
83+ }
84+ ],
85+ "counters": {
86+ "bytes_received": 240027,
87+ "bytes_sent": 9156,
88+ "errors_received": 0,
89+ "errors_sent": 0,
90+ "packets_dropped_inbound": 0,
91+ "packets_dropped_outbound": 0,
92+ "packets_received": 147,
93+ "packets_sent": 101
94+ },
95+ "host_name": "veth72615c2e",
96+ "hwaddr": "00:16:3e:47:97:1c",
97+ "mtu": 1500,
98+ "state": "up",
99+ "type": "broadcast"
100+ },
101+ "lo": {
102+ "addresses": [
103+ {
104+ "address": "127.0.0.1",
105+ "family": "inet",
106+ "netmask": "8",
107+ "scope": "local"
108+ },
109+ {
110+ "address": "::1",
111+ "family": "inet6",
112+ "netmask": "128",
113+ "scope": "local"
114+ }
115+ ],
116+ "counters": {
117+ "bytes_received": 0,
118+ "bytes_sent": 0,
119+ "errors_received": 0,
120+ "errors_sent": 0,
121+ "packets_dropped_inbound": 0,
122+ "packets_dropped_outbound": 0,
123+ "packets_received": 0,
124+ "packets_sent": 0
125+ },
126+ "host_name": "",
127+ "hwaddr": "",
128+ "mtu": 65536,
129+ "state": "up",
130+ "type": "loopback"
131+ }
132+ },
133+ "pid": 3832,
134+ "processes": 23,
135+ "status": "Running",
136+ "status_code": 103
137+}
138 ''')
139 self.assertEqual('RUNNING', info['state'])
140- self.assertEqual('7821', info['pid'])
141- self.assertEqual('192.168.0.177', info['ip'])
142+ self.assertEqual('3832', info['pid'])
143+ self.assertEqual('10.124.1.54', info['ip'])
144
145 def test_stopped(self):
146 info = lxd.lxd_info('foo', '''
147-Name: foo
148-Status: Stopped
149+{
150+ "cpu": {
151+ "usage": 0
152+ },
153+ "disk": {},
154+ "memory": {
155+ "swap_usage": 0,
156+ "swap_usage_peak": 0,
157+ "usage": 0,
158+ "usage_peak": 0
159+ },
160+ "network": null,
161+ "pid": 0,
162+ "processes": 0,
163+ "status": "Stopped",
164+ "status_code": 102
165+}
166 ''')
167- self.assertEqual({'state': 'STOPPED'}, info)
168+ self.assertEqual({'state': 'STOPPED', 'pid': '0'}, info)
169
170 def test_no_ips(self):
171 # Before ips are set
172 info = lxd.lxd_info('foo', '''
173-Name: foo
174-Status: Running
175-Ips:
176-(none)
177+{
178+ "cpu": {
179+ "usage": 0
180+ },
181+ "disk": {},
182+ "memory": {
183+ "swap_usage": 0,
184+ "swap_usage_peak": 0,
185+ "usage": 0,
186+ "usage_peak": 0
187+ },
188+ "network": {"eth0": {"addresses": []}},
189+ "pid": 123,
190+ "processes": 0,
191+ "status": "Running",
192+ "status_code": 102
193+}
194 ''')
195- self.assertEqual({'state': 'RUNNING'}, info)
196+ self.assertEqual({'state': 'RUNNING', 'pid': '123'}, info)
197 self.assertFalse('ip' in info)
198
199
200
201=== modified file 'olsvms/vms/lxd.py'
202--- olsvms/vms/lxd.py 2022-05-18 14:50:10 +0000
203+++ olsvms/vms/lxd.py 2023-01-05 04:22:59 +0000
204@@ -16,6 +16,7 @@
205 from __future__ import unicode_literals
206
207 import hashlib
208+import json
209 import logging
210 import os
211 import time
212@@ -80,43 +81,29 @@
213 return root and lxd
214
215
216-def lxd_info(vm_name, source=None):
217+def lxd_info(vm_name, source=None, list_source=None):
218 info = dict(state='UNKNOWN')
219 if source is None:
220- info_command = ['lxc', 'info', vm_name]
221- try:
222- _, source, err = subprocesses.run(info_command)
223- except errors.CommandError as e:
224- if e.err.lower() in ('error: not found\n',):
225- return info
226- else:
227- raise
228- scanning_ips = False
229- for l in source.splitlines():
230- if l.startswith('Resources:'):
231- # Nothing for us from there
232- break
233- elif scanning_ips:
234- if l == '(none)':
235- # interfaces are not setup yet
236- continue
237- details = l.split('\t')
238- try:
239- ifce, proto, ip = details[0:3]
240- ifce = ifce[0:-1].strip()
241- except ValueError:
242- raise ValueError('Unexpected IP line: {}'.format(l))
243- # FIXME: Assume eth0 until we can do better -- vila 2015-12-22
244- if 'eth0' in ifce and proto == 'inet':
245- info['ip'] = ip
246- elif l.startswith('Status:'):
247- _, s = l.split()
248- info['state'] = s.upper()
249- elif l.startswith('Pid:'):
250- _, pid = l.split()
251- info['pid'] = pid
252- elif l.startswith('Ips:'):
253- scanning_ips = True
254+ if list_source is None:
255+ list_command = ['lxc', 'query', '/1.0/instances']
256+ list_source = subprocesses.run(list_command)[1]
257+ instance_list = json.loads(list_source)
258+ if '/1.0/instances/{}'.format(vm_name) not in instance_list:
259+ return info
260+ query_command = [
261+ 'lxc', 'query', '/1.0/instances/{}/state'.format(vm_name)
262+ ]
263+ source = subprocesses.run(query_command)[1]
264+ state = json.loads(source)
265+ info['state'] = state['status'].upper()
266+ info['pid'] = str(state['pid'])
267+ # FIXME: Assume eth0 until we can do better -- verterok 2023-01-05
268+ if state.get('network'):
269+ addresses = state['network'].get('eth0', {}).get('addresses', [])
270+ for addr in addresses:
271+ if addr['family'] == 'inet':
272+ info['ip'] = addr['address']
273+ break
274 return info
275
276

Subscribers

People subscribed via source and target branches