Merge lp:~heber013/utah/fix-provisioning-function into lp:utah
- fix-provisioning-function
- Merge into dev
Status: | Merged |
---|---|
Merged at revision: | 1130 |
Proposed branch: | lp:~heber013/utah/fix-provisioning-function |
Merge into: | lp:utah |
Diff against target: |
277 lines (+78/-41) 3 files modified
conf/utah/default-vm.xml (+5/-2) utah/provisioning/provisioning.py (+56/-37) utah/provisioning/vm.py (+17/-2) |
To merge this branch: | bzr merge lp:~heber013/utah/fix-provisioning-function |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jean-Baptiste Lallement | Approve | ||
Paul Larson | Pending | ||
Review via email: mp+352837@code.launchpad.net |
This proposal supersedes a proposal from 2018-07-10.
Commit message
Fixing broken provisioning function due to initrd file extension change
Description of the change
Fixing broken provisioning function due to initrd file extension change
Paul Larson (pwlars) wrote : Posted in a previous version of this proposal | # |
Jean-Baptiste Lallement (jibel) wrote : Posted in a previous version of this proposal | # |
I think the fix is incomplete. casper/initrd and the target directory initrd have the same name and utah fails with ENOTDIR
cat: write error: Broken pipe
Unhandled error in UTAH:
Traceback (most recent call last):
File "/usr/bin/
exitstatus = timeout(
File "/usr/lib/
return command(*args, **kw)
File "/usr/bin/
exitstatus, locallogs = run_tests(args, _get_machine(args))
File "/usr/lib/
exitstatus, remote_path = _run(machine, args.runlist, extraopts)
File "/usr/lib/
return _install_
File "/usr/lib/
machine.
File "/usr/lib/
self.
File "/usr/lib/
self.
File "/usr/lib/
self.
File "/usr/lib/
config.
File "/usr/lib/
retval = command(*args, **kw)
File "/usr/lib/
self.
File "/usr/lib/
self.
File "/usr/lib/
self.
File "/usr/lib/
shutil.
File "/usr/lib/
copyfile(src, dst)
File "/usr/lib/
with open(dst, 'wb') as fdst:
IOError: [Errno 20] Not a directory: '/var/lib/
Heber Parrucci (heber013) wrote : Posted in a previous version of this proposal | # |
I tried fixing _copy_qemu_scripts and some more errors. Now I am getting an error in the function _preseedcasper:
2018-08-06 17:17:13,086 root WARNING: Command (sed -i 1i/scripts/
- 1130. By Heber Parrucci
-
Fixing issue when repacking initrd
- 1131. By Heber Parrucci
-
Fixing utah tests:
* Adding more memory to created VMs
* Adding video type qxl
* Adding retries when starting the VM with vm.create() - 1132. By Heber Parrucci
-
Increasing wait period default value when starting the virtual machine
- 1133. By Heber Parrucci
-
Updating logic on first VM boot
Jean-Baptiste Lallement (jibel) wrote : | # |
Thanks for this patch.
It fixes the problem with desktop images but breaks server tests.
The error is:
INFO: logpath was already set by /etc/utah/config
2018-09-10 03:00:05,890 cleanup WARNING: OSError when changing directory permissions: [Errno 1] Operation not permitted: '/var/lib/
2018-09-10 03:00:05,890 cleanup WARNING: OSError when changing directory permissions: [Errno 1] Operation not permitted: '/var/lib/
2018-09-10 03:00:05,891 cleanup WARNING: OSError when changing directory permissions: [Errno 1] Operation not permitted: '/var/lib/
2018-09-10 03:00:05,891 cleanup WARNING: OSError when changing directory permissions: [Errno 1] Operation not permitted: '/var/lib/
Unhandled error in UTAH:
Traceback (most recent call last):
File "/usr/bin/
exitstatus = timeout(
File "/usr/lib/
return command(*args, **kw)
File "/usr/bin/
exitstatus, locallogs = run_tests(args, _get_machine(args))
File "/usr/lib/
exitstatus, remote_path = _run(machine, args.runlist, extraopts)
File "/usr/lib/
return _install_
File "/usr/lib/
machine.
File "/usr/lib/
self.
File "/usr/lib/
self.
File "/usr/lib/
self._start()
File "/usr/lib/
self.
File "/usr/lib/
if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirtError: Requested operation is not valid: domain is already running
+ RETCODE=4
- 1134. By Heber Parrucci
-
Fixing start vm function
Heber Parrucci (heber013) wrote : | # |
> Thanks for this patch.
>
> It fixes the problem with desktop images but breaks server tests.
>
> The error is:
>
> INFO: logpath was already set by /etc/utah/config
> 2018-09-10 03:00:05,890 cleanup WARNING: OSError when changing directory
> permissions: [Errno 1] Operation not permitted: '/var/lib/
> -cosmic-
> 2018-09-10 03:00:05,890 cleanup WARNING: OSError when changing directory
> permissions: [Errno 1] Operation not permitted: '/var/lib/
> -cosmic-
> 2018-09-10 03:00:05,891 cleanup WARNING: OSError when changing directory
> permissions: [Errno 1] Operation not permitted: '/var/lib/
> -cosmic-
> 2018-09-10 03:00:05,891 cleanup WARNING: OSError when changing directory
> permissions: [Errno 1] Operation not permitted: '/var/lib/
> -cosmic-
> Unhandled error in UTAH:
> Traceback (most recent call last):
> File "/usr/bin/
> exitstatus = timeout(
> File "/usr/lib/
> return command(*args, **kw)
> File "/usr/bin/
> exitstatus, locallogs = run_tests(args, _get_machine(args))
> File "/usr/lib/
> exitstatus, remote_path = _run(machine, args.runlist, extraopts)
> File "/usr/lib/
> return _install_
> File "/usr/lib/
> _install_and_run
> machine.
> File "/usr/lib/
> line 316, in installclient
> self.uploadfile
> File "/usr/lib/
> in uploadfiles
> self.activecheck()
> File "/usr/lib/
> in activecheck
> self._start()
> File "/usr/lib/
> in _start
> self.vm.create()
> File "/usr/lib/
> if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
> libvirtError: Requested operation is not valid: domain is already running
>
> + RETCODE=4
It should be fixed now. Thanks!
Jean-Baptiste Lallement (jibel) wrote : | # |
Thanks. Tested on Xenial with cosmic and bionic images of Desktop and server.
Preview Diff
1 | === modified file 'conf/utah/default-vm.xml' | |||
2 | --- conf/utah/default-vm.xml 2016-02-04 16:28:14 +0000 | |||
3 | +++ conf/utah/default-vm.xml 2018-09-10 14:38:14 +0000 | |||
4 | @@ -20,8 +20,8 @@ | |||
5 | 20 | <domain type='qemu'> | 20 | <domain type='qemu'> |
6 | 21 | <name>Utah Example</name> | 21 | <name>Utah Example</name> |
7 | 22 | <uuid>00000000-0000-0000-0000-000000000000</uuid> | 22 | <uuid>00000000-0000-0000-0000-000000000000</uuid> |
10 | 23 | <memory>524288</memory> | 23 | <memory>1048576</memory> |
11 | 24 | <currentMemory>524288</currentMemory> | 24 | <currentMemory>1048576</currentMemory> |
12 | 25 | <vcpu>1</vcpu> | 25 | <vcpu>1</vcpu> |
13 | 26 | <os> | 26 | <os> |
14 | 27 | <type arch='i686' machine='pc'>hvm</type> | 27 | <type arch='i686' machine='pc'>hvm</type> |
15 | @@ -49,6 +49,9 @@ | |||
16 | 49 | <model type='virtio'/> | 49 | <model type='virtio'/> |
17 | 50 | </interface> | 50 | </interface> |
18 | 51 | <graphics type='vnc' autoport='yes'/> | 51 | <graphics type='vnc' autoport='yes'/> |
19 | 52 | <video> | ||
20 | 53 | <model type='qxl' vram='16384' heads='1'/> | ||
21 | 54 | </video> | ||
22 | 52 | </devices> | 55 | </devices> |
23 | 53 | </domain> | 56 | </domain> |
24 | 54 | 57 | ||
25 | 55 | 58 | ||
26 | === modified file 'utah/provisioning/provisioning.py' | |||
27 | --- utah/provisioning/provisioning.py 2018-07-07 16:12:04 +0000 | |||
28 | +++ utah/provisioning/provisioning.py 2018-09-10 14:38:14 +0000 | |||
29 | @@ -25,6 +25,7 @@ | |||
30 | 25 | import re | 25 | import re |
31 | 26 | import shutil | 26 | import shutil |
32 | 27 | import stat | 27 | import stat |
33 | 28 | import subprocess | ||
34 | 28 | import sys | 29 | import sys |
35 | 29 | import urllib | 30 | import urllib |
36 | 30 | import uuid | 31 | import uuid |
37 | @@ -321,7 +322,7 @@ | |||
38 | 321 | 'File not found: {filename}; ' | 322 | 'File not found: {filename}; ' |
39 | 322 | 'UTAH was probably updated during the run. ' | 323 | 'UTAH was probably updated during the run. ' |
40 | 323 | 'Please try again.' | 324 | 'Please try again.' |
42 | 324 | .format(filename=deb), | 325 | .format(filename=deb), |
43 | 325 | retry=True) | 326 | retry=True) |
44 | 326 | raise err | 327 | raise err |
45 | 327 | except AttributeError: | 328 | except AttributeError: |
46 | @@ -508,8 +509,8 @@ | |||
47 | 508 | raise UTAHProvisioningException( | 509 | raise UTAHProvisioningException( |
48 | 509 | '{cls} attempted to call the {method} method ' | 510 | '{cls} attempted to call the {method} method ' |
49 | 510 | 'of the base Machine class, which is not implemented' | 511 | 'of the base Machine class, which is not implemented' |
52 | 511 | .format(cls=self.__class__.__name__, | 512 | .format(cls=self.__class__.__name__, |
53 | 512 | method=method)) | 513 | method=method)) |
54 | 513 | 514 | ||
55 | 514 | def cleanfile(self, path): | 515 | def cleanfile(self, path): |
56 | 515 | """Register a path to be cleaned later. | 516 | """Register a path to be cleaned later. |
57 | @@ -558,7 +559,6 @@ | |||
58 | 558 | 559 | ||
59 | 559 | 560 | ||
60 | 560 | class CustomInstallMixin(object): | 561 | class CustomInstallMixin(object): |
61 | 561 | |||
62 | 562 | """Provide routines for automating an install from an image.""" | 562 | """Provide routines for automating an install from an image.""" |
63 | 563 | 563 | ||
64 | 564 | def _preparekernel(self, kernel=None, tmpdir=None): | 564 | def _preparekernel(self, kernel=None, tmpdir=None): |
65 | @@ -661,15 +661,24 @@ | |||
66 | 661 | if os.path.splitext(initrd)[1] == '.gz': | 661 | if os.path.splitext(initrd)[1] == '.gz': |
67 | 662 | self.logger.debug('Using gzip based on file extension') | 662 | self.logger.debug('Using gzip based on file extension') |
68 | 663 | pipe.prepend('zcat $IN', 'f-') | 663 | pipe.prepend('zcat $IN', 'f-') |
69 | 664 | pipe.append('cpio -ivd 2>/dev/null', '-.') | ||
70 | 665 | exitstatus = pipe.copy(initrd, '/dev/null') | ||
71 | 666 | self.initrd_uncompressed_path = os.path.join(tmpdir, 'initrd.d') | ||
72 | 667 | self.initrd_no_extension = False | ||
73 | 664 | elif os.path.splitext(initrd)[1] == '.lz': | 668 | elif os.path.splitext(initrd)[1] == '.lz': |
74 | 665 | self.logger.debug('Using lzma based on file extension') | 669 | self.logger.debug('Using lzma based on file extension') |
75 | 666 | pipe.prepend('lzcat -S .lz $IN', 'f-') | 670 | pipe.prepend('lzcat -S .lz $IN', 'f-') |
76 | 671 | pipe.append('cpio -ivd 2>/dev/null', '-.') | ||
77 | 672 | exitstatus = pipe.copy(initrd, '/dev/null') | ||
78 | 673 | self.initrd_uncompressed_path = os.path.join(tmpdir, 'initrd.d') | ||
79 | 674 | self.initrd_no_extension = False | ||
80 | 675 | elif not os.path.splitext(initrd)[1]: | ||
81 | 676 | exitstatus = subprocess.check_call(['unmkinitramfs', initrd, os.getcwd()]) | ||
82 | 677 | self.initrd_uncompressed_path = os.path.join(tmpdir, 'initrd.d', 'main') | ||
83 | 678 | self.initrd_no_extension = True | ||
84 | 667 | else: | 679 | else: |
85 | 668 | raise UTAHProvisioningException( | 680 | raise UTAHProvisioningException( |
90 | 669 | 'initrd file does have have gz or lz extension: {}' | 681 | 'initrd file does have have gz or lz extension or no extension: {}'.format(initrd)) |
87 | 670 | .format(initrd)) | ||
88 | 671 | pipe.append('cpio -ivd 2>/dev/null', '-.') | ||
89 | 672 | exitstatus = pipe.copy(initrd, '/dev/null') | ||
91 | 673 | if exitstatus != 0: | 682 | if exitstatus != 0: |
92 | 674 | # Currently this comes up as 512 when things seem fine | 683 | # Currently this comes up as 512 when things seem fine |
93 | 675 | # TODO: refactor this and check for codes at all stages | 684 | # TODO: refactor this and check for codes at all stages |
94 | @@ -683,10 +692,10 @@ | |||
95 | 683 | if tmpdir is None: | 692 | if tmpdir is None: |
96 | 684 | tmpdir = self.tmpdir | 693 | tmpdir = self.tmpdir |
97 | 685 | shutil.copyfile(config.sshpublickey, | 694 | shutil.copyfile(config.sshpublickey, |
99 | 686 | os.path.join(tmpdir, 'initrd.d', 'utah-ssh-key')) | 695 | os.path.join(self.initrd_uncompressed_path, 'utah-ssh-key')) |
100 | 687 | 696 | ||
101 | 688 | self.logger.info('Creating latecommand scripts') | 697 | self.logger.info('Creating latecommand scripts') |
103 | 689 | filename = os.path.join(tmpdir, 'initrd.d', 'utah-latecommand') | 698 | filename = os.path.join(self.initrd_uncompressed_path, 'utah-latecommand') |
104 | 690 | template.write('utah-latecommand.jinja2', | 699 | template.write('utah-latecommand.jinja2', |
105 | 691 | filename, | 700 | filename, |
106 | 692 | user=config.user, | 701 | user=config.user, |
107 | @@ -696,19 +705,22 @@ | |||
108 | 696 | install_type=self.image.installtype, | 705 | install_type=self.image.installtype, |
109 | 697 | md5=self.image.getmd5()) | 706 | md5=self.image.getmd5()) |
110 | 698 | 707 | ||
112 | 699 | filename = os.path.join(tmpdir, 'initrd.d', 'utah-setup') | 708 | filename = os.path.join(self.initrd_uncompressed_path, 'utah-setup') |
113 | 700 | template.write('utah-setup.jinja2', | 709 | template.write('utah-setup.jinja2', |
114 | 701 | filename, | 710 | filename, |
115 | 702 | packages=config.installpackages, | 711 | packages=config.installpackages, |
116 | 703 | log_file='/var/log/utah-install') | 712 | log_file='/var/log/utah-install') |
117 | 704 | 713 | ||
119 | 705 | filename = os.path.join(tmpdir, 'initrd.d', 'utah-autorun.sh') | 714 | filename = os.path.join(self.initrd_uncompressed_path, 'utah-autorun.sh') |
120 | 706 | template.write('utah-autorun.sh.jinja2', | 715 | template.write('utah-autorun.sh.jinja2', |
121 | 707 | filename, | 716 | filename, |
122 | 708 | log_file='/var/log/utah-install') | 717 | log_file='/var/log/utah-install') |
123 | 709 | 718 | ||
124 | 710 | def _copy_qemu_scripts(self, tmpdir=None): | 719 | def _copy_qemu_scripts(self, tmpdir=None): |
126 | 711 | initrd_work_dir = os.path.join(tmpdir, 'initrd') | 720 | if self.initrd_no_extension: |
127 | 721 | initrd_work_dir = self.initrd_uncompressed_path | ||
128 | 722 | else: | ||
129 | 723 | initrd_work_dir = os.path.join(tmpdir, 'initrd') | ||
130 | 712 | if not os.path.exists(initrd_work_dir): | 724 | if not os.path.exists(initrd_work_dir): |
131 | 713 | os.makedirs(initrd_work_dir) | 725 | os.makedirs(initrd_work_dir) |
132 | 714 | # copy the qemu scripts into initrd | 726 | # copy the qemu scripts into initrd |
133 | @@ -736,8 +748,8 @@ | |||
134 | 736 | if self.image.installtype == 'desktop': | 748 | if self.image.installtype == 'desktop': |
135 | 737 | self._rewrite_failure_command(preseed) | 749 | self._rewrite_failure_command(preseed) |
136 | 738 | 750 | ||
139 | 739 | output_preseed_filename = os.path.join(tmpdir, | 751 | output_preseed_filename = os.path.join(self.initrd_uncompressed_path, |
140 | 740 | 'initrd.d', 'preseed.cfg') | 752 | 'preseed.cfg') |
141 | 741 | with open(output_preseed_filename, 'w') as f: | 753 | with open(output_preseed_filename, 'w') as f: |
142 | 742 | f.write(preseed.dump()) | 754 | f.write(preseed.dump()) |
143 | 743 | self.finalpreseed = output_preseed_filename | 755 | self.finalpreseed = output_preseed_filename |
144 | @@ -766,7 +778,7 @@ | |||
145 | 766 | question.prepend('ubiquity ubiquity/summary note') | 778 | question.prepend('ubiquity ubiquity/summary note') |
146 | 767 | question.prepend('ubiquity ubiquity/reboot boolean true') | 779 | question.prepend('ubiquity ubiquity/reboot boolean true') |
147 | 768 | 780 | ||
149 | 769 | filename = os.path.join(tmpdir, 'initrd.d', 'latecommand-wrapper') | 781 | filename = os.path.join(self.initrd_uncompressed_path, 'latecommand-wrapper') |
150 | 770 | target_log_file = '/target{}'.format(log_file) | 782 | target_log_file = '/target{}'.format(log_file) |
151 | 771 | template.write('latecommand-wrapper.jinja2', | 783 | template.write('latecommand-wrapper.jinja2', |
152 | 772 | filename, | 784 | filename, |
153 | @@ -838,10 +850,8 @@ | |||
154 | 838 | self.logger.info('Inserting preseed into casper') | 850 | self.logger.info('Inserting preseed into casper') |
155 | 839 | if tmpdir is None: | 851 | if tmpdir is None: |
156 | 840 | tmpdir = self.tmpdir | 852 | tmpdir = self.tmpdir |
161 | 841 | 853 | casper_dir = os.path.join(os.path.join(self.initrd_uncompressed_path, 'scripts', | |
162 | 842 | casper_dir = os.path.join(tmpdir, 'initrd.d', 'scripts', | 854 | 'casper-bottom')) |
159 | 843 | 'casper-bottom') | ||
160 | 844 | |||
163 | 845 | filename = os.path.join(casper_dir, 'utah') | 855 | filename = os.path.join(casper_dir, 'utah') |
164 | 846 | template.write('casper-preseed-script.jinja2', filename) | 856 | template.write('casper-preseed-script.jinja2', filename) |
165 | 847 | os.chmod(filename, 0755) | 857 | os.chmod(filename, 0755) |
166 | @@ -856,7 +866,7 @@ | |||
167 | 856 | if exitstatus != 0: | 866 | if exitstatus != 0: |
168 | 857 | raise UTAHProvisioningException('Failed to setup casper script') | 867 | raise UTAHProvisioningException('Failed to setup casper script') |
169 | 858 | 868 | ||
171 | 859 | casper_file = os.path.join(tmpdir, 'initrd.d', 'etc', 'casper.conf') | 869 | casper_file = os.path.join(self.initrd_uncompressed_path, 'etc', 'casper.conf') |
172 | 860 | tmpfilename = '{}.tmp'.format(casper_file) | 870 | tmpfilename = '{}.tmp'.format(casper_file) |
173 | 861 | with open(casper_file, 'r') as i: | 871 | with open(casper_file, 'r') as i: |
174 | 862 | with open(tmpfilename, 'w') as o: | 872 | with open(tmpfilename, 'w') as o: |
175 | @@ -879,7 +889,7 @@ | |||
176 | 879 | """ | 889 | """ |
177 | 880 | if tmpdir is None: | 890 | if tmpdir is None: |
178 | 881 | tmpdir = self.tmpdir | 891 | tmpdir = self.tmpdir |
180 | 882 | inittab = os.path.join(tmpdir, 'initrd.d', 'etc', 'inittab') | 892 | inittab = os.path.join(self.initrd_uncompressed_path, 'etc', 'inittab') |
181 | 883 | if os.path.isfile(inittab): | 893 | if os.path.isfile(inittab): |
182 | 884 | self.logger.info('Updating inittab') | 894 | self.logger.info('Updating inittab') |
183 | 885 | with open(inittab, 'a') as myfile: | 895 | with open(inittab, 'a') as myfile: |
184 | @@ -889,7 +899,7 @@ | |||
185 | 889 | "-f /var/log/syslog \n") | 899 | "-f /var/log/syslog \n") |
186 | 890 | 900 | ||
187 | 891 | self.logger.info('Creating rsyslog config file') | 901 | self.logger.info('Creating rsyslog config file') |
189 | 892 | conffilename = os.path.join(tmpdir, 'initrd.d', '50-utahdefault.conf') | 902 | conffilename = os.path.join(self.initrd_uncompressed_path, '50-utahdefault.conf') |
190 | 893 | with open(conffilename, 'w') as f: | 903 | with open(conffilename, 'w') as f: |
191 | 894 | if self.rsyslog.port: | 904 | if self.rsyslog.port: |
192 | 895 | ip = self._ipaddr(config.bridge) | 905 | ip = self._ipaddr(config.bridge) |
193 | @@ -909,21 +919,30 @@ | |||
194 | 909 | self.logger.info('Repacking initrd') | 919 | self.logger.info('Repacking initrd') |
195 | 910 | if tmpdir is None: | 920 | if tmpdir is None: |
196 | 911 | tmpdir = self.tmpdir | 921 | tmpdir = self.tmpdir |
206 | 912 | pipe = pipes.Template() | 922 | if self.initrd_no_extension: |
207 | 913 | pipe.prepend('find .', '.-') | 923 | os.chdir(self.initrd_uncompressed_path) |
208 | 914 | pipe.append('cpio --quiet -o -H newc', '--') | 924 | pipe = pipes.Template() |
209 | 915 | # Desktop image loads initrd.gz, | 925 | pipe.prepend('find .', '.-') |
210 | 916 | # but for physical machines we should stick with lz | 926 | pipe.append('cpio --quiet -o -H newc', '--') |
211 | 917 | if self.image.installtype == 'desktop': | 927 | initrd = os.path.join(tmpdir, 'initrd') |
212 | 918 | self.logger.debug('Using lzma because installtype is desktop') | 928 | if pipe.copy('/dev/null', initrd) != 0: |
213 | 919 | pipe.append('lzma -9fc ', '--') | 929 | raise UTAHProvisioningException('Failed to repack initrd') |
205 | 920 | initrd = os.path.join(tmpdir, 'initrd.lz') | ||
214 | 921 | else: | 930 | else: |
220 | 922 | self.logger.debug('Using gzip because installtype is not desktop') | 931 | pipe = pipes.Template() |
221 | 923 | pipe.append('gzip -9fc ', '--') | 932 | pipe.prepend('find .', '.-') |
222 | 924 | initrd = os.path.join(tmpdir, 'initrd.gz') | 933 | pipe.append('cpio --quiet -o -H newc', '--') |
223 | 925 | if pipe.copy('/dev/null', initrd) != 0: | 934 | # Desktop image loads initrd.gz, |
224 | 926 | raise UTAHProvisioningException('Failed to repack initrd') | 935 | # but for physical machines we should stick with lz |
225 | 936 | if self.image.installtype == 'desktop': | ||
226 | 937 | self.logger.debug('Using lzma because installtype is desktop') | ||
227 | 938 | pipe.append('lzma -9fc ', '--') | ||
228 | 939 | initrd = os.path.join(tmpdir, 'initrd.lz') | ||
229 | 940 | else: | ||
230 | 941 | self.logger.debug('Using gzip because installtype is not desktop') | ||
231 | 942 | pipe.append('gzip -9fc ', '--') | ||
232 | 943 | initrd = os.path.join(tmpdir, 'initrd.gz') | ||
233 | 944 | if pipe.copy('/dev/null', initrd) != 0: | ||
234 | 945 | raise UTAHProvisioningException('Failed to repack initrd') | ||
235 | 927 | return initrd | 946 | return initrd |
236 | 928 | 947 | ||
237 | 929 | def _cmdlinesetup(self): | 948 | def _cmdlinesetup(self): |
238 | 930 | 949 | ||
239 | === modified file 'utah/provisioning/vm.py' | |||
240 | --- utah/provisioning/vm.py 2017-07-06 18:03:17 +0000 | |||
241 | +++ utah/provisioning/vm.py 2018-09-10 14:38:14 +0000 | |||
242 | @@ -220,6 +220,7 @@ | |||
243 | 220 | os.makedirs(self.directory) | 220 | os.makedirs(self.directory) |
244 | 221 | except OSError as err: | 221 | except OSError as err: |
245 | 222 | raise UTAHVMProvisioningException(err) | 222 | raise UTAHVMProvisioningException(err) |
246 | 223 | self.first_boot = True | ||
247 | 223 | self.logger.debug('CustomVM init finished') | 224 | self.logger.debug('CustomVM init finished') |
248 | 224 | 225 | ||
249 | 225 | def _createdisks(self, disksizes=None): | 226 | def _createdisks(self, disksizes=None): |
250 | @@ -552,12 +553,26 @@ | |||
251 | 552 | if self.poweroff: | 553 | if self.poweroff: |
252 | 553 | self.cleanfunction(self.vm.shutdown, force=True) | 554 | self.cleanfunction(self.vm.shutdown, force=True) |
253 | 554 | 555 | ||
255 | 555 | def _start(self): | 556 | def _start(self, retries=6, wait=10): |
256 | 556 | """Start the VM.""" | 557 | """Start the VM.""" |
257 | 557 | self.logger.info('Starting CustomVM') | 558 | self.logger.info('Starting CustomVM') |
258 | 559 | attempt = 1 | ||
259 | 558 | if self.vm is not None: | 560 | if self.vm is not None: |
261 | 559 | if self.vm.isActive() == 0: | 561 | # For desktop tests the first boot configures the qemu script to run system tests and |
262 | 562 | # shuts down the machine, so we start the machine and wait until it shuts down, | ||
263 | 563 | # then we start it again and continue | ||
264 | 564 | if self.image.installtype == 'desktop' and self.first_boot: | ||
265 | 560 | self.vm.create() | 565 | self.vm.create() |
266 | 566 | while self.vm.isActive() == 1 and attempt <= retries: | ||
267 | 567 | self.logger.info('Waiting for the VM to shut down, attempt number: %s', attempt) | ||
268 | 568 | time.sleep(wait) | ||
269 | 569 | attempt += 1 | ||
270 | 570 | if self.vm.isActive() == 0: | ||
271 | 571 | self.vm.create() | ||
272 | 572 | self.first_boot = False | ||
273 | 573 | else: | ||
274 | 574 | if self.vm.isActive() == 0: | ||
275 | 575 | self.vm.create() | ||
276 | 561 | else: | 576 | else: |
277 | 562 | raise UTAHVMProvisioningException('Failed to provision VM') | 577 | raise UTAHVMProvisioningException('Failed to provision VM') |
278 | 563 | 578 |
Looks sane, +1 assuming it works for you