Merge "vPE Sample VNF is missing in the installation scripts"
[yardstick.git] / ansible / build_yardstick_image.yml
1 # Copyright (c) 2017 Intel Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 ---
15 - hosts: jumphost
16
17   vars:
18     boot_modes:
19       'amd64': disk1
20       'arm64': uefi1
21     boot_mode: "{{ boot_modes[YARD_IMG_ARCH] }}"
22     image_filename: "{{ release }}-server-cloudimg-{{ YARD_IMG_ARCH }}-{{ boot_mode }}.img"
23     image_path: "{{ release }}/current/{{ image_filename }}"
24     host: "{{ lookup('env', 'HOST')|default('cloud-images.ubuntu.com', true)}}"
25     image_url: "{{ lookup('env', 'IMAGE_URL')|default('https://' ~ host ~ '/' ~ image_path, true) }}"
26     image_dest: "{{ workspace }}/{{ image_filename }}"
27     sha256sums_path: "{{ release }}/current/SHA256SUMS"
28     sha256sums_filename: "{{ sha256sums_path|basename }}"
29     sha256sums_url: "{{ lookup('env', 'SHA256SUMS_URL')|default('https://' ~ host ~ '/' ~ sha256sums_path, true) }}"
30
31     workspace: "{{ lookup('env', 'workspace')|default('/tmp/workspace/yardstick', true) }}"
32     raw_imgfile_basename: "yardstick-{{ release }}-server.raw"
33     growpart_package:
34       RedHat: cloud-utils-growpart
35       Debian: cloud-guest-utils
36   environment:
37     - PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
38     - "{{ proxy_env }}"
39
40   tasks:
41     - group_by:
42         key: image_builder
43
44     - package: name=parted state=present
45     - package: name=kpartx state=present
46     - package: name="{{ growpart_package[ansible_os_family] }}" state=present
47
48     - set_fact:
49         imgfile: "{{ normal_image_file }}"
50       when: img_property == "normal"
51
52     - set_fact:
53         imgfile: "{{ nsb_image_file }}"
54       when: img_property == "nsb"
55
56     - set_fact:
57         mountdir: "{{ lookup('env', 'mountdir')|default('/mnt/yardstick', true) }}"
58
59     - set_fact:
60         raw_imgfile: "{{ workspace }}/{{ raw_imgfile_basename }}"
61
62     # cleanup non-lxd
63     - name: unmount all old mount points
64       mount:
65         name: "{{ item }}"
66         state: unmounted
67       with_items:
68         # order matters
69         - "{{ mountdir }}/proc"
70         - "{{ mountdir }}"
71         - "/mnt/{{ release }}"
72
73     - name: kpartx -dv to delete all image partition device nodes
74       command: kpartx -dv "{{ raw_imgfile }}"
75       ignore_errors: true
76
77     - name: Debug dump loop devices
78       command: losetup -a
79       ignore_errors: true
80
81     - name: delete loop devices for image file
82       # use this because kpartx -dv will fail if raw_imgfile was delete
83       # but in theory we could have deleted file still attached to loopback device?
84       # use grep because of // and awk
85       shell: losetup -O NAME,BACK-FILE | grep "{{ raw_imgfile_basename }}" | awk '{ print $1 }' | xargs -l1 losetup -v -d
86       ignore_errors: true
87
88     - name: Debug dump loop devices again
89       command: losetup -a
90       ignore_errors: true
91
92     - name: delete {{ raw_imgfile }}
93       file:
94         path: "{{ raw_imgfile }}"
95         state: absent
96
97     # common
98     - name: remove {{ mountdir }}
99       file:
100         path: "{{ mountdir }}"
101         state: absent
102
103     # download-common
104     - name: remove {{ workspace }}
105       file:
106         path: "{{ workspace }}"
107         state: directory
108
109     - name: "fetch {{ image_url }} and verify "
110       fetch_url_and_verify:
111         url: "{{ image_url }}"
112         sha256url: "{{ sha256sums_url }}"
113         dest: "{{ image_dest }}"
114
115     - name: convert image to raw
116       command: "qemu-img convert {{ image_dest }} {{ raw_imgfile }}"
117
118     - name: resize image to allow for more VNFs
119       command: "qemu-img resize -f raw {{ raw_imgfile }} +2G"
120
121     - name: resize parition to allow for more VNFs
122       # use growpart because maybe it handles GPT better than parted
123       command: growpart {{ raw_imgfile }}  1
124
125     - name: create mknod devices in chroot
126       command: "mknod -m 0660 /dev/loop{{ item }} b 7 {{ item }}"
127       args:
128         creates: "/dev/loop{{ item }}"
129       with_sequence: start=0 end=9
130       tags: mknod_devices
131
132     - name: find first partition device
133       command: kpartx -l "{{ raw_imgfile }}"
134       register: kpartx_res
135
136     - set_fact:
137         image_first_partition: "{{ kpartx_res.stdout_lines[0].split()[0] }}"
138
139     - set_fact:
140         # assume / is the first partition
141         image_first_partition_device: "/dev/mapper/{{ image_first_partition }}"
142
143     - name: use kpartx to create device nodes for the raw image loop device
144       # operate on the loop device to avoid /dev namespace missing devices
145       command: kpartx -avs "{{ raw_imgfile }}"
146
147     - name: parted dump raw image
148       command: parted "{{ raw_imgfile }}" print
149       register: parted_res
150
151     - debug:
152         var: parted_res
153         verbosity: 2
154
155     - name: use blkid to find filesystem type of first partition device
156       command: blkid -o value -s TYPE {{ image_first_partition_device }}
157       register: blkid_res
158
159     - set_fact:
160         image_fs_type: "{{ blkid_res.stdout.strip() }}"
161     - fail:
162         msg: "We only support ext4 image filesystems because we have to resize"
163       when: image_fs_type != "ext4"
164
165     - name: fsck the image filesystem
166       command: "e2fsck -y -f {{ image_first_partition_device  }}"
167
168     - name: resize filesystem to full partition size
169       command: resize2fs {{ image_first_partition_device }}
170
171     - name: fsck the image filesystem
172       command: "e2fsck -y -f {{ image_first_partition_device  }}"
173
174     - name: make tmp disposable fstab
175       command: mktemp --tmpdir fake_fstab.XXXXXXXXXX
176       register: mktemp_res
177
178     - set_fact:
179         fake_fstab: "{{ mktemp_res.stdout.strip() }}"
180
181     - name: mount first parition on image device
182       mount:
183         src: "{{ image_first_partition_device }}"
184         name: "{{ mountdir }}"
185         # fstype is required
186         fstype: "{{ image_fs_type }}"
187         # !!!!!!! this is required otherwise we add entries to /etc/fstab
188         # and prevent the system from booting
189         fstab: "{{ fake_fstab }}"
190         state: mounted
191
192     - name: mount chroot /proc
193       mount:
194         src: none
195         name: "{{ mountdir }}/proc"
196         fstype: proc
197         # !!!!!!! this is required otherwise we add entries to /etc/fstab
198         # and prevent the system from booting
199         fstab: "{{ fake_fstab }}"
200         state: mounted
201
202     - name: if arm copy qemu-aarch64-static into chroot
203       copy:
204         src: /usr/bin/qemu-aarch64-static
205         dest: "{{ mountdir }}/usr/bin"
206       when: 'YARD_IMG_ARCH == "arm64"'
207
208     - name: create ubuntu policy-rc.d workaround
209       copy:
210         content: "{{ '#!/bin/sh\nexit 101\n' }}"
211         dest: "{{ mountdir }}/usr/sbin/policy-rc.d"
212         mode: 0755
213       when: "target_os == 'Ubuntu'"
214
215     - name: add chroot as host
216       add_host:
217         name: "{{ mountdir }}"
218         groups: chroot_image,image_builder
219         connection: chroot
220         ansible_python_interpreter: /usr/bin/python3
221         # set this host variable here
222         nameserver_ip: "{{ ansible_dns.nameservers[0] }}"
223         image_type: vm
224
225 - name: include ubuntu_server_cloudimg_modify.yml
226   include: ubuntu_server_cloudimg_modify.yml
227   when: img_property == "normal"
228
229 - name: include ubuntu_server_cloudimg_modify_samplevnfs.yml
230   include: ubuntu_server_cloudimg_modify_samplevnfs.yml
231   when: img_property == "nsb"
232
233 - hosts: localhost
234   tasks:
235     - name: convert image to image file
236       command: "qemu-img convert -c -o compat=0.10 -O qcow2 {{ raw_imgfile }} {{ imgfile }}"
237
238 - name: run post build tasks
239   include: post_build_yardstick_image.yml
240
241 - hosts: localhost
242
243   tasks:
244     - debug:
245         msg: "yardstick image = {{ imgfile }}"