290ecbd62e6e3cd2b6d845727c3940d2be0076b1
[armband.git] / patches / opnfv-fuel / 0002-salt-formulas-Add-enable-armband-formula.patch
1 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2 : Copyright (c) 2017 Enea AB and others.
3 :
4 : All rights reserved. This program and the accompanying materials
5 : are made available under the terms of the Apache License, Version 2.0
6 : which accompanies this distribution, and is available at
7 : http://www.apache.org/licenses/LICENSE-2.0
8 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
9 From: Guillermo Herrero <Guillermo.Herrero@enea.com>
10 Date: Tue, 25 Jul 2017 00:58:32 +0200
11 Subject: [PATCH] salt-formulas: Add & enable armband formula
12
13 - prereq: install qemu-efi;
14 - prereq: install vgabios;
15 - prereq: fix missing link for vgabios binary blob;
16 - nova patch: Support qemu >= 2.10 (backport from [1]);
17 - nova patch: Add video type virtio for AArch64 (backport from [2]);
18 - nova patch: libvirt driver: Add ttyAMA0 by default on AArch64;
19 - nova patch: libvirt driver: AArch64: ACPI depends on AAVMF;
20 - nova conf: cpu_model=cortex-a57 (only for virtual deploys);
21 - nova conf: virt_type=qemu (only for virtual deploys);
22 - nova conf: pointer_model=ps2mouse since AArch64 has no USB tablet;
23
24 [1] https://github.com/openstack/nova/commit/8075797
25 [2] https://github.com/openstack/nova/commit/f0f0953
26
27 Signed-off-by: Guillermo Herrero <Guillermo.Herrero@enea.com>
28 Signed-off-by: Charalampos Kominos <Charalampos.Kominos@enea.com>
29 Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
30 ---
31  mcp/config/states/openstack                        |   2 +
32  mcp/config/states/openstack_ha                     |   1 +
33  mcp/config/states/virtual_control_plane            |   1 +
34  .../armband/files/nova-libvirt-aarch64-rollup.diff | 317 +++++++++++++++++++++
35  mcp/salt-formulas/armband/init.sls                 |   7 +
36  mcp/salt-formulas/armband/nova_config.sls          |  30 ++
37  mcp/salt-formulas/armband/nova_libvirt.sls         |   7 +
38  mcp/salt-formulas/armband/qemu_efi.sls             |   2 +
39  mcp/salt-formulas/armband/vgabios.sls              |   7 +
40  9 files changed, 374 insertions(+)
41  create mode 100644 mcp/salt-formulas/armband/files/nova-libvirt-aarch64-rollup.diff
42  create mode 100644 mcp/salt-formulas/armband/init.sls
43  create mode 100644 mcp/salt-formulas/armband/nova_config.sls
44  create mode 100644 mcp/salt-formulas/armband/nova_libvirt.sls
45  create mode 100644 mcp/salt-formulas/armband/qemu_efi.sls
46  create mode 100644 mcp/salt-formulas/armband/vgabios.sls
47
48 diff --git a/mcp/config/states/openstack b/mcp/config/states/openstack
49 index 369e165..d2a0b63 100755
50 --- a/mcp/config/states/openstack
51 +++ b/mcp/config/states/openstack
52 @@ -47,3 +47,5 @@ salt -I 'ceilometer:server' state.sls ceilometer
53  salt -I 'ceilometer:agent' state.sls ceilometer
54
55  salt -I 'horizon:server' state.sls horizon
56 +
57 +salt -I 'nova:compute' state.sls armband || true
58 diff --git a/mcp/config/states/openstack_ha b/mcp/config/states/openstack_ha
59 index fbddc6e..6bad8da 100755
60 --- a/mcp/config/states/openstack_ha
61 +++ b/mcp/config/states/openstack_ha
62 @@ -52,6 +52,7 @@ salt -I 'neutron:server' state.sls neutron -b 1
63  salt -I 'neutron:gateway' state.sls neutron.gateway
64
65  salt -I 'nova:compute' state.sls nova
66 +salt -I 'nova:compute' state.sls armband || true
67
68  salt -I 'mongodb:server' state.sls mongodb || true
69  wait_for 90 "salt -C 'I@mongodb:server and *01*' cmd.run 'mongo localhost:27017/admin'"
70 diff --git a/mcp/config/states/virtual_control_plane b/mcp/config/states/virtual_control_plane
71 index c355126..99fb517 100755
72 --- a/mcp/config/states/virtual_control_plane
73 +++ b/mcp/config/states/virtual_control_plane
74 @@ -46,6 +46,7 @@ wait_for 90 "! salt -C 'kvm* or cmp*' test.ping | " \
75
76  salt -C '* and not cfg01* and not mas01*' state.apply linux,ntp
77
78 +salt -C 'kvm*' state.sls armband || true
79  wait_for 5 "salt -C 'kvm*' state.sls libvirt"
80
81  salt -C '* and not cfg01* and not mas01*' state.apply salt
82 diff --git a/mcp/salt-formulas/armband/files/nova-libvirt-aarch64-rollup.diff b/mcp/salt-formulas/armband/files/nova-libvirt-aarch64-rollup.diff
83 new file mode 100644
84 index 0000000..4d7f04c
85 --- /dev/null
86 +++ b/mcp/salt-formulas/armband/files/nova-libvirt-aarch64-rollup.diff
87 @@ -0,0 +1,317 @@
88 +From 807579755c4a116309eca5b2bcdbab9d1f393bab Mon Sep 17 00:00:00 2001
89 +From: Matt Riedemann <mriedem.os@gmail.com>
90 +Date: Wed, 20 Sep 2017 10:44:11 -0400
91 +Subject: [PATCH] Support qemu >= 2.10
92 +
93 +Qemu 2.10 added the requirement of a --force-share flag to qemu-img
94 +info when reading information about a disk that is in use by a
95 +guest. We do this a lot in Nova for operations like gathering
96 +information before live migration.
97 +
98 +Up until this point all qemu/libvirt version matching has been solely
99 +inside the libvirt driver, however all the image manip code was moved
100 +out to nova.virt.images. We need the version of QEMU available there.
101 +
102 +This does it by initializing that version on driver init host. The net
103 +effect is also that broken libvirt connections are figured out
104 +earlier, as there is an active probe for this value.
105 +
106 +Co-Authored-By: Sean Dague <sean@dague.net>
107 +
108 +[ Alexandru.Avadanii@enea.com ]
109 +Minor patch adjustment to apply cleanly on Newton without further
110 +backporting.
111 +
112 +Change-Id: Iae2962bb86100f03fd3ad9aac3767da876291e74
113 +Closes-Bug: #1718295
114 +
115 +Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
116 +---
117 + nova/test.py                                |  3 +++
118 + nova/tests/unit/virt/libvirt/test_driver.py | 20 ++++++++++++++++++--
119 + nova/tests/unit/virt/libvirt/test_utils.py  | 25 +++++++++++++++++++++++++
120 + nova/virt/images.py                         | 10 ++++++++++
121 + nova/virt/libvirt/driver.py                 | 14 +++++++++-----
122 + 5 files changed, 65 insertions(+), 7 deletions(-)
123 +
124 +diff --git a/nova/test.py b/nova/test.py
125 +index f0e6953b965..9b9ea9507e8 100644
126 +--- a/nova/test.py
127 ++++ b/nova/test.py
128 +@@ -61,6 +61,7 @@
129 + from nova.tests.unit import policy_fixture
130 + from nova.tests import uuidsentinel as uuids
131 + from nova import utils
132 ++from nova.virt import images
133 +
134 +
135 + CONF = cfg.CONF
136 +@@ -303,6 +304,8 @@ def setUp(self):
137 +         # nova.utils._IS_NEUTRON.  We set it to None to avoid any
138 +         # caching of that value.
139 +         utils._IS_NEUTRON = None
140 ++        # Reset the global QEMU version flag.
141 ++        images.QEMU_VERSION = None
142 +
143 +         mox_fixture = self.useFixture(moxstubout.MoxStubout())
144 +         self.mox = mox_fixture.mox
145 +diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py
146 +index fe54dc75e7f..4e9f2bd250e 100644
147 +--- a/nova/tests/unit/virt/libvirt/test_driver.py
148 ++++ b/nova/tests/unit/virt/libvirt/test_driver.py
149 +@@ -986,6 +986,23 @@ def test_next_min_qemu_version_ok(self, mock_warning, mock_get_libversion):
150 +                 break
151 +         self.assertFalse(version_arg_found)
152 +
153 ++    # NOTE(sdague): python2.7 and python3.5 have different behaviors
154 ++    # when it comes to comparing against the sentinel, so
155 ++    # has_min_version is needed to pass python3.5.
156 ++    @mock.patch.object(nova.virt.libvirt.host.Host, "has_min_version",
157 ++                       return_value=True)
158 ++    @mock.patch.object(fakelibvirt.Connection, 'getVersion',
159 ++                       return_value=mock.sentinel.qemu_version)
160 ++    def test_qemu_image_version(self, mock_get_libversion, min_ver):
161 ++        """Test that init_host sets qemu image version
162 ++
163 ++        A sentinel is used here so that we aren't chasing this value
164 ++        against minimums that get raised over time.
165 ++        """
166 ++        drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
167 ++        drvr.init_host("dummyhost")
168 ++        self.assertEqual(images.QEMU_VERSION, mock.sentinel.qemu_version)
169 ++
170 +     @mock.patch.object(fakelibvirt.Connection, 'getLibVersion',
171 +                        return_value=versionutils.convert_version_to_int(
172 +                            libvirt_driver.MIN_LIBVIRT_OTHER_ARCH.get(
173 +@@ -11605,9 +11622,8 @@ def test_command_with_broken_connection(self):
174 +                               return_value=service_mock),
175 +             mock.patch.object(host.Host, "get_capabilities")):
176 +
177 +-            drvr.init_host("wibble")
178 +             self.assertRaises(exception.HypervisorUnavailable,
179 +-                              drvr.get_num_instances)
180 ++                              drvr.init_host, ("wibble",))
181 +             self.assertTrue(service_mock.disabled)
182 +
183 +     def test_service_resume_after_broken_connection(self):
184 +diff --git a/nova/tests/unit/virt/libvirt/test_utils.py b/nova/tests/unit/virt/libvirt/test_utils.py
185 +index 646a72c8599..49945a3cd3b 100644
186 +--- a/nova/tests/unit/virt/libvirt/test_utils.py
187 ++++ b/nova/tests/unit/virt/libvirt/test_utils.py
188 +@@ -173,6 +173,31 @@ def test_qemu_info_canon(self, mock_execute, mock_exists):
189 +
190 +     @mock.patch('os.path.exists', return_value=True)
191 +     @mock.patch('nova.utils.execute')
192 ++    def test_qemu_info_canon_qemu_2_10(self, mock_execute, mock_exists):
193 ++        images.QEMU_VERSION = images.QEMU_VERSION_REQ_SHARED
194 ++        path = "disk.config"
195 ++        example_output = """image: disk.config
196 ++file format: raw
197 ++virtual size: 64M (67108864 bytes)
198 ++cluster_size: 65536
199 ++disk size: 96K
200 ++blah BLAH: bb
201 ++"""
202 ++        mock_execute.return_value = (example_output, '')
203 ++        image_info = images.qemu_img_info(path)
204 ++        mock_execute.assert_called_once_with('env', 'LC_ALL=C', 'LANG=C',
205 ++                                             'qemu-img', 'info', path,
206 ++                                             '--force-share',
207 ++                                             prlimit=images.QEMU_IMG_LIMITS)
208 ++        mock_exists.assert_called_once_with(path)
209 ++        self.assertEqual('disk.config', image_info.image)
210 ++        self.assertEqual('raw', image_info.file_format)
211 ++        self.assertEqual(67108864, image_info.virtual_size)
212 ++        self.assertEqual(98304, image_info.disk_size)
213 ++        self.assertEqual(65536, image_info.cluster_size)
214 ++
215 ++    @mock.patch('os.path.exists', return_value=True)
216 ++    @mock.patch('nova.utils.execute')
217 +     def test_qemu_info_canon2(self, mock_execute, mock_exists):
218 +         path = "disk.config"
219 +         example_output = """image: disk.config
220 +diff --git a/nova/virt/images.py b/nova/virt/images.py
221 +index dae6bc7ef52..be2a9d9e062 100644
222 +--- a/nova/virt/images.py
223 ++++ b/nova/virt/images.py
224 +@@ -19,6 +19,7 @@
225 + Handling of VM disk images.
226 + """
227 +
228 ++import operator
229 + import os
230 +
231 + from oslo_concurrency import processutils
232 +@@ -42,6 +43,11 @@
233 +     cpu_time=8,
234 +     address_space=1 * units.Gi)
235 +
236 ++# This is set by the libvirt driver on startup. The version is used to
237 ++# determine what flags need to be set on the command line.
238 ++QEMU_VERSION = None
239 ++QEMU_VERSION_REQ_SHARED = 2010000
240 ++
241 +
242 + def qemu_img_info(path, format=None):
243 +     """Return an object containing the parsed output from qemu-img info."""
244 +@@ -60,6 +66,10 @@ def qemu_img_info(path, format=None):
245 +         cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
246 +         if format is not None:
247 +             cmd = cmd + ('-f', format)
248 ++        # Check to see if the qemu version is >= 2.10 because if so, we need
249 ++        # to add the --force-share flag.
250 ++        if QEMU_VERSION and operator.ge(QEMU_VERSION, QEMU_VERSION_REQ_SHARED):
251 ++            cmd = cmd + ('--force-share',)
252 +         out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
253 +     except processutils.ProcessExecutionError as exp:
254 +         # this means we hit prlimits, make the exception more specific
255 +diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
256 +index 82dc2b99f6a..8d4eb90ecf5 100644
257 +--- a/nova/virt/libvirt/driver.py
258 ++++ b/nova/virt/libvirt/driver.py
259 +@@ -481,11 +481,15 @@ def init_host(self, host):
260 +                 _('Nova requires libvirt version %s or greater.') %
261 +                 self._version_to_string(MIN_LIBVIRT_VERSION))
262 +
263 +-        if (CONF.libvirt.virt_type in ("qemu", "kvm") and
264 +-            not self._host.has_min_version(hv_ver=MIN_QEMU_VERSION)):
265 +-            raise exception.InternalError(
266 +-                _('Nova requires QEMU version %s or greater.') %
267 +-                self._version_to_string(MIN_QEMU_VERSION))
268 ++        if CONF.libvirt.virt_type in ("qemu", "kvm"):
269 ++            if self._host.has_min_version(hv_ver=MIN_QEMU_VERSION):
270 ++                # "qemu-img info" calls are version dependent, so we need to
271 ++                # store the version in the images module.
272 ++                images.QEMU_VERSION = self._host.get_connection().getVersion()
273 ++            else:
274 ++                raise exception.InternalError(
275 ++                    _('Nova requires QEMU version %s or greater.') %
276 ++                    self._version_to_string(MIN_QEMU_VERSION))
277 +
278 +         if CONF.libvirt.virt_type == 'parallels':
279 +             if not self._host.has_min_version(hv_ver=MIN_VIRTUOZZO_VERSION):
280 +--
281 +
282 +From: Stanislaw Kardach <stanislaw.kardach@cavium.com>
283 +Date: Tue, 22 Mar 2016 12:05:09 +0100
284 +Subject: [PATCH] nova: Update console defaults for armv7, aarch64
285 +
286 +Nova hardcodes default options for serial console.
287 +For armv7 and aarch64 direct kernel boot, adding console=ttyAMA0 is
288 +a nice UX addition.
289 +
290 +Signed-off-by: Stanislaw Kardach <stanislaw.kardach@cavium.com>
291 +Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
292 +Signed-off-by: Guillermo Herrero <Guillermo.Herrero@enea.com>
293 +
294 +---
295 +
296 +diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
297 +--- a/nova/virt/libvirt/driver.py
298 ++++ b/nova/virt/libvirt/driver.py
299 +@@ -4179,7 +4179,12 @@ class LibvirtDriver(driver.ComputeDriver):
300 +         if virt_type == "xen":
301 +             guest.os_cmdline = "ro root=%s" % root_device_name
302 +         else:
303 ++            guestarch = libvirt_utils.get_arch(image_meta)
304 +             guest.os_cmdline = ("root=%s %s" % (root_device_name, CONSOLE))
305 ++            if guestarch in (fields.Architecture.ARMV7,
306 ++                             fields.Architecture.AARCH64):
307 ++                # NOTE(armband): ARM v7/v8 use PL011 drv, add ttyAMA0 console
308 ++                guest.os_cmdline += " console=ttyAMA0"
309 +             if virt_type == "qemu":
310 +                 guest.os_cmdline += " no_timer_check"
311 +         if instance.ramdisk_id:
312 +--
313 +
314 +From: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
315 +Date: Thu, 24 Aug 2017 10:57:28 +0200
316 +Subject: [PATCH] libvirt: AArch64: ACPI depends on AAVMF
317 +
318 +On AArch64, ACPI should be added to domain XML only if guest UEFI
319 +(AAVMF) is also used.
320 +
321 +Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
322 +Signed-off-by: Ciprian Barbu <ciprian.barbu@enea.com>
323 +
324 +---
325 +
326 +diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
327 +--- a/nova/virt/libvirt/driver.py
328 ++++ b/nova/virt/libvirt/driver.py
329 +@@ -4255,7 +4255,7 @@
330 +             tmhyperv.present = True
331 +             clk.add_timer(tmhyperv)
332 +
333 +-    def _set_features(self, guest, os_type, caps, virt_type):
334 ++    def _set_features(self, guest, os_type, image_meta, caps, virt_type):
335 +         if virt_type == "xen":
336 +             # PAE only makes sense in X86
337 +             if caps.host.cpu.arch in (fields.Architecture.I686,
338 +@@ -4264,7 +4264,10 @@
339 +
340 +         if (virt_type not in ("lxc", "uml", "parallels", "xen") or
341 +                 (virt_type == "xen" and guest.os_type == fields.VMMode.HVM)):
342 +-            guest.features.append(vconfig.LibvirtConfigGuestFeatureACPI())
343 ++            guestarch = libvirt_utils.get_arch(image_meta)
344 ++            if (guestarch not in (fields.Architecture.ARMV7, fields.Architecture.AARCH64) or
345 ++                image_meta.properties.get('hw_firmware_type') == 'uefi'):
346 ++                    guest.features.append(vconfig.LibvirtConfigGuestFeatureACPI())
347 +             guest.features.append(vconfig.LibvirtConfigGuestFeatureAPIC())
348 +
349 +         if (virt_type in ("qemu", "kvm") and
350 +@@ -4799,7 +4802,7 @@
351 +             self._conf_non_lxc_uml(virt_type, guest, root_device_name, rescue,
352 +                     instance, inst_path, image_meta, disk_info)
353 +
354 +-        self._set_features(guest, instance.os_type, caps, virt_type)
355 ++        self._set_features(guest, instance.os_type, image_meta, caps, virt_type)
356 +         self._set_clock(guest, instance.os_type, image_meta, virt_type)
357 +
358 +         storage_configs = self._get_guest_storage_config(
359 +--
360 +
361 +From f0f09530ee9169eb29bc28d4f118676d7dc6640e Mon Sep 17 00:00:00 2001
362 +From: Kevin Zhao <kevin.zhao@arm.com>
363 +Date: Tue, 15 Aug 2017 09:52:09 +0000
364 +Subject: [PATCH] Add video type virtio for AArch64
365 +
366 +Currently only "virtio" type is supported on AArch64, and the
367 +other "virrus", "qxl" and "vga" don't work on AArch64 according to
368 +libvirt upstream:
369 +https://www.redhat.com/archives/libvir-list/2016-September/msg00546.html
370 +Then this patch adds the virtio for AArch64 and tweaks the related test cases.
371 +
372 +Closes-bug: #1710766
373 +
374 +[ Alexandru.Avadanii@enea.com ]
375 +Dropped test changes so it applies cleanly on Newton without more backports.
376 +
377 +Change-Id: Iba8a1e671f2b5759b3d9178aa1871d0cf888b26b
378 +Signed-off-by: Kevin Zhao <kevin.zhao@arm.com>
379 +Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
380 +---
381 +
382 +--- a/nova/virt/libvirt/driver.py
383 ++++ b/nova/virt/libvirt/driver.py
384 +@@ -4342,7 +4342,8 @@ def _check_number_of_serial_console(self, num_ports):
385 +                 allowed=ALLOWED_QEMU_SERIAL_PORTS, virt_type=virt_type)
386 +
387 +     def _add_video_driver(self, guest, image_meta, flavor):
388 +-        VALID_VIDEO_DEVICES = ("vga", "cirrus", "vmvga", "xen", "qxl")
389 ++        VALID_VIDEO_DEVICES = ("vga", "cirrus", "vmvga",
390 ++                               "xen", "qxl", "virtio")
391 +         video = vconfig.LibvirtConfigGuestVideo()
392 +         # NOTE(ldbragst): The following logic sets the video.type
393 +         # depending on supported defaults given the architecture,
394 +@@ -4360,6 +4361,10 @@ def _add_video_driver(self, guest, image_meta, flavor):
395 +             # NOTE(ldbragst): PowerKVM doesn't support 'cirrus' be default
396 +             # so use 'vga' instead when running on Power hardware.
397 +             video.type = 'vga'
398 ++        elif guestarch in (fields.Architecture.AARCH64):
399 ++            # NOTE(kevinz): Only virtio device type is supported by AARCH64
400 ++            # so use 'virtio' instead when running on AArch64 hardware.
401 ++            video.type = 'virtio'
402 +         elif CONF.spice.enabled:
403 +             video.type = 'qxl'
404 +         if image_meta.properties.get('hw_video_model'):
405 diff --git a/mcp/salt-formulas/armband/init.sls b/mcp/salt-formulas/armband/init.sls
406 new file mode 100644
407 index 0000000..8a8cf2a
408 --- /dev/null
409 +++ b/mcp/salt-formulas/armband/init.sls
410 @@ -0,0 +1,7 @@
411 +include:
412 + - armband.qemu_efi
413 + - armband.vgabios
414 + {%- if salt['pkg.version']('python-nova') %}
415 + - armband.nova_libvirt
416 + - armband.nova_config
417 + {%- endif %}
418 diff --git a/mcp/salt-formulas/armband/nova_config.sls b/mcp/salt-formulas/armband/nova_config.sls
419 new file mode 100644
420 index 0000000..674f371
421 --- /dev/null
422 +++ b/mcp/salt-formulas/armband/nova_config.sls
423 @@ -0,0 +1,30 @@
424 +{% if grains['virtual'] == 'kvm' %}
425 +nova_virt_type:
426 +  file.replace:
427 +    - name: "/etc/nova/nova.conf"
428 +    - pattern: '^virt_type\s*=.*$'
429 +    - repl: "virt_type = qemu"
430 +{% endif %}
431 +nova_pointer_model:
432 +  file.replace:
433 +    - name: "/etc/nova/nova.conf"
434 +    - pattern: '^#pointer_model\s*=.*$'
435 +    - repl: "pointer_model = ps2mouse"
436 +nova_cpu_mode:
437 +  file.replace:
438 +    - name: "/etc/nova/nova.conf"
439 +    - pattern:  '^cpu_mode\s*=\s*host-passthrough'
440 +    - repl: "cpu_mode = custom"
441 +nova_cpu_model:
442 +  file.replace:
443 +    - name: "/etc/nova/nova.conf"
444 +    - pattern: '^#cpu_model\s*=.*$'
445 +    {% if grains['virtual'] == 'kvm' %}
446 +    - repl: "cpu_model = cortex-a57"
447 +    {% else %}
448 +    - repl: "cpu_model = host"
449 +    {% endif %}
450 +restart_nova-compute:
451 +  cmd:
452 +    - run
453 +    - name: "service nova-compute restart"
454 diff --git a/mcp/salt-formulas/armband/nova_libvirt.sls b/mcp/salt-formulas/armband/nova_libvirt.sls
455 new file mode 100644
456 index 0000000..bc2cbda
457 --- /dev/null
458 +++ b/mcp/salt-formulas/armband/nova_libvirt.sls
459 @@ -0,0 +1,7 @@
460 +nova-libvirt-aarch64-rollup:
461 +  file.patch:
462 +  - name: /usr/lib/python2.7/dist-packages
463 +  - source: salt://armband/files/nova-libvirt-aarch64-rollup.diff
464 +  - hash: False
465 +  - options: '-p1'
466 +  - unless: 'test -f /var/cache/salt/minion/files/base/armband/files/nova-libvirt-aarch64-rollup.diff && cd /usr/lib/python2.7/dist-packages && patch -p1 -R --dry-run /var/cache/salt/minion/files/base/armband/files/nova-libvirt-aarch64-rollup.diff'
467 diff --git a/mcp/salt-formulas/armband/qemu_efi.sls b/mcp/salt-formulas/armband/qemu_efi.sls
468 new file mode 100644
469 index 0000000..c697dae
470 --- /dev/null
471 +++ b/mcp/salt-formulas/armband/qemu_efi.sls
472 @@ -0,0 +1,2 @@
473 +qemu-efi:
474 +  pkg.installed
475 diff --git a/mcp/salt-formulas/armband/vgabios.sls b/mcp/salt-formulas/armband/vgabios.sls
476 new file mode 100644
477 index 0000000..500c2bc
478 --- /dev/null
479 +++ b/mcp/salt-formulas/armband/vgabios.sls
480 @@ -0,0 +1,7 @@
481 +vgabios:
482 +  pkg.installed
483 +/usr/share/qemu:
484 +  file.directory
485 +/usr/share/qemu/vgabios-stdvga.bin:
486 +  file.symlink:
487 +    - target: "/usr/share/vgabios/vgabios.bin"