Merge lp:~freyes/maas-deployer/lp1570218 into lp:~maas-deployers/maas-deployer/next

Proposed by Felipe Reyes
Status: Merged
Merged at revision: 77
Proposed branch: lp:~freyes/maas-deployer/lp1570218
Merge into: lp:~maas-deployers/maas-deployer/next
Diff against target: 276 lines (+81/-33)
6 files modified
examples/deployment.yaml (+2/-2)
maas_deployer/tests/test_vm.py (+51/-6)
maas_deployer/vmaas/engine.py (+1/-1)
maas_deployer/vmaas/templates/cloud-init.cfg (+1/-1)
maas_deployer/vmaas/util.py (+3/-2)
maas_deployer/vmaas/vm.py (+23/-21)
To merge this branch: bzr merge lp:~freyes/maas-deployer/lp1570218
Reviewer Review Type Date Requested Status
Billy Olsen Approve
Edward Hope-Morley Needs Fixing
Review via email: mp+301726@code.launchpad.net

Description of the change

Split 'arch' into 'build_arch' and 'kernel_arch'

This allows to make a clear differentiation what's the expected 'arch'
in libvirt (kernel arch) versus the 'arch' expected by MAAS (build arch).

So users can define the arch in deployment.yaml as 'ppc64el' or 'pp64' and get a functional deployment, as the juju/maas vms will be launched using 'ppc64' and using the ubuntu ppc64el cloud image.

To post a comment you must log in.
lp:~freyes/maas-deployer/lp1570218 updated
79. By Felipe Reyes

Mock virsh

Revision history for this message
Felipe Reyes (freyes) wrote :

A user with access to a power8 machine is testing this patch (available at https://launchpad.net/~freyes/+archive/ubuntu/lp1570218 )

Revision history for this message
Edward Hope-Morley (hopem) :
review: Needs Fixing
Revision history for this message
Felipe Reyes (freyes) :
lp:~freyes/maas-deployer/lp1570218 updated
80. By Felipe Reyes

Fix command line parsing

Revision history for this message
Felipe Reyes (freyes) wrote :
Revision history for this message
Billy Olsen (billy-olsen) wrote :

LGTM, thanks Felipe!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/deployment.yaml'
2--- examples/deployment.yaml 2016-04-27 12:53:58 +0000
3+++ examples/deployment.yaml 2016-08-19 13:25:54 +0000
4@@ -8,7 +8,7 @@
5 interfaces: ['bridge=virbr0,model=virtio']
6 memory: 2048
7 vcpus: 2
8- arch: amd64
9+ arch: amd64 # build arch
10 pool: default
11 disk_size: 20G
12 sticky_ip_address:
13@@ -29,7 +29,7 @@
14 interfaces: ['bridge=virbr0,model=virtio']
15 memory: 4096
16 vcpus: 2
17- arch: amd64
18+ arch: amd64 # build arch
19 pool: default
20 disk_size: 60G
21 #release: trusty
22
23=== modified file 'maas_deployer/tests/test_vm.py'
24--- maas_deployer/tests/test_vm.py 2015-09-11 10:09:16 +0000
25+++ maas_deployer/tests/test_vm.py 2016-08-19 13:25:54 +0000
26@@ -3,8 +3,10 @@
27 #
28
29 import unittest
30+
31+import mock
32+
33 from maas_deployer.vmaas import vm
34-from mock import patch, MagicMock
35
36
37 VIRSH_LIST_ALL = """
38@@ -15,15 +17,20 @@
39 - juju-boot-vm-dc1 shut off
40 - fooX shut off
41 """
42+VIRSH_POOL_LIST = """ Name State Autostart
43+-------------------------------------------
44+ default active yes
45+ uvtool active yes
46+""" # noqa
47
48
49 class TestVM(unittest.TestCase):
50
51- @patch.object(vm, 'log', MagicMock())
52- @patch.object(vm.Instance, 'assert_pool_exists', lambda *args: None)
53- @patch.object(vm, 'cfg')
54- @patch.object(vm, 'virsh')
55- @patch.object(vm.libvirt, 'open', lambda *args: None)
56+ @mock.patch.object(vm, 'log', mock.MagicMock())
57+ @mock.patch.object(vm.Instance, 'assert_pool_exists', lambda *args: None)
58+ @mock.patch.object(vm, 'cfg')
59+ @mock.patch.object(vm, 'virsh')
60+ @mock.patch.object(vm.libvirt, 'open', lambda *args: None)
61 def test_instance_domain_exists(self, mock_virsh, mock_cfg):
62 mock_cfg.use_existing = False
63 mock_cfg.remote = None
64@@ -36,3 +43,41 @@
65 inst = vm.Instance({})
66 self.assertFalse(inst._domain_exists('foo'))
67 self.assertTrue(inst._domain_exists('fooX'))
68+
69+
70+@mock.patch.object(vm, 'virsh')
71+@mock.patch('libvirt.open')
72+class TestInstance(unittest.TestCase):
73+ def setUp(self):
74+ self.INSTANCE_PARAMS = {
75+ 'name': 'foo',
76+ 'interfaces': ['bridge=virbr0,model=virtio'],
77+ 'memory': 2048,
78+ 'vcpus': 2,
79+ 'arch': 'amd64',
80+ 'pool': 'default',
81+ 'disk_size': '20G',
82+ }
83+ setattr(vm.cfg, 'remote', 'qemu:///system')
84+
85+ def test_instance_arch(self, libvirt_open, virsh):
86+ virsh.return_value = (VIRSH_POOL_LIST, 0)
87+ instance = vm.Instance(self.INSTANCE_PARAMS)
88+
89+ self.assertEqual(instance.kernel_arch, 'x86_64')
90+
91+ def test_instance_pp64(self, libvirt_open, virsh):
92+ virsh.return_value = (VIRSH_POOL_LIST, 0)
93+ self.INSTANCE_PARAMS['arch'] = 'ppc64'
94+ instance = vm.Instance(self.INSTANCE_PARAMS)
95+
96+ self.assertEqual(instance.build_arch, 'ppc64el')
97+ self.assertEqual(instance.kernel_arch, 'ppc64')
98+
99+ def test_instance_pp64el(self, libvirt_open, virsh):
100+ virsh.return_value = (VIRSH_POOL_LIST, 0)
101+ self.INSTANCE_PARAMS['arch'] = 'ppc64el'
102+ instance = vm.Instance(self.INSTANCE_PARAMS)
103+
104+ self.assertEqual(instance.build_arch, 'ppc64el')
105+ self.assertEqual(instance.kernel_arch, 'ppc64')
106
107=== modified file 'maas_deployer/vmaas/engine.py'
108--- maas_deployer/vmaas/engine.py 2016-08-01 20:02:22 +0000
109+++ maas_deployer/vmaas/engine.py 2016-08-19 13:25:54 +0000
110@@ -88,7 +88,7 @@
111 """
112 node = {
113 'name': juju_domain.name,
114- 'architecture': juju_config.get('arch'),
115+ 'architecture': juju_domain.build_arch,
116 'mac_addresses': [x for x in juju_domain.mac_addresses],
117 'tags': 'bootstrap'
118 }
119
120=== modified file 'maas_deployer/vmaas/templates/cloud-init.cfg'
121--- maas_deployer/vmaas/templates/cloud-init.cfg 2016-03-31 17:31:45 +0000
122+++ maas_deployer/vmaas/templates/cloud-init.cfg 2016-08-19 13:25:54 +0000
123@@ -44,7 +44,7 @@
124 # Used to manage KVM instances via libvirt
125 - libvirt-bin
126 # Below package does not exist on Power8 architecture.
127-{%- if arch != 'ppc64' %}
128+{%- if arch != 'ppc64el' %}
129 - linux-image-extra-virtual
130 {% endif %}
131 - jq
132
133=== modified file 'maas_deployer/vmaas/util.py'
134--- maas_deployer/vmaas/util.py 2016-04-27 19:41:53 +0000
135+++ maas_deployer/vmaas/util.py 2016-08-19 13:25:54 +0000
136@@ -9,6 +9,7 @@
137 import logging
138 import os
139 import subprocess
140+import sys
141 import time
142
143 log = logging.getLogger('vmaas.main')
144@@ -202,8 +203,8 @@
145 raise AttributeError("%r object has no attribute %r" %
146 (self.__class__, attr))
147
148- def parse_args(self):
149- self._args = self._parser.parse_args()
150+ def parse_args(self, argv=None):
151+ self._args = self._parser.parse_args(argv)
152
153 @property
154 def args(self):
155
156=== modified file 'maas_deployer/vmaas/vm.py'
157--- maas_deployer/vmaas/vm.py 2016-04-27 19:41:53 +0000
158+++ maas_deployer/vmaas/vm.py 2016-08-19 13:25:54 +0000
159@@ -34,6 +34,8 @@
160
161
162 log = logging.getLogger('vmaas.main')
163+ARCH_BUILD_TO_KERNEL = {'ppc64el': 'ppc64',
164+ 'amd64': 'x86_64'}
165
166
167 class Instance(object):
168@@ -41,7 +43,17 @@
169 def __init__(self, params, autostart=False):
170 self.name = params.get('name')
171 self.interfaces = params.get('interfaces')
172- self.arch = params.get('arch', 'amd64')
173+ self.build_arch = params.get('arch', 'amd64')
174+
175+ if self.build_arch == 'ppc64':
176+ # see LP: #1570218
177+ log.warning(("`arch' should be the build arch instead of the "
178+ "architecture expected by the kernel. Using `ppc64el'"
179+ "instead of `ppc64'"))
180+ self.build_arch = 'ppc64el'
181+
182+ self.kernel_arch = ARCH_BUILD_TO_KERNEL.get(self.build_arch,
183+ self.build_arch)
184 self.disk_size = params.get('disk_size', '20G')
185 self.vcpus = params.get('vcpus', 1)
186 self.memory = params.get('memory', 1024)
187@@ -128,18 +140,13 @@
188 create the domain.
189 """
190
191- # NOTE: virt-install appears to prefer x86_64 over amd64
192- arch = self.arch
193- if arch == 'amd64':
194- arch = 'x86_64'
195-
196 cmd = ['virt-install',
197 '--connect', cfg.remote,
198 '--name', self.name,
199 '--ram', str(self.memory),
200 '--vcpus', str(self.vcpus),
201 '--video', str(self.video),
202- '--arch', str(arch)]
203+ '--arch', str(self.kernel_arch)]
204
205 for disk in self._get_disks():
206 cmd.extend(['--disk', disk])
207@@ -298,7 +305,6 @@
208 super(CloudInstance, self).__init__(params, autostart)
209 self.name = params.get('name')
210 self.interfaces = params.get('interfaces')
211- self.arch = params.get('arch', 'amd64')
212 self.disk_size = params.get('disk_size', '40G')
213 self.vcpus = params.get('vcpus', 2)
214 self.memory = params.get('memory', 4096)
215@@ -316,14 +322,10 @@
216 Returns a tuple with the cloud-image url and the file it
217 should be saved as.
218 """
219- if self.arch == "ppc64":
220- url = ('https://cloud-images.ubuntu.com/{release}/current/'
221- '{release}-server-cloudimg-{arch}el-disk1.img')
222- else:
223- url = ('https://cloud-images.ubuntu.com/{release}/current/'
224- '{release}-server-cloudimg-{arch}-disk1.img')
225+ url = ('https://cloud-images.ubuntu.com/{release}/current/'
226+ '{release}-server-cloudimg-{arch}-disk1.img')
227
228- url = url.format(release=self.release, arch=self.arch)
229+ url = url.format(release=self.release, arch=self.build_arch)
230 f = url.split('/')[-1]
231 return (url, f)
232
233@@ -394,7 +396,7 @@
234 """
235 storage_pool = self.conn.storagePoolLookupByName(self.pool)
236 existing_vols = [v.name() for v in storage_pool.listAllVolumes()]
237- basevol = "%s-%s-base" % (self.release, self.arch)
238+ basevol = "%s-%s-base" % (self.release, self.build_arch)
239 self._create_base_volume(basevol, existing_vols)
240 root_img_name = '{}-root.img'.format(self.name)
241 self._create_root_volume(root_img_name, basevol, existing_vols,
242@@ -457,7 +459,7 @@
243 etc_net_interfaces = ["%s%s" % (indent, l.rstrip()) for l in
244 etc_net_interfaces]
245
246- parms = {
247+ params = {
248 'hostname': self.name,
249 'user': self.user,
250 'password': self.password,
251@@ -465,21 +467,21 @@
252 'apt_http_proxy': self.apt_http_proxy,
253 'apt_sources': self.apt_sources,
254 'network_config': '\n'.join(etc_net_interfaces),
255- 'arch': self.arch
256+ 'arch': self.build_arch
257 }
258- content = template.load('cloud-init.cfg', parms)
259+ content = template.load('cloud-init.cfg', params)
260 with open(base_file, 'w+') as f:
261 f.write(content)
262 f.flush()
263
264 # Generate the script file...
265 config_maas_script = os.path.join(self.working_dir, 'config-maas.sh')
266- parms = {
267+ params = {
268 'user': self.user,
269 'password': self.password,
270 'node_group_ifaces': self.node_group_ifaces,
271 }
272- content = template.load('config-maas.sh', parms)
273+ content = template.load('config-maas.sh', params)
274 with open(config_maas_script, 'w+') as f:
275 f.write(content)
276 f.flush()

Subscribers

People subscribed via source and target branches