Merge ~mateus-morais/ubuntu/+source/open-iscsi:merge-lp2040361-noble into ubuntu/+source/open-iscsi:debian/sid

Proposed by Mateus Rodrigues de Morais
Status: Merged
Merge reported by: Mateus Rodrigues de Morais
Merged at revision: 05712925316ba3d416229e07c4d81d89fe8655f8
Proposed branch: ~mateus-morais/ubuntu/+source/open-iscsi:merge-lp2040361-noble
Merge into: ubuntu/+source/open-iscsi:debian/sid
Diff against target: 5633 lines (+5368/-6)
17 files modified
debian/README.Debian (+2/-2)
debian/changelog (+1420/-0)
debian/control (+2/-1)
debian/extra/startup-checks.sh (+1/-1)
debian/open-iscsi.postinst (+1/-1)
debian/patches/fix-format-overflow-warnings.patch (+30/-0)
debian/patches/series (+1/-0)
debian/tests/README-boot-test.md (+139/-0)
debian/tests/control (+4/-0)
debian/tests/get-image (+227/-0)
debian/tests/install (+1/-1)
debian/tests/patch-image (+381/-0)
debian/tests/test-open-iscsi.py (+427/-0)
debian/tests/testlib.py (+1488/-0)
debian/tests/testsuite (+6/-0)
debian/tests/tgt-boot-test (+534/-0)
debian/tests/xkvm (+704/-0)
Reviewer Review Type Date Requested Status
Simon Quigley (community) Approve
git-ubuntu import Pending
Review via email: mp+457350@code.launchpad.net

Description of the change

Merging open-iscsi 2.1.9-3 into Noble.

PPA: https://launchpad.net/~mateus-morais/+archive/ubuntu/open-iscsi-merge

Autopkgtest results:
- amd64: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mateus-morais-open-iscsi-merge/noble/amd64/o/open-iscsi/20231214_121346_4c753@/log.gz
- arm64: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mateus-morais-open-iscsi-merge/noble/arm64/o/open-iscsi/20231214_123506_fbf3e@/log.gz
- armhf: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mateus-morais-open-iscsi-merge/noble/armhf/o/open-iscsi/20231211_213812_85c16@/log.gz
- ppc64el: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mateus-morais-open-iscsi-merge/noble/ppc64el/o/open-iscsi/20231214_121048_9d038@/log.gz
- s390x: https://autopkgtest.ubuntu.com/results/autopkgtest-noble-mateus-morais-open-iscsi-merge/noble/s390x/o/open-iscsi/20231214_121229_f18aa@/log.gz

This also includes two fixes for issues that appeared when running PPA autopkgtests:

- commit 7b679fb: server images have recently started having separate /boot partitions, which the test script didn't anticipate and ended up looking for kernel and initrd in an empty /boot directory. This fixes that by manually mounting the /boot partition, so that kernel and initrd are visible.

- commit ec3f26f: this is a weird issue that caused the /etc/iscsi/initiatorname.iscsi file to still contain GenerateName=yes even after the package was installed and configured. Technically, the postinst script should already replace that with an actual name during postinst configure, but that was not happening. So making the test purge the package and reinstall it fixed the issue.

To post a comment you must log in.
Revision history for this message
Simon Quigley (tsimonq2) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/README.Debian b/debian/README.Debian
2index f0c2568..43c7c81 100644
3--- a/debian/README.Debian
4+++ b/debian/README.Debian
5@@ -57,7 +57,7 @@ iSCSI Qualified Names (IQN) and initiatorname.iscsi
6 The initiatorname.iscsi file defines the iSCSI Qualified Name (IQN) of the iSCSI
7 initiator. This IQN is used by the initiator to identify itself to the target.
8
9-Example: InitiatorName=iqn.1993-08.org.debian:01:lnx-debian
10+Example: InitiatorName=iqn.2004-10.com.ubuntu:01:lnx-debian
11
12 While this name can be adjusted to suit your needs, once set, it should not be
13 changed. If you later change the InitiatorName, existing access control lists
14@@ -100,7 +100,7 @@ options in your initramfs:
15
16 Example Syntax:
17
18- ISCSI_INITIATOR="iqn.1993-08.org.debian:01:9b3e5634fdb9"
19+ ISCSI_INITIATOR="iqn.2004-10.com.ubuntu:01:9b3e5634fdb9"
20 ISCSI_TARGET_NAME=iqn.2008-01.com.example:storage.foo
21 ISCSI_TARGET_IP=192.168.1.1
22 ISCSI_TARGET_PORT=3260
23diff --git a/debian/changelog b/debian/changelog
24index 7a092a5..ef294ff 100644
25--- a/debian/changelog
26+++ b/debian/changelog
27@@ -1,3 +1,27 @@
28+open-iscsi (2.1.9-3ubuntu1) noble; urgency=medium
29+
30+ * Merge with Debian unstable (LP: #2040361). Remaining changes:
31+ - d/README.Debian, d/extra/startup-checks.sh, d/open-iscsi.postinst:
32+ Apply Ubuntu branding to iqn initiator name
33+ - debian/tests: Add Ubuntu autopkgtest suite:
34+ + d/t/README-boot-test.md: document test design
35+ + d/t/control: register testsuite
36+ + d/t/get-image: helper to fetch an ubuntu cloud image
37+ + d/t/patch-image: helper to modify an ubuntu cloud image
38+ + d/test-open-iscsi.py, d/t/testlib.py: various qa regression tests
39+ + d/t/testsuite: helper to invoke qa regression tests
40+ + d/t/tgt-boot-test: test using tgt to boot from iscsi
41+ + d/t/xkvm: helper to spawn a VM
42+ - d/p/fix-format-overflow-warnings.patch: Fix format overflow warnings
43+ seen when building with -O3 to avoid FTBFS on ppc64el
44+ * d/t/patch-image: fixed kernel detection by manually mounting /boot when
45+ downloaded image contains a separate /boot partition
46+ * d/t/install: fixed test by forcing a package reinstall so that
47+ /etc/iscsi/initiatorname.iscsi can have expected value from the
48+ postinst script
49+
50+ -- Mateus Rodrigues de Morais <mateus.morais@canonical.com> Thu, 14 Dec 2023 10:08:38 -0300
51+
52 open-iscsi (2.1.9-3) unstable; urgency=medium
53
54 * Release to unstable.
55@@ -32,6 +56,30 @@ open-iscsi (2.1.8-2) unstable; urgency=medium
56
57 -- Chris Hofstaedtler <zeha@debian.org> Sun, 27 Aug 2023 12:10:27 +0200
58
59+open-iscsi (2.1.8-1ubuntu2) mantic; urgency=medium
60+
61+ * Fix format overflow warnings seen when building with
62+ -O3 to avoid FTBFS on ppc64el (LP: #2036884)
63+
64+ -- Graham Inggs <ginggs@ubuntu.com> Fri, 22 Sep 2023 15:42:55 +0000
65+
66+open-iscsi (2.1.8-1ubuntu1) lunar; urgency=low
67+
68+ * Merge from Debian unstable. Remaining changes:
69+ - debian/tests: Add Ubuntu autopkgtest suite:
70+ + d/t/README-boot-test.md: document test design
71+ + d/t/control: register testsuite
72+ + d/t/get-image: helper to fetch an ubuntu cloud image
73+ + d/t/patch-image: helper to modify an ubuntu cloud image
74+ + d/test-open-iscsi.py, d/t/testlib.py: various qa regression tests
75+ + d/t/testsuite: helper to invoke qa regression tests
76+ + d/t/tgt-boot-test: test using tgt to boot from iscsi
77+ + d/t/xkvm: helper to spawn a VM
78+ - d/README.Debian, d/extra/startup-checks.sh, d/open-iscsi.postinst:
79+ Apply Ubuntu branding to iqn initiator name
80+
81+ -- Steve Langasek <steve.langasek@ubuntu.com> Mon, 07 Nov 2022 15:10:10 -0800
82+
83 open-iscsi (2.1.8-1) unstable; urgency=medium
84
85 [ Chris Hofstaedtler ]
86@@ -44,6 +92,33 @@ open-iscsi (2.1.8-1) unstable; urgency=medium
87
88 -- Chris Hofstaedtler <zeha@debian.org> Wed, 19 Oct 2022 15:59:32 +0000
89
90+open-iscsi (2.1.7-2ubuntu1) kinetic; urgency=low
91+
92+ * Merge from Debian unstable. Remaining changes:
93+ - debian/tests: Add Ubuntu autopkgtest suite:
94+ + d/t/README-boot-test.md: document test design
95+ + d/t/control: register testsuite
96+ + d/t/get-image: helper to fetch an ubuntu cloud image
97+ + d/t/patch-image: helper to modify an ubuntu cloud image
98+ + d/test-open-iscsi.py, d/t/testlib.py: various qa regression tests
99+ + d/t/testsuite: helper to invoke qa regression tests
100+ + d/t/tgt-boot-test: test using tgt to boot from iscsi
101+ + d/t/xkvm: helper to spawn a VM
102+ - d/README.Debian, d/extra/startup-checks.sh, d/open-iscsi.postinst:
103+ Apply Ubuntu branding to iqn initiator name
104+ * Dropped changes, no longer needed:
105+ - debian/open-iscsi-udeb.start: Apply Ubuntu branding
106+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
107+ * Dropped changes, included in Debian:
108+ - d/p/lp1979692-fix-gcc12-ftbfs-0*.patch: Fix FTBFS with GCC 12.
109+ - d/rules: remove duplicated dh_installsystemd section
110+ * Dropped changes, no longer needed:
111+ - d/control: Transition from libopeniscsiusr0.2.0 to libopeniscsiusr;
112+ not needed, the referenced version is no longer in any supported
113+ release and the transitional package is in the previous LTS.
114+
115+ -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 16 Aug 2022 08:32:36 -0700
116+
117 open-iscsi (2.1.7-2) unstable; urgency=medium
118
119 * [09dfaec] Enable hardening build flags
120@@ -69,6 +144,86 @@ open-iscsi (2.1.7-1) unstable; urgency=medium
121
122 -- Chris Hofstaedtler <zeha@debian.org> Fri, 29 Jul 2022 19:59:11 +0000
123
124+open-iscsi (2.1.5-1ubuntu2) kinetic; urgency=medium
125+
126+ * d/p/lp1979692-fix-gcc12-ftbfs-0*.patch: Fix FTBFS with GCC 12.
127+ (LP: #1979692)
128+
129+ -- Sergio Durigan Junior <sergio.durigan@canonical.com> Thu, 23 Jun 2022 17:28:56 -0400
130+
131+open-iscsi (2.1.5-1ubuntu1) jammy; urgency=medium
132+
133+ * Merge with Debian unstable (LP: #1946835). Remaining changes:
134+ - debian/tests: Add Ubuntu autopkgtest suite:
135+ + d/t/README-boot-test.md: document test design
136+ + d/t/control: register testsuite
137+ + d/t/get-image: helper to fetch an ubuntu cloud image
138+ + d/t/patch-image: helper to modify an ubuntu cloud image
139+ + d/test-open-iscsi.py, d/t/testlib.py: various qa regression tests
140+ + d/t/testsuite: helper to invoke qa regression tests
141+ + d/t/tgt-boot-test: test using tgt to boot from iscsi
142+ + d/t/xkvm: helper to spawn a VM
143+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
144+ - d/README.Debian, d/extra/startup-checks.sh, d/open-iscsi-udeb.start,
145+ d/open-iscsi.postinst: Apply Ubuntu branding to iqn initiator name
146+ - d/control: Transition from libopeniscsiusr0.2.0 to libopeniscsiusr
147+ - d/t/test-open-iscsi.py: adopt to resolvectl (systemd v249 compat)
148+ * Dropped changes, included in Debian:
149+ - d/iscsid.service: Let iscsid systemd job run in privileged containers
150+ but not in unprivileged ones
151+ - debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
152+ run ipconfig to gather all DHCP config info, including DNS search
153+ domain, which iBFT can't provide.
154+ - Remove initramfs interfaces stamp in case no iscsi devs mounted
155+ If iscsi root was requested, but no iscsi devices were mounted, remove
156+ the initramfs interfaces stamp file. Meaning, that on shutdown there is
157+ no 30s delay, whilst trying to re-establish iscsi login to perform a
158+ logout.
159+ - add IPv6 support
160+ + Source /run/net6-*.conf when needed.
161+ + debian/extra/initramfs.local-top: handle IPv6 configs being shipped
162+ in DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
163+ /run/initramfs/open-iscsi.interface
164+ - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi
165+ logout hook and recommend finalrd and busybox for the logout hook
166+ to work.
167+ - Make iscsid socket-activated to only activate it as needed:
168+ + debian/open-iscsi.service: do not start or check iscsid.service
169+ + debian/rules: install and enable iscsid.socket
170+ + debian/open-iscsi.postinst:
171+ + run restart logic only if service is running on upgrade
172+ + drop no longer reachable upgrade path that affects iscsid
173+ + disable iscsid.service on upgrade
174+ + handle iscsid.socket to be started if the service is not running yet
175+ + d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
176+ run when udev disks are attached.
177+ + d/iscsid.service: Remove ExecStop= directive.
178+ + debian/tests/install: fix tests to work with socket activation
179+ + debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
180+ - debian/open-iscsi.service: Start open-iscsi systemd job when either
181+ /etc/iscsi/nodes or /sys/class/iscsi_session have content.
182+ - Prevent network interface that contains iscsi root from bouncing
183+ during boot or going down during shutdown if the system is using
184+ resolvconf or ifupdown:
185+ + d/iscsi-network-interface.rules
186+ + d/extra/net-interface-handler
187+ - debian/extra/initramfs.hook: add ib_iser to the list of modules
188+ included in the initramfs, so that we can in principle support
189+ iscsi root on infiniband.
190+ - debian/open-iscsi.kmod drop: (LP 1833586)
191+ no static module list is needed if we let iscsid load modules itself.
192+ - d/extra/initramfs.local-{top,bottom}: move removal of
193+ open-iscsi.interface file from local-top to local-bottom,
194+ and fix shell quoting issue that would result in /run/initramfs/
195+ open-iscsi.interface always being removed (LP 1872813)
196+ - d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds and
197+ initialization, because upstream's gcc10 support is incomplete. This
198+ change can be dropped when upstream has completed their gcc support.
199+ * Added changes
200+ - d/rules: remove duplicated dh_installsystemd section
201+
202+ -- Dave Jones <dave.jones@canonical.com> Wed, 19 Jan 2022 11:38:12 +0000
203+
204 open-iscsi (2.1.5-1) unstable; urgency=medium
205
206 * [150470c] New upstream version 2.1.5
207@@ -162,6 +317,91 @@ open-iscsi (2.1.4-1) unstable; urgency=low
208
209 -- Ritesh Raj Sarraf <rrs@debian.org> Thu, 02 Sep 2021 18:07:51 +0530
210
211+open-iscsi (2.1.4-0ubuntu3) jammy; urgency=medium
212+
213+ * No-change rebuild against openssl3
214+
215+ -- Simon Chopin <simon.chopin@canonical.com> Wed, 01 Dec 2021 16:08:23 +0000
216+
217+open-iscsi (2.1.4-0ubuntu2) jammy; urgency=medium
218+
219+ * [a0e81aa] d/t/test-open-iscsi.py: adopt to resolvectl (systemd v249 compat)
220+
221+ -- Lukas Märdian <slyon@ubuntu.com> Mon, 22 Nov 2021 11:42:18 +0100
222+
223+open-iscsi (2.1.4-0ubuntu1) impish; urgency=medium
224+
225+ * Merge with Debian unstable (LP: #1934290). Remaining changes:
226+ - debian/tests: Add Ubuntu autopkgtest suite:
227+ + d/t/README-boot-test.md: document test design
228+ + d/t/control: register testsuite
229+ + d/t/get-image: helper to fetch an ubuntu cloud image
230+ + d/t/patch-image: helper to modify an ubuntu cloud image
231+ + d/test-open-iscsi.py, d/t/testlib.py: various qa regression tests
232+ + d/t/testsuite: helper to invoke qa regression tests
233+ + d/t/tgt-boot-test: test using tgt to boot from iscsi
234+ + d/t/xkvm: helper to spawn a VM
235+ Note: this suite should be replaced by LIO that replaced TGT in main.
236+ - d/iscsid.service: Let iscsid systemd job run in privileged containers
237+ but not in unprivileged ones
238+ - debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
239+ run ipconfig to gather all DHCP config info, including DNS search
240+ domain, which iBFT can't provide.
241+ - Remove initramfs interfaces stamp in case no iscsi devs mounted
242+ If iscsi root was requested, but no iscsi devices were mounted, remove
243+ the initramfs interfaces stamp file. Meaning, that on shutdown there is
244+ no 30s delay, whilst trying to re-establish iscsi login to perform a
245+ logout.
246+ - add IPv6 support
247+ + Source /run/net6-*.conf when needed.
248+ + debian/extra/initramfs.local-top: handle IPv6 configs being shipped
249+ in DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
250+ /run/initramfs/open-iscsi.interface
251+ - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi
252+ logout hook and recommend finalrd and busybox for the logout hook
253+ to work.
254+ - Make iscsid socket-activated to only activate it as needed:
255+ + debian/open-iscsi.service: do not start or check iscsid.service
256+ + debian/rules: install and enable iscsid.socket
257+ + debian/open-iscsi.postinst:
258+ + run restart logic only if service is running on upgrade
259+ + drop no longer reachable upgrade path that affects iscsid
260+ + disable iscsid.service on upgrade
261+ + handle iscsid.socket to be started if the service is not running yet
262+ + d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
263+ run when udev disks are attached.
264+ + d/iscsid.service: Remove ExecStop= directive.
265+ + debian/tests/install: fix tests to work with socket activation
266+ + debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
267+ - debian/open-iscsi.service: Start open-iscsi systemd job when either
268+ /etc/iscsi/nodes or /sys/class/iscsi_session have content.
269+ - Prevent network interface that contains iscsi root from bouncing
270+ during boot or going down during shutdown if the system is using
271+ resolvconf or ifupdown:
272+ + d/iscsi-network-interface.rules
273+ + d/extra/net-interface-handler
274+ - debian/extra/initramfs.hook: add ib_iser to the list of modules
275+ included in the initramfs, so that we can in principle support
276+ iscsi root on infiniband.
277+ - debian/open-iscsi.kmod drop: (LP 1833586)
278+ no static module list is needed if we let iscsid load modules itself.
279+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
280+ - d/extra/initramfs.local-{top,bottom}: move removal of
281+ open-iscsi.interface file from local-top to local-bottom,
282+ and fix shell quoting issue that would result in /run/initramfs/
283+ open-iscsi.interface always being removed (LP 1872813)
284+ - d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds and
285+ initialization, because upstream's gcc10 support is incomplete. This
286+ change can be dropped when upstream has completed their gcc support.
287+ - d/README.Debian, d/extra/startup-checks.sh, d/open-iscsi-udeb.start,
288+ d/open-iscsi.postinst: Apply Ubuntu branding to iqn initiator name
289+ * Added changes
290+ - merge bug fix release 2.1.4 from upstream
291+ - Revert "Add patches from upstream" [upstream in 2.1.4]
292+ - d/control: Transition from libopeniscsiusr0.2.0 to libopeniscsiusr
293+
294+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 01 Jul 2021 14:13:08 +0200
295+
296 open-iscsi (2.1.3-5) unstable; urgency=medium
297
298 [ Cyril Brulebois ]
299@@ -197,6 +437,119 @@ open-iscsi (2.1.3-2) unstable; urgency=medium
300
301 -- Chris Hofstaedtler <zeha@debian.org> Sun, 07 Feb 2021 19:23:13 +0000
302
303+open-iscsi (2.1.3-1ubuntu6) hirsute; urgency=medium
304+
305+ * d/open-iscsi.finalrd: fix UID resolution issues in logout (LP: #1922976)
306+ Thanks to Michael Brown
307+
308+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 18 Mar 2021 09:44:07 +0100
309+
310+open-iscsi (2.1.3-1ubuntu5) hirsute; urgency=medium
311+
312+ * make d/t/testuite python3 compatible (LP: #1919461)
313+ - backport changes from qa-regression-testing since we diverged
314+ - various tests: make py3 compliant, fix formatting a bit
315+ - tests: convert deprecated assertEquals() to assertEqual()
316+ - Remove all references to python-utils
317+ - d/t/testlib.py: update to last state from
318+ git+ssh://git.launchpad.net/qa-regression-testing
319+ - d/t/{control,testsuite}: bump to use python3
320+ - d/t/test-open-iscsi.py: switch shebang to python3
321+ - d/t/test-open-iscsi.py: adapt to updated testlib
322+ * Add patches from upstream [this is from Debian upload 2.1.3-2]:
323+ - Fix memory leak in iscsiadm, Fix iscsiadm segfault when exiting, and
324+ - Fix iscsistart login issue when target is delayed. The last one should
325+ - fix iscsi-root with delayed network (Closes: #980085)
326+
327+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 18 Mar 2021 09:44:07 +0100
328+
329+open-iscsi (2.1.3-1ubuntu4) hirsute; urgency=medium
330+
331+ * Rebuild again so s390x pick up the right debhelper
332+
333+ -- Sebastien Bacher <seb128@ubuntu.com> Wed, 24 Feb 2021 16:29:41 +0100
334+
335+open-iscsi (2.1.3-1ubuntu3) hirsute; urgency=medium
336+
337+ * No-change rebuild to drop the udeb package.
338+
339+ -- Matthias Klose <doko@ubuntu.com> Mon, 22 Feb 2021 10:35:42 +0100
340+
341+open-iscsi (2.1.3-1ubuntu2) hirsute; urgency=medium
342+
343+ * Apply Ubuntu branding to iqn initiator name.
344+
345+ -- Dimitri John Ledkov <xnox@ubuntu.com> Wed, 17 Feb 2021 00:05:22 +0000
346+
347+open-iscsi (2.1.3-1ubuntu1) hirsute; urgency=medium
348+
349+ * Merge with Debian unstable. Remaining changes:
350+ - debian/tests: Add Ubuntu autopkgtest suite:
351+ - README-boot-test.md
352+ - tgt-boot-test: tests
353+ - test-open-iscsi.py
354+ - testlib.py
355+ - get-image
356+ - patch-image
357+ - testsuite
358+ - xkvm
359+ - d/iscsid.service: Let iscsid systemd job run in privileged containers
360+ but not in unprivileged ones
361+ - d/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
362+ run ipconfig to gather all DHCP config info, including DNS search
363+ domain, which iBFT can't provide.
364+ - Remove initramfs interfaces stamp in case no iscsi devs mounted.
365+ If iscsi root was requested, but no iscsi devices were mounted, remove
366+ the initramfs interfaces stamp file. Meaning, that on shutdown there is
367+ no 30s delay, whilst trying to re-establish iscsi login to perform a
368+ logout.
369+ - add IPv6 support
370+ - Source /run/net6-*.conf when needed.
371+ - d/extra/initramfs.local-top: handle IPv6 configs being shipped in
372+ DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
373+ .interface
374+ - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi logout
375+ hook and recommend finalrd and busybox for the logout hook to work.
376+ - Make iscsid socket-activated to only activate it as needed:
377+ - debian/open-iscsi.service: do not start or check iscsid.service
378+ - debian/rules: install and enable iscsid.socket
379+ - debian/open-iscsi.postinst:
380+ - run restart logic only if service is running on upgrade
381+ - drop no longer reachable upgrade path that affects iscsid
382+ - disable iscsid.service on upgrade
383+ - handle iscsid.socket to be started if the service is not running yet
384+ - d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
385+ run when udev disks are attached.
386+ - d/iscsid.service: Remove ExecStop= directive.
387+ - debian/tests/install: fix tests to work with socket activation
388+ - debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
389+ [updated to match 2.1.2]
390+ - debian/open-iscsi.service: Start open-iscsi systemd job when either
391+ /etc/iscsi/nodes or /sys/class/iscsi_session have content.
392+ - Prevent network interface that contains iscsi root from bouncing
393+ during boot or going down during shutdown if the system is using
394+ resolvconf or ifupdown:
395+ - d/iscsi-network-interface.rules
396+ - d/extra/net-interface-handler
397+ - d/extra/initramfs.hook: add ib_iser to the list of modules included in
398+ the initramfs, so that we can in principle support iscsi root on
399+ infiniband.
400+ - d/open-iscsi.kmod drop: (LP #1833586)
401+ no static module list is needed if we let iscsid load modules itself.
402+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
403+ - d/extra/initramfs.local-{top,bottom}: move removal of
404+ open-iscsi.interface file from local-top to local-bottom, and fix shell
405+ quoting issue that would result in /run/initramfs/ open-iscsi.interface
406+ always being removed (LP #1872813)
407+ - debian/control, debian/rules: Fix libopeniscsiusr binary package
408+ name (LP 1892228).
409+ - d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds
410+ and initialization, because upstream's gcc10 support is incomplete.
411+ This change can be dropped when upstream has completed their gcc
412+ support.
413+
414+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Tue, 19 Jan 2021 13:29:46 +0100
415+
416 open-iscsi (2.1.3-1) unstable; urgency=medium
417
418 * [afee47d] New upstream version 2.1.3
419@@ -215,6 +568,75 @@ open-iscsi (2.1.2-2) unstable; urgency=medium
420
421 -- Chris Hofstaedtler <zeha@debian.org> Sun, 06 Dec 2020 23:25:11 +0000
422
423+open-iscsi (2.1.2-1ubuntu1) hirsute; urgency=medium
424+
425+ * Merge with Debian unstable. Remaining changes:
426+ - debian/tests: Add Ubuntu autopkgtest suite:
427+ - README-boot-test.md
428+ - tgt-boot-test: tests
429+ - test-open-iscsi.py
430+ - testlib.py
431+ - get-image
432+ - patch-image
433+ - testsuite
434+ - xkvm
435+ - d/iscsid.service: Let iscsid systemd job run in privileged containers
436+ but not in unprivileged ones
437+ - d/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
438+ run ipconfig to gather all DHCP config info, including DNS search
439+ domain, which iBFT can't provide.
440+ - Remove initramfs interfaces stamp in case no iscsi devs mounted.
441+ If iscsi root was requested, but no iscsi devices were mounted, remove
442+ the initramfs interfaces stamp file. Meaning, that on shutdown there is
443+ no 30s delay, whilst trying to re-establish iscsi login to perform a
444+ logout.
445+ - add IPv6 support
446+ - Source /run/net6-*.conf when needed.
447+ - d/extra/initramfs.local-top: handle IPv6 configs being shipped in
448+ DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
449+ .interface
450+ - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi logout
451+ hook and recommend finalrd and busybox for the logout hook to work.
452+ - Make iscsid socket-activated to only activate it as needed:
453+ - debian/open-iscsi.service: do not start or check iscsid.service
454+ - debian/rules: install and enable iscsid.socket
455+ - debian/open-iscsi.postinst:
456+ - run restart logic only if service is running on upgrade
457+ - drop no longer reachable upgrade path that affects iscsid
458+ - disable iscsid.service on upgrade
459+ - handle iscsid.socket to be started if the service is not running yet
460+ - d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
461+ run when udev disks are attached.
462+ - d/iscsid.service: Remove ExecStop= directive.
463+ - debian/tests/install: fix tests to work with socket activation
464+ - debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
465+ [updated to match 2.1.2]
466+ - debian/open-iscsi.service: Start open-iscsi systemd job when either
467+ /etc/iscsi/nodes or /sys/class/iscsi_session have content.
468+ - Prevent network interface that contains iscsi root from bouncing
469+ during boot or going down during shutdown if the system is using
470+ resolvconf or ifupdown:
471+ - d/iscsi-network-interface.rules
472+ - d/extra/net-interface-handler
473+ - d/extra/initramfs.hook: add ib_iser to the list of modules included in
474+ the initramfs, so that we can in principle support iscsi root on
475+ infiniband.
476+ - d/open-iscsi.kmod drop: (LP #1833586)
477+ no static module list is needed if we let iscsid load modules itself.
478+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
479+ - d/extra/initramfs.local-{top,bottom}: move removal of
480+ open-iscsi.interface file from local-top to local-bottom, and fix shell
481+ quoting issue that would result in /run/initramfs/ open-iscsi.interface
482+ always being removed (LP #1872813)
483+ - debian/control, debian/rules: Fix libopeniscsiusr binary package
484+ name (LP 1892228).
485+ - d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds
486+ and initialization, because upstream's gcc10 support is incomplete.
487+ This change can be dropped when upstream has completed their gcc
488+ support.
489+
490+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 03 Dec 2020 14:44:39 +0100
491+
492 open-iscsi (2.1.2-1) unstable; urgency=medium
493
494 * [7f10701] New upstream version 2.1.2
495@@ -236,6 +658,86 @@ open-iscsi (2.1.1-2) unstable; urgency=medium
496
497 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 14 Aug 2020 12:32:16 +0530
498
499+open-iscsi (2.1.1-1ubuntu2) groovy; urgency=medium
500+
501+ * debian/control, debian/rules: Fix libopeniscsiusr binary package
502+ name (LP: #1892228).
503+ * debian/rules: Fix deprecated warning for dh_installinit that
504+ --no-restart-on-upgrade has been replaced by --no-stop-on-upgrade,
505+ which is equivalent in functionality (ref deb #837528).
506+
507+ -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Wed, 19 Aug 2020 19:08:47 +0000
508+
509+open-iscsi (2.1.1-1ubuntu1) groovy; urgency=medium
510+
511+ * New upstream version 2.1.1
512+ * d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds
513+ and initialization, because upstream's gcc10 support is incomplete.
514+ This change can be dropped when upstream has completed their gcc
515+ support.
516+ * Merge with Debian unstable (LP: #1891374). Remaining changes:
517+ - debian/tests: Add Ubuntu autopkgtest suite:
518+ - README-boot-test.md
519+ - tgt-boot-test: tests
520+ - test-open-iscsi.py
521+ - testlib.py
522+ - get-image
523+ - patch-image
524+ - testsuite
525+ - xkvm
526+ - d/iscsid.service: Let iscsid systemd job run in privileged containers
527+ but not in unprivileged ones
528+ - d/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
529+ run ipconfig to gather all DHCP config info, including DNS search
530+ domain, which iBFT can't provide.
531+ - Remove initramfs interfaces stamp in case no iscsi devs mounted.
532+ If iscsi root was requested, but no iscsi devices were mounted, remove
533+ the initramfs interfaces stamp file. Meaning, that on shutdown there is
534+ no 30s delay, whilst trying to re-establish iscsi login to perform a
535+ logout.
536+ - add IPv6 support
537+ - Source /run/net6-*.conf when needed.
538+ - d/extra/initramfs.local-top: handle IPv6 configs being shipped in
539+ DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
540+ .interface
541+ - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi logout
542+ hook and recommend finalrd and busybox for the logout hook to work.
543+ - Make iscsid socket-activated to only activate it as needed:
544+ - debian/open-iscsi.service: do not start or check iscsid.service
545+ - debian/rules: install and enable iscsid.socket
546+ - debian/open-iscsi.postinst:
547+ - run restart logic only if service is running on upgrade
548+ - drop no longer reachable upgrade path that affects iscsid
549+ - disable iscsid.service on upgrade
550+ - handle iscsid.socket to be started if the service is not running yet
551+ - d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
552+ run when udev disks are attached.
553+ - d/iscsid.service: Remove ExecStop= directive.
554+ - debian/tests/install: fix tests to work with socket activation
555+ - debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
556+ - debian/open-iscsi.service: Start open-iscsi systemd job when either
557+ /etc/iscsi/nodes or /sys/class/iscsi_session have content.
558+ - Prevent network interface that contains iscsi root from bouncing
559+ during boot or going down during shutdown if the system is using
560+ resolvconf or ifupdown:
561+ - d/iscsi-network-interface.rules
562+ - d/extra/net-interface-handler
563+ - d/extra/initramfs.hook: add ib_iser to the list of modules included in
564+ the initramfs, so that we can in principle support iscsi root on
565+ infiniband.
566+ - d/open-iscsi.kmod drop: (LP #1833586)
567+ no static module list is needed if we let iscsid load modules itself.
568+ - Stop producing udebs on i386 where we no longer have d-i or a kernel.
569+ - Use python2 instead of python in the autopkg tests: Next step for
570+ open-iscsi is to revist all iscsi-root feature and autopkgtests, so
571+ keep python2 to avoid re-work later.
572+ - d/extra/initramfs.local-{top,bottom}: move removal of
573+ open-iscsi.interface file from local-top to local-bottom, and fix shell
574+ quoting issue that would result in /run/initramfs/ open-iscsi.interface
575+ always being removed (LP #1872813)
576+
577+ -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Thu, 13 Aug 2020 04:29:43 +0000
578+
579 open-iscsi (2.1.1-1) experimental; urgency=medium
580
581 [ Rafael David Tinoco ]
582@@ -280,6 +782,98 @@ open-iscsi (2.1.1-1) experimental; urgency=medium
583
584 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 23 Jun 2020 20:38:47 +0530
585
586+open-iscsi (2.0.874-7.1ubuntu6.1) focal; urgency=medium
587+
588+ [ Ben Swartzlander ]
589+ * allow open-iscsi to disable auto-scan feature (LP: #1877617)
590+ - d/p/lp1877617-Allow-disabling-auto-LUN-scans.patch
591+ - d/p/lp1877617-Fix-manual-LUN-scans-feature.patch
592+
593+ -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Mon, 11 May 2020 02:03:33 +0000
594+
595+open-iscsi (2.0.874-7.1ubuntu6) focal; urgency=medium
596+
597+ * d/extra/initramfs.local-{top,bottom}: move removal of open-iscsi.interface
598+ file from local-top to local-bottom, and fix shell quoting issue that
599+ would result in /run/initramfs/open-iscsi.interface always being removed
600+ (LP: #1872813)
601+
602+ -- Daniel Watkins <oddbloke@ubuntu.com> Tue, 14 Apr 2020 16:54:37 -0400
603+
604+open-iscsi (2.0.874-7.1ubuntu5) focal; urgency=medium
605+
606+ * Use python2 instead of python in the autopkg tests.
607+
608+ -- Matthias Klose <doko@ubuntu.com> Thu, 30 Jan 2020 10:14:16 +0100
609+
610+open-iscsi (2.0.874-7.1ubuntu3) eoan; urgency=medium
611+
612+ * Stop producing udebs on i386 where we no longer have d-i or a kernel.
613+
614+ -- Adam Conrad <adconrad@ubuntu.com> Wed, 09 Oct 2019 14:10:37 -0600
615+
616+open-iscsi (2.0.874-7.1ubuntu2) eoan; urgency=medium
617+
618+ * debian/open-iscsi.kmod: drop; no static module list is needed if we let
619+ iscsid load modules itself. LP: #1833586.
620+ * debian/extra/initramfs.hook: add ib_iser to the list of modules
621+ included in the initramfs, so that we can in principle support iscsi
622+ root on infiniband.
623+
624+ -- Steve Langasek <steve.langasek@ubuntu.com> Thu, 20 Jun 2019 13:48:46 -0700
625+
626+open-iscsi (2.0.874-7.1ubuntu1) eoan; urgency=low
627+
628+ * Merge from Debian unstable. Remaining changes:
629+ - debian/tests: Add Ubuntu autopkgtest.
630+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
631+ debian/open-iscsi.install:
632+ Prevent network interface that contains iscsi root from bouncing
633+ during boot or going down during shutdown if the system is using
634+ resolvconf or ifupdown.
635+ - Let iscsid systemd job run in privileged containers but not in
636+ unprivileged ones
637+ - Start open-iscsi systemd job when either /etc/iscsi/nodes or
638+ /sys/class/iscsi_session have content
639+ - add IPv6 support
640+ + Source /run/net6-*.conf when needed.
641+ + debian/extra/initramfs.local-top: handle IPv6 configs being
642+ shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
643+ can fill in /run/initramfs/open-iscsi.interface
644+ - make iscsid socket-activated to only activate it as needed
645+ + debian/iscsid.socket: systemd socket file for iscsid
646+ + debian/open-iscsi.service: do not start or check iscsid.service
647+ + debian/rules: install and enable iscsid.socket
648+ + debian/patches/iscid-conf-use-systemd.socket-patch: default to the
649+ socket
650+ + debian/open-iscsi.postinst:
651+ * run restart logic only if service is running on upgrade
652+ * drop no longer reachable upgrade path that affects iscsid
653+ * disable iscsid.service on upgrade
654+ * handle iscsid.socket to be started if the service is not running
655+ yet
656+ + d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
657+ run when udev disks are attached.
658+ + d/iscsid.service: Remove ExecStop= directive.
659+ + debian/tests/install: fix tests to work with socket activation
660+ - Ship finalrd logout hook.
661+ - debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
662+ run ipconfig to gather all DHCP config info, including DNS search
663+ domain, which iBFT can't provide.
664+ - If iscsi root was requested, but no iscsi devices were mounted, remove
665+ the initramfs interfaces stamp file. Meaning, that on shutdown there
666+ is no 30s delay, whilst trying to re-establish iscsi login to perform
667+ a logout.
668+ * Dropped changes, included in Debian:
669+ - Fix fail to build from source due to undefined reference to
670+ minor
671+ * Drop breaks on never-released version of finalrd.
672+ * debian/net-interface-handler: drop upstart support, unused since bionic.
673+ * Drop cleanup of upstart jobs, no longer needed post bionic.
674+ * debian/tests/daemon: drop, unused.
675+
676+ -- Steve Langasek <steve.langasek@ubuntu.com> Mon, 29 Apr 2019 16:13:37 -0700
677+
678 open-iscsi (2.0.874-7) unstable; urgency=medium
679
680 * [eeda27c] Enable back pristine-tar as we have now committed it
681@@ -295,6 +889,158 @@ open-iscsi (2.0.874-6) unstable; urgency=medium
682
683 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 05 Oct 2018 11:31:19 +0530
684
685+open-iscsi (2.0.874-5ubuntu15) disco; urgency=medium
686+
687+ * d/iscsid.service: Remove ExecStop= directive. Letting systemd
688+ handle termination prevents restart failures. (LP: #1821255)
689+
690+ -- Heitor R. Alves de Siqueira <halves@canonical.com> Thu, 28 Mar 2019 10:21:24 -0300
691+
692+open-iscsi (2.0.874-5ubuntu14) disco; urgency=medium
693+
694+ * debian/iscsi-disk.rules: Fix bug with LVM on top of iscsi devices.
695+ (LP: #1807978)
696+
697+ -- Scott Moser <smoser@ubuntu.com> Tue, 11 Dec 2018 19:01:14 -0500
698+
699+open-iscsi (2.0.874-5ubuntu13) disco; urgency=medium
700+
701+ [ Robert C Jennings & Dimitri John Ledkov ]
702+ * If iscsi root was requested, but no iscsi devices were mounted, remove
703+ the initramfs interfaces stamp file. Meaning, that on shutdown there
704+ is no 30s delay, whilst trying to re-establish iscsi login to perform
705+ a logout. LP: #1800681
706+
707+ -- Dimitri John Ledkov <xnox@ubuntu.com> Sun, 09 Dec 2018 22:29:20 +0000
708+
709+open-iscsi (2.0.874-5ubuntu12) disco; urgency=medium
710+
711+ [Scott Moser]
712+ * debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
713+ run ipconfig to gather all DHCP config info, including DNS search
714+ domain, which iBFT can't provide. (LP: #1806777)
715+
716+ -- Dan Streetman <ddstreet@canonical.com> Wed, 05 Dec 2018 11:28:12 -0500
717+
718+open-iscsi (2.0.874-5ubuntu11) disco; urgency=medium
719+
720+ * debian/tests/test-open-iscsi.py: Fix called process error.
721+ If no image was available for a release, a NameError exception would be
722+ raised.
723+
724+ -- Scott Moser <smoser@ubuntu.com> Wed, 14 Nov 2018 16:50:29 -0500
725+
726+open-iscsi (2.0.874-5ubuntu10) disco; urgency=medium
727+
728+ * d/iscsi-disk.rules, d/tests: Add a udev rule so that iscsid.service
729+ will be run when udev disks are attached. (LP: #1802354)
730+ * debian/tests: improve tgt boot test
731+ - disable snapd and snap.seeded services to avoid unnecessary
732+ resource consumption during tests.
733+ - save artifacts from the test run.
734+
735+ -- Scott Moser <smoser@ubuntu.com> Wed, 14 Nov 2018 16:05:46 -0500
736+
737+open-iscsi (2.0.874-5ubuntu9) cosmic; urgency=medium
738+
739+ * d/net-interface-handler: replace 'domainsearch' with the correct
740+ configuration option 'search' in net-interface-handler (LP: #1791108)
741+
742+ -- Victor Tapia <victor.tapia@canonical.com> Mon, 17 Sep 2018 15:58:34 +0200
743+
744+open-iscsi (2.0.874-5ubuntu8) cosmic; urgency=medium
745+
746+ * d/tests: insert some debug units in an attempt to diagnose any
747+ occurences of bug 1788188.
748+ * Fix fail to build from source due to undefined reference to
749+ minor (LP: #1791154)
750+
751+ -- Scott Moser <smoser@ubuntu.com> Tue, 21 Aug 2018 13:33:06 -0400
752+
753+open-iscsi (2.0.874-5ubuntu7) cosmic; urgency=medium
754+
755+ * d/tests: make interactive use of tgt-boot-test more usable by
756+ only using 'timeout' from the test harness.
757+ * debian/tests/README-boot-test.md: minor doc fixes and whitespace.
758+ * d/net-interface-handler: Apply changes only for the iscsi-root interface.
759+ (LP: #1785108)
760+
761+ -- Scott Moser <smoser@ubuntu.com> Tue, 07 Aug 2018 16:37:13 -0400
762+
763+open-iscsi (2.0.874-5ubuntu6) cosmic; urgency=medium
764+
765+ * Ship finalrd logout hook.
766+
767+ -- Dimitri John Ledkov <xnox@ubuntu.com> Fri, 03 Aug 2018 15:03:51 +0100
768+
769+open-iscsi (2.0.874-5ubuntu5) cosmic; urgency=medium
770+
771+ * Harden dep8 tests against effects due to slow execution on Launchpad
772+ infrastructure (LP: #1732028).
773+ - debian/tests/patch-image: remove problematic fstab entries
774+ - debian/tests/tgt-boot-test: ran xkvm in verbose mode
775+
776+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 19 Jul 2018 18:22:39 +0200
777+
778+open-iscsi (2.0.874-5ubuntu4) cosmic; urgency=medium
779+
780+ * debian/tests/install: ignore the potential stderr of the probing command
781+ that is meant to activate iscsid indirectly via the socket.
782+
783+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Wed, 30 May 2018 15:42:12 +0200
784+
785+open-iscsi (2.0.874-5ubuntu3) cosmic; urgency=medium
786+
787+ * make iscsid socket activated to only activate it as-needed (LP: #1755858)
788+ - debian/iscsid.socket: systemd socket file for iscsid
789+ - debian/open-iscsi.service: do not start or check iscsid.service
790+ - debian/rules: install and enable iscsid.socket
791+ - debian/patches/iscid-conf-use-systemd.socket-patch: default to the socket
792+ - debian/open-iscsi.postinst:
793+ + run restart logic only if service is running on upgrade
794+ + drop no more reachable upgrade path that affects iscsid
795+ + disable iscsid.service on upgrade
796+ + handle iscsid.socket to be started if the service is not running yet
797+ - debian/tests/install: fix tests to work with socket activation
798+
799+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Wed, 23 May 2018 15:50:01 +0200
800+
801+open-iscsi (2.0.874-5ubuntu2) bionic; urgency=medium
802+
803+ * debian/tests:
804+ - tgt-boot-test: Use 'timeout' to force a 60m timeout of the boot test.
805+ - README-boot-test.md: document environment variables BOOT_TIMEOUT
806+ and _USE_KVM.
807+
808+ -- Scott Moser <smoser@ubuntu.com> Wed, 21 Feb 2018 13:19:17 -0500
809+
810+open-iscsi (2.0.874-5ubuntu1) bionic; urgency=low
811+
812+ * Merge with Debian unstable. Remaining changes:
813+ - debian/tests: Add Ubuntu autopkgtests.
814+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
815+ debian/open-iscsi.install:
816+ Prevent network interface that contains iscsi root from bouncing
817+ during boot or going down during shutdown.
818+ Integrates with resolvconf and initramfs code that writes
819+ /run/initramfs/open-iscsi.interface
820+ - debian/open-iscsi.maintscript: clean up the obsolete
821+ iscsi-network-interface upstart job, file on upgrade.
822+ - Let iscsid systemd job run in privileged containers but not in
823+ unprivileged ones
824+ - Start open-iscsi systemd job when either /etc/iscsi/nodes or
825+ /sys/class/iscsi_session have content
826+ Based on patch by Nish Aravamudan, thanks! (LP #1576341)
827+ - add IPv6 support
828+ + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
829+ LP #1621507
830+ + Source /run/net6-*.conf when needed.
831+ + debian/extra/initramfs.local-top: handle IPv6 configs being
832+ shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
833+ can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
834+
835+ -- Dimitri John Ledkov <xnox@ubuntu.com> Fri, 12 Jan 2018 14:00:59 +0000
836+
837 open-iscsi (2.0.874-5) unstable; urgency=high
838
839 * [aeb86f7] Fix multiple security issues in iscsiuio. (CVE-2017-17840)
840@@ -302,6 +1048,74 @@ open-iscsi (2.0.874-5) unstable; urgency=high
841
842 -- Christian Seiler <christian@iwakd.de> Sat, 23 Dec 2017 11:30:44 +0100
843
844+open-iscsi (2.0.874-4ubuntu5) bionic; urgency=medium
845+
846+ * debian/tests/patch-image: mount auxilary filesystems before upgrading
847+ packages. Fixes ADT tests, when triggered by packages, that need
848+ /proc, /dev, etc mounted to complete the upgrade.
849+
850+ -- Dimitri John Ledkov <xnox@ubuntu.com> Wed, 03 Jan 2018 12:21:05 +0000
851+
852+open-iscsi (2.0.874-4ubuntu4) bionic; urgency=medium
853+
854+ * debian/tests/test-open-iscsi.py: skip test if cloud image is unavailable.
855+ This solves flaky tests in restricted network environments as well as in
856+ the short period after opening a new release (LP: #1731907).
857+
858+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 16 Nov 2017 12:06:34 +0100
859+
860+open-iscsi (2.0.874-4ubuntu3) artful; urgency=medium
861+
862+ * debian/tests/xkvm: do not use kvm (-enable-kvm) by default if
863+ operating inside a vm. nested kvm is finicky.
864+
865+ -- Scott Moser <smoser@ubuntu.com> Wed, 11 Oct 2017 18:14:08 -0400
866+
867+open-iscsi (2.0.874-4ubuntu2) artful; urgency=medium
868+
869+ * debian/tests/test-open-iscsi.py: query systemd-resolved if present.
870+ Ubuntu images now have systemd-resolved managing /etc/resolv.conf
871+ so support test if that is the case (LP: #1715468).
872+
873+ -- Scott Moser <smoser@ubuntu.com> Wed, 06 Sep 2017 16:20:16 -0400
874+
875+open-iscsi (2.0.874-4ubuntu1) artful; urgency=medium
876+
877+ * Merge with Debian unstable. Remaining changes:
878+ - debian/tests: Add Ubuntu autopkgtests.
879+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
880+ debian/open-iscsi.install:
881+ Prevent network interface that contains iscsi root from bouncing
882+ during boot or going down during shutdown.
883+ Integrates with resolvconf and initramfs code that writes
884+ /run/initramfs/open-iscsi.interface
885+ - debian/open-iscsi.maintscript: clean up the obsolete
886+ iscsi-network-interface upstart job, file on upgrade.
887+ - Let iscsid systemd job run in privileged containers but not in
888+ unprivileged ones
889+ - Start open-iscsi systemd job when either /etc/iscsi/nodes or
890+ /sys/class/iscsi_session have content
891+ Based on patch by Nish Aravamudan, thanks! (LP #1576341)
892+ - add IPv6 support
893+ + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
894+ LP #1621507
895+ + Source /run/net6-*.conf when needed.
896+ + debian/extra/initramfs.local-top: handle IPv6 configs being
897+ shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
898+ can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
899+ * Drop:
900+ - d/extra/initramfs.local-top: When booting from iBFT,
901+ set the PROTO= entry in /run/net-*.conf accordingly,
902+ so that other tools, such as cloud-init, can use that
903+ information. (cloud-init fails if the current PROTO=none
904+ is used.) (LP: #1684039) (Closes: #866213)
905+ [ Fixed in Debian 2.0.874-4 ]
906+ * d/t/test-open-iscsi.py: drop test_daemon test
907+ - With the updates to the systemd units, the services do not run
908+ unless iSCSI is configured.
909+
910+ -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 08 Aug 2017 16:16:27 -0700
911+
912 open-iscsi (2.0.874-4) unstable; urgency=medium
913
914 * [0347300] initramfs: populate PROTO= entry in /run/net-*.conf from iBFT
915@@ -316,6 +1130,64 @@ open-iscsi (2.0.874-3) unstable; urgency=medium
916
917 -- Christian Seiler <christian@iwakd.de> Sun, 18 Jun 2017 22:01:22 +0200
918
919+open-iscsi (2.0.874-2ubuntu3) artful; urgency=medium
920+
921+ * d/t/test-open-iscsi.py: drop test_daemon test
922+ - With the updates to the systemd units, the services do not run
923+ unless iSCSI is configured.
924+
925+ -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 08 Aug 2017 16:05:29 -0700
926+
927+open-iscsi (2.0.874-2ubuntu2) artful; urgency=medium
928+
929+ * d/extra/initramfs.local-top: When booting from iBFT,
930+ set the PROTO= entry in /run/net-*.conf accordingly,
931+ so that other tools, such as cloud-init, can use that
932+ information. (cloud-init fails if the current PROTO=none
933+ is used.) (LP: #1684039) (Closes: #866213)
934+
935+ -- Eric Desrochers <eric.desrochers@canonical.com> Wed, 05 Jul 2017 09:02:12 -0400
936+
937+open-iscsi (2.0.874-2ubuntu1) artful; urgency=medium
938+
939+ [ Nishanth Aravamudan ]
940+ * Merge with Debian unstable. Remaining changes:
941+ - debian/tests: Add Ubuntu autopkgtests.
942+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
943+ debian/open-iscsi.install:
944+ Prevent network interface that contains iscsi root from bouncing
945+ during boot or going down during shutdown.
946+ Integrates with resolvconf and initramfs code that writes
947+ /run/initramfs/open-iscsi.interface
948+ - debian/open-iscsi.maintscript: clean up the obsolete
949+ iscsi-network-interface upstart job, file on upgrade.
950+ - add IPv6 support
951+ + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
952+ LP #1621507
953+ + Source /run/net6-*.conf when needed.
954+ + debian/extra/initramfs.local-top: handle IPv6 configs being
955+ shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
956+ can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
957+ * Drop:
958+ - Make systemd job not run in containers (LP #1576341)
959+ [ This prevents running iscsi in privileged containers.
960+ Fixed differently in this upload. ]
961+ - Cherry-pick from Debian git repository (Christian Seiler):
962+ + open-iscsi-udeb: drop Depends: libnss-files-udeb
963+ (Closes #819685)
964+ [ Fixed in Debian ]
965+ - d/extra/initramfs.local-top whitespace change
966+ [ previously undocumented ]
967+
968+ [ Balint Reczey ]
969+ * Let iscsid systemd job run in privileged containers but not in
970+ unprivileged ones
971+ * Start open-iscsi systemd job when either /etc/iscsi/nodes or
972+ /sys/class/iscsi_session have content
973+ Based on patch by Nish Aravamudan, thanks! (LP #1576341)
974+
975+ -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 09 May 2017 09:24:23 -0700
976+
977 open-iscsi (2.0.874-2) unstable; urgency=medium
978
979 [ Christian Seiler ]
980@@ -455,6 +1327,155 @@ open-iscsi (2.0.873+git0.3b4b4500-15) unstable; urgency=medium
981
982 -- Christian Seiler <christian@iwakd.de> Fri, 20 May 2016 09:52:46 +0200
983
984+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu17) zesty; urgency=medium
985+
986+ * debian/tests:
987+ - README-boot-test.md: mention limited space caveat.
988+ - patch-image: fix handling of ADT_TEST_TRIGGERS if source package
989+ built more than one binary package.
990+ - test-open-iscsi.py: change to rely on patch-image
991+ adding package 'open-iscsi' rather than passing it in itself.
992+
993+ -- Scott Moser <smoser@ubuntu.com> Thu, 16 Feb 2017 15:47:58 -0500
994+
995+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu16) zesty; urgency=medium
996+
997+ * debian/tests: many improvements to the open-iscsi and tgt boot test.
998+ - only run test on amd64. just avoid timeout errors or other unrelated
999+ issues causing failure.
1000+ - debian/tests/README-boot-test.md: add doc describing the tgt-boot-test
1001+ - rename get-maas-eph to get-image
1002+ - use a cloud image instead of a maas image for booting. The value in
1003+ this is that we can then install open-iscsi inside the image and get an
1004+ updated initramfs.
1005+ - use subprocess.check_call rather than subprocess.call so that we
1006+ actually catch errors.
1007+ - update xkvm to what is in curtin/tools/xkvm
1008+ - improve updating of images to consider ADT_TEST_TRIGGERS if set.
1009+
1010+ -- Scott Moser <smoser@ubuntu.com> Tue, 14 Feb 2017 17:07:00 -0500
1011+
1012+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu15) zesty; urgency=medium
1013+
1014+ * debian/tests/tgt-boot-test: set HOST_IP harder for the testsuite test.
1015+
1016+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Sun, 29 Jan 2017 13:05:47 -0500
1017+
1018+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu14) zesty; urgency=medium
1019+
1020+ * Make systemd job not run in containers (LP: #1576341)
1021+
1022+ -- Serge Hallyn <serge.hallyn@ubuntu.com> Sun, 15 Jan 2017 23:08:29 -0600
1023+
1024+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu13) zesty; urgency=medium
1025+
1026+ * Fix syntax error in previous changes. LP: #1621507
1027+
1028+ -- LaMont Jones <lamont@ubuntu.com> Fri, 09 Dec 2016 12:35:45 +0100
1029+
1030+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu12) zesty; urgency=medium
1031+
1032+ * debian/tests/tgt-boot-test: set HOST_IP to 10.0.2.2; it's suboptimal but
1033+ given the test setup this will allow the right IPs to be used to bring up
1034+ the iscsi target in the xkvm.
1035+
1036+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 08 Dec 2016 11:00:12 +0100
1037+
1038+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu11) zesty; urgency=medium
1039+
1040+ * debian/tests/tgt-boot-test: drop -serial stdio altogether since running
1041+ the VM in -nographics mode will already output to stdout.
1042+
1043+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Tue, 22 Nov 2016 11:27:55 -0500
1044+
1045+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu10) zesty; urgency=medium
1046+
1047+ * debian/tests/tgt-boot-test: always log qemu serial to stdio so we can
1048+ actually see what is going on during the tests.
1049+
1050+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 17 Nov 2016 11:01:27 -0500
1051+
1052+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu9) zesty; urgency=medium
1053+
1054+ [ LaMont Jones ]
1055+ * Clean up net-interface-handler
1056+ * Source /run/net6-*.conf when needed.
1057+
1058+ [ Mathieu Trudel-Lapierre ]
1059+ * debian/extra/initramfs.local-top: handle IPv6 configs being shipped in
1060+ DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
1061+ /run/initramfs/open-iscsi.interface (LP: #1621507)
1062+
1063+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 03 Nov 2016 16:30:37 -0600
1064+
1065+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu8) yakkety; urgency=medium
1066+
1067+ * debian/tests/xkvm: don't --enable-kvm.
1068+
1069+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Wed, 05 Oct 2016 12:58:21 -0400
1070+
1071+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu7) yakkety; urgency=medium
1072+
1073+ * debian/tests/test-open-iscsi.py: glob to pick up open-iscsi.deb, which may
1074+ be named differently depending on how autopkgtests are run.
1075+
1076+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Wed, 05 Oct 2016 09:56:25 -0400
1077+
1078+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu6) yakkety; urgency=medium
1079+
1080+ * debian/tests/test-open-iscsi.py: install the open-iscsi binary into a test
1081+ MAAS image, so we can check bootability. Download the open-iscsi explicitly
1082+ to /tmp before trying to copy it; so that we don't need to depend on ugly
1083+ internal autopkgtest paths.
1084+
1085+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Tue, 04 Oct 2016 09:05:56 -0400
1086+
1087+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu5) yakkety; urgency=medium
1088+
1089+ * debian/tests/control: add build-needed since some of the new tests
1090+ appear to require that (so they can reach open-iscsi.deb which is a build
1091+ artifact from building in autopkgtest).
1092+
1093+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Mon, 03 Oct 2016 16:10:54 -0400
1094+
1095+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu4) yakkety; urgency=medium
1096+
1097+ * add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
1098+ LP: #1621507
1099+
1100+ -- LaMont Jones <lamont@canonical.com> Tue, 20 Sep 2016 08:05:41 -0600
1101+
1102+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu3) xenial; urgency=medium
1103+
1104+ * Cherry-pick from Debian git repository (Christian Seiler):
1105+ - open-iscsi-udeb: drop Depends: libnss-files-udeb (Closes: #819685)
1106+
1107+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 15 Apr 2016 16:54:26 +0100
1108+
1109+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu2) xenial; urgency=medium
1110+
1111+ * debian/tests: add two new tests. One to verify net-interface-handler is
1112+ installed executable, and one to actually test that /etc/resolv.conf is
1113+ updated with dhcp dns responses.
1114+
1115+ -- Diogo Matsubara <diogo.matsubara@gmail.com> Wed, 09 Mar 2016 12:56:42 -0300
1116+
1117+open-iscsi (2.0.873+git0.3b4b4500-14ubuntu1) xenial; urgency=medium
1118+
1119+ * Merge from debian. Remaining changes:
1120+ - debian/tests: Add Ubuntu autopkgtest.
1121+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
1122+ debian/open-iscsi.install:
1123+ Prevent network interface that contains iscsi root from bouncing
1124+ during boot or going down during shutdown.
1125+ Integrates with resolvconf and initramfs code that writes
1126+ /run/initramfs/open-iscsi.interface
1127+ - debian/open-iscsi.maintscript: clean up the obsolete
1128+ iscsi-network-interface upstart job, file on upgrade.
1129+ * make debian/net-interface-handler executable (LP: #1553017)
1130+
1131+ -- Scott Moser <smoser@ubuntu.com> Fri, 04 Mar 2016 13:17:45 -0500
1132+
1133 open-iscsi (2.0.873+git0.3b4b4500-14) unstable; urgency=medium
1134
1135 [ Christian Seiler ]
1136@@ -467,6 +1488,21 @@ open-iscsi (2.0.873+git0.3b4b4500-14) unstable; urgency=medium
1137
1138 -- Christian Seiler <christian@iwakd.de> Thu, 03 Mar 2016 18:47:46 +0100
1139
1140+open-iscsi (2.0.873+git0.3b4b4500-13ubuntu1) xenial; urgency=medium
1141+
1142+ * Merge from Debian (LP: #1546877). Remaining changes:
1143+ - debian/tests: Add Ubuntu autopkgtest.
1144+ - debian/iscsi-network-interface.rules, debian/net-interface-handler,
1145+ debian/open-iscsi.install:
1146+ Prevent network interface that contains iscsi root from bouncing
1147+ during boot or going down during shutdown.
1148+ Integrates with resolvconf and initramfs code that writes
1149+ /run/initramfs/open-iscsi.interface
1150+ - debian/open-iscsi.maintscript: clean up the obsolete
1151+ iscsi-network-interface upstart job, file on upgrade.
1152+
1153+ -- Scott Moser <smoser@ubuntu.com> Thu, 18 Feb 2016 00:53:37 -0500
1154+
1155 open-iscsi (2.0.873+git0.3b4b4500-13) unstable; urgency=medium
1156
1157 [ Christian Seiler ]
1158@@ -688,6 +1724,115 @@ open-iscsi (2.0.873+git0.3b4b4500-1) unstable; urgency=low
1159
1160 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 05 Nov 2013 21:45:47 +0530
1161
1162+open-iscsi (2.0.873-3ubuntu13) wily; urgency=medium
1163+
1164+ * debian/net-interface-handler: Create the resolvconf dir, to avoid failure
1165+ when resolvconf did not start yet; the udev rules run in parallel with
1166+ it. (LP: #1501033)
1167+
1168+ -- Martin Pitt <martin.pitt@ubuntu.com> Tue, 06 Oct 2015 07:05:48 +0200
1169+
1170+open-iscsi (2.0.873-3ubuntu12) wily; urgency=medium
1171+
1172+ * Drop debian/ifup@.service.conf again, it ceased to work with net.agent in
1173+ wily and the whole idea of net-interface-handler is to *stop* ifupdown
1174+ from fiddling with the iscsi interface. Replace with udev rules
1175+ (debian/iscsi-network-interface.rules) which achieves this without relying
1176+ on ifupdown or a particular init system. (LP: #1463461)
1177+ * Drop debian/open-iscsi.iscsi-network-interface.upstart as well, obsolete
1178+ now. Also clean it up on upgrades.
1179+
1180+ -- Martin Pitt <martin.pitt@ubuntu.com> Thu, 11 Jun 2015 11:58:29 +0200
1181+
1182+open-iscsi (2.0.873-3ubuntu11) vivid; urgency=medium
1183+
1184+ * Factor out logic from debian/open-iscsi.iscsi-network-interface.upstart
1185+ into debian/net-interface-handler, and install the latter in debian/rules.
1186+ * Add debian/ifup@.service.conf: Drop-in for ifup@.service to run
1187+ net-interface-handler under systemd. (LP: #1432829)
1188+
1189+ -- Martin Pitt <martin.pitt@ubuntu.com> Fri, 27 Mar 2015 09:51:05 +0100
1190+
1191+open-iscsi (2.0.873-3ubuntu10) vivid; urgency=medium
1192+
1193+ * Start open-iscsi after installation and make sure initiatorname is
1194+ generated. (Patch backported from Debian)
1195+ * debian/tests/daemon: Stop calling the init.d script as we expect the
1196+ daemon to start automatically now.
1197+
1198+ -- Martin Pitt <martin.pitt@ubuntu.com> Fri, 06 Mar 2015 13:17:26 +0100
1199+
1200+open-iscsi (2.0.873-3ubuntu9) trusty; urgency=medium
1201+
1202+ * Add missing python test dependency.
1203+
1204+ -- Martin Pitt <martin.pitt@ubuntu.com> Wed, 26 Feb 2014 16:07:37 +0100
1205+
1206+open-iscsi (2.0.873-3ubuntu8) trusty; urgency=medium
1207+
1208+ * open-iscsi-udeb: Enable builds on armhf, arm64, ppc64el, x32 (LP: #1274203)
1209+
1210+ -- dann frazier <dann.frazier@canonical.com> Wed, 29 Jan 2014 12:34:45 -0700
1211+
1212+open-iscsi (2.0.873-3ubuntu7) saucy; urgency=low
1213+
1214+ * Use dh_autotools-dev to update config.sub|guess.
1215+
1216+ -- Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> Fri, 11 Oct 2013 17:03:37 +0100
1217+
1218+open-iscsi (2.0.873-3ubuntu6) saucy; urgency=low
1219+
1220+ * debian/tests: Add autopkgtest.
1221+
1222+ -- Yolanda <yolanda.robla@canonical.com> Mon, 27 May 2013 10:39:35 +0200
1223+
1224+open-iscsi (2.0.873-3ubuntu5) quantal-proposed; urgency=low
1225+
1226+ * Ensure all udev events have been processed before trying to configure
1227+ iscsi networking in the initramfs (LP: #1066945):
1228+ - debian/extra/initramfs.local-top: Restore wait_for_udev call before
1229+ configure_networking to ensure network devices are present.
1230+
1231+ -- James Page <james.page@ubuntu.com> Wed, 17 Oct 2012 12:37:43 +0100
1232+
1233+open-iscsi (2.0.873-3ubuntu4) quantal-proposed; urgency=low
1234+
1235+ * Generate initiator name on install, not first boot, ensuring that the
1236+ initramfs built during install contains a valid iSCSI initiator name
1237+ resulting in a iSCSI based root volume that will actually boot
1238+ (LP: #1057635):
1239+ - debian/{rules,initiatorname.iscsi}: Don't install a default
1240+ initiatorname.iscsi.
1241+ - debian/open-iscsi.postinst: Generate initiatorname.iscsi on install.
1242+
1243+ -- James Page <james.page@ubuntu.com> Mon, 15 Oct 2012 12:42:53 +0100
1244+
1245+open-iscsi (2.0.873-3ubuntu3) quantal; urgency=low
1246+
1247+ * debian/open-iscsi.iscsi-network-interface.upstart: fix bad syntax
1248+ in 'post-stop'
1249+
1250+ -- Scott Moser <smoser@ubuntu.com> Mon, 17 Sep 2012 16:50:22 -0400
1251+
1252+open-iscsi (2.0.873-3ubuntu2) quantal; urgency=low
1253+
1254+ * debian/extra/initramfs.local-top: start writing
1255+ /run/initramfs/open-iscsi.interface file again (LP: #1050480)
1256+ * debian/open-iscsi.iscsi-network-interface.upstart: integrate with
1257+ resolvconf (LP: #1050487)
1258+
1259+ -- Scott Moser <smoser@ubuntu.com> Mon, 17 Sep 2012 15:46:26 -0400
1260+
1261+open-iscsi (2.0.873-3ubuntu1) quantal; urgency=low
1262+
1263+ * Merge from Debian. Remaining changes: (LP: #961114, LP: #677333)
1264+ - Add upstart job iscsi-network-interface
1265+ - Migrate from /var/run and /lib/init/rw to /run, from /var/lock to
1266+ /run/lock.
1267+ * Turn open-iscsi-utils into a transitional package
1268+
1269+ -- Stéphane Graber <stgraber@ubuntu.com> Tue, 10 Jul 2012 13:53:52 -0400
1270+
1271 open-iscsi (2.0.873-3) unstable; urgency=low
1272
1273 * [4939401] Fix build to install udeb stuff only on supported architectures
1274@@ -862,6 +2007,239 @@ open-iscsi (2.0.871-1) unstable; urgency=low
1275
1276 -- Ritesh Raj Sarraf <rrs@researchut.com> Sat, 06 Feb 2010 20:28:23 +0530
1277
1278+open-iscsi (2.0.871-0ubuntu9) oneiric-proposed; urgency=low
1279+
1280+ * Make sure the upstart job triggers ifupdown's upstart script to avoid
1281+ waiting 2 minutes at boot time for network to come up. (LP: #870214)
1282+
1283+ -- Stéphane Graber <stgraber@ubuntu.com> Tue, 11 Oct 2011 22:31:39 +0100
1284+
1285+open-iscsi (2.0.871-0ubuntu8) oneiric; urgency=low
1286+
1287+ * Disable open-iscsi init script when root is on iscsi (LP: #838809)
1288+
1289+ -- Stéphane Graber <stgraber@ubuntu.com> Thu, 15 Sep 2011 10:01:12 -0400
1290+
1291+open-iscsi (2.0.871-0ubuntu7) oneiric; urgency=low
1292+
1293+ * Migrate from /var/run and /lib/init/rw to /run, from /var/lock to
1294+ /run/lock, and from /dev/.initramfs to /run/initramfs.
1295+
1296+ -- Colin Watson <cjwatson@ubuntu.com> Thu, 14 Jul 2011 17:01:42 +0100
1297+
1298+open-iscsi (2.0.871-0ubuntu6) oneiric; urgency=low
1299+
1300+ * Fix initramfs iSCSI login (many thanks to Amos Hayes for lending me a
1301+ test system; LP: #728088):
1302+ - Write out /dev/.initramfs/open-iscsi.interface in the same subshell as
1303+ configure_networking, so that we can get at the value of DEVICE.
1304+ - Wait for udev to settle before attempting to configure networking.
1305+
1306+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 27 May 2011 23:27:31 +0100
1307+
1308+open-iscsi (2.0.871-0ubuntu5) maverick; urgency=low
1309+
1310+ * Include <sys/types.h> and <sys/stat.h> in usr/iscsi_sysfs.c for S_*
1311+ macros (LP: #600953).
1312+
1313+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 02 Jul 2010 17:08:14 +0100
1314+
1315+open-iscsi (2.0.871-0ubuntu4) lucid; urgency=low
1316+
1317+ * Revert ISCSI_NETDEVICE change; it's normally better to select the
1318+ interface by MAC address (LP: #473036).
1319+
1320+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 05 Feb 2010 12:06:06 -0800
1321+
1322+open-iscsi (2.0.871-0ubuntu3) lucid; urgency=low
1323+
1324+ * If ISCSI_NETDEVICE is set, configure that interface in the initramfs
1325+ (LP: #473036).
1326+
1327+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 22 Jan 2010 17:01:17 +0000
1328+
1329+open-iscsi (2.0.871-0ubuntu2) lucid; urgency=low
1330+
1331+ * Fix handling of ISCSI_USERNAME, ISCSI_PASSWORD, ISCSI_IN_USERNAME, and
1332+ ISCSI_IN_PASSWORD in iscsi.initramfs (closes: #525053).
1333+
1334+ -- Colin Watson <cjwatson@ubuntu.com> Mon, 14 Dec 2009 12:24:42 +0000
1335+
1336+open-iscsi (2.0.871-0ubuntu1) lucid; urgency=low
1337+
1338+ * New upstream release.
1339+ * If the root filesystem is on iSCSI, prevent the network interface used
1340+ for it from being brought up or down automatically (LP: #457767).
1341+ * Backport from upstream:
1342+ - Allow updating of discovery records (Hannes Reinecke).
1343+ - Fix discovery record use, rather than always using iscsid.conf
1344+ settings (Mike Christie).
1345+
1346+ -- Colin Watson <cjwatson@ubuntu.com> Thu, 10 Dec 2009 18:19:20 +0000
1347+
1348+open-iscsi (2.0.870.1-0ubuntu12) karmic; urgency=low
1349+
1350+ * debian/open-iscsi-udeb.finish-install: Stop checking
1351+ disk-detect/iscsi/enable, as that template doesn't exist any more.
1352+
1353+ -- Colin Watson <cjwatson@ubuntu.com> Fri, 02 Oct 2009 18:49:18 +0100
1354+
1355+open-iscsi (2.0.870.1-0ubuntu11) karmic; urgency=low
1356+
1357+ * open-iscsi-utils Replaces: old versions of open-iscsi.
1358+ * SECURITY UPDATE: temporary file vulnerability (LP: #408915)
1359+ - utils/iscsi_discovery: store iscsiadm -m discovery result in a
1360+ variable rather than writing it to an insecurely-created temporary
1361+ file
1362+ - CVE-2009-1297
1363+
1364+ -- Colin Watson <cjwatson@ubuntu.com> Mon, 24 Aug 2009 23:42:10 +0100
1365+
1366+open-iscsi (2.0.870.1-0ubuntu10) karmic; urgency=low
1367+
1368+ * debian/control, debian/open-iscsi-utils.install,
1369+ open-iscsi-utils.manpages : create a new binary package which
1370+ contains /sbin/iscsiadm, needed for some packages to build against
1371+ (eg, libvirt), but not containing the init script, LP: #414986
1372+
1373+ -- Dustin Kirkland <kirkland@ubuntu.com> Tue, 18 Aug 2009 08:11:34 -0500
1374+
1375+open-iscsi (2.0.870.1-0ubuntu9) karmic; urgency=low
1376+
1377+ * debian/open-iscsi.init: don't exit with error if
1378+ /lib/init/rw/sendsigs.omit.d/ doesn't exist (LP: #414986)
1379+
1380+ -- Jamie Strandboge <jamie@ubuntu.com> Mon, 17 Aug 2009 14:12:01 -0500
1381+
1382+open-iscsi (2.0.870.1-0ubuntu8) karmic; urgency=low
1383+
1384+ * Make sure network devices are always included in the initramfs if
1385+ booting with / on iSCSI.
1386+ * Retry initramfs network configuration for a while until it works (LP:
1387+ #237460).
1388+
1389+ -- Colin Watson <cjwatson@ubuntu.com> Tue, 11 Aug 2009 13:05:43 +0100
1390+
1391+open-iscsi (2.0.870.1-0ubuntu7) karmic; urgency=low
1392+
1393+ [ Colin Watson ]
1394+ * debian/open-iscsi-udeb.postinst, debian/open-iscsi-udeb.templates:
1395+ Remove; this is being taken over by disk-detect and partman-iscsi.
1396+ * debian/control: Remove XB-Installer-Menu-Item.
1397+
1398+ [ Mathias Gug ]
1399+ * debian/open-iscsi.postinst: Fix backwards use of update-rc.d (LP:
1400+ #306678).
1401+ * debian/open-iscsi.init: Overwrite existing pid file symlinks in
1402+ /lib/init/rw/sendsigs.omit.d/.
1403+
1404+ -- Colin Watson <cjwatson@ubuntu.com> Mon, 10 Aug 2009 13:28:41 +0100
1405+
1406+open-iscsi (2.0.870.1-0ubuntu6) karmic; urgency=low
1407+
1408+ * utils/iscsi_discovery: Fix several bashisms (test ==, &> redirection,
1409+ trap with numeric signals).
1410+
1411+ -- Colin Watson <cjwatson@ubuntu.com> Tue, 04 Aug 2009 12:30:44 +0100
1412+
1413+open-iscsi (2.0.870.1-0ubuntu5) karmic; urgency=low
1414+
1415+ * utils/iscsi_discovery: replace uses of awk with other shell voodoo, so
1416+ that this works in the installer. LP: #236640.
1417+ * debian/rules, debian/open-iscsi-udeb.dirs: install the open-isci-udeb
1418+ finish script to /usr/lib/finish-install.d, not to /lib/finish-install.d.
1419+ * debian/open-iscsi-udeb.finish-install: copy the config from the root
1420+ to the correct directory in the target.
1421+
1422+ -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 07 Jul 2009 22:10:17 -0700
1423+
1424+open-iscsi (2.0.870.1-0ubuntu4) karmic; urgency=low
1425+
1426+ * debian/extra/initramfs.hook: iscsistart is in /sbin, not /usr/sbin (LP:
1427+ #364616).
1428+
1429+ -- Colin Watson <cjwatson@ubuntu.com> Thu, 02 Jul 2009 14:12:25 +0100
1430+
1431+open-iscsi (2.0.870.1-0ubuntu3) jaunty; urgency=low
1432+
1433+ * Invoke iscsi-iname using normal $PATH lookup rather than using an
1434+ incorrect explicit path (see LP #236640).
1435+
1436+ -- Colin Watson <cjwatson@ubuntu.com> Thu, 09 Apr 2009 16:49:08 +0100
1437+
1438+open-iscsi (2.0.870.1-0ubuntu2) jaunty; urgency=low
1439+
1440+ * debian/control: Drop udeb dependency on crypto-modules; as best as I can
1441+ tell, this is required for crc32c support, which is now built-in to the
1442+ Ubuntu kernels.
1443+
1444+ -- Dustin Kirkland <kirkland@ubuntu.com> Tue, 03 Feb 2009 11:20:35 +0100
1445+
1446+open-iscsi (2.0.870.1-0ubuntu1) jaunty; urgency=low
1447+
1448+ * New upstream release:
1449+ - Support 2.6.26/27 kernels (LP: #289470).
1450+ - Fix iscsid shutdown (LP: #181188).
1451+ * Merge from Debian. Remaining Ubuntu changes:
1452+ - Note: Debian version isn't 870~rc3 but 869.2 which leads to a big
1453+ .diff.gz file. Only files in debian/ have been considered for this merge
1454+ since debian hasn't patched the source.
1455+ - debian/control, debian/rules, debian/open-iscsi-udeb*:
1456+ + Add open-iscsi-udeb.
1457+ - debian/open-iscsi.dirs:
1458+ + rename dirs to open-iscsi.dirs because of open-iscsi-udeb addition.
1459+ + drop network/if-up.d/ directory since we're using symlinks instead.
1460+ + utilities installed in /bin,/sbin rather than /usr/bin,/usr/sbin.
1461+ - debian/open-iscsi.init:
1462+ + utilities installed in /bin,/sbin rather than /usr/bin,/usr/sbin.
1463+ + lsb log messages.
1464+ + Don't generate initiatorname name (moved to postinst).
1465+ + Support for being called from ifup/ifdown scripts.
1466+ + Refactor start functions:
1467+ - move daemon start to startdaemon function.
1468+ - call udevadm settle rather then udevsettle (which doesn't do anything
1469+ useful).
1470+ - don't exit if the daemon is already running during sanitychecks.
1471+ Instead check in startdaemon if the daemon needs to be started.
1472+ - only start automatic targets if necessary.
1473+ - add waitfordevices function: called during rcS, waits for all
1474+ automatic targets to be ready. Iscsi targets are considered as
1475+ local block devices - they don't need to be marked with _netdev in
1476+ fstab. (LP: #227848)
1477+ - start targets if not run from rcS.
1478+ + Check status of iscsid daemon in addition to listing the iscsi sessions
1479+ when status action is called.
1480+ + Add iscsid to the list of processes that should not be killed by
1481+ sendsigs during shutdown (LP: #192080).
1482+ + Add starttargets, stoptargets and restarttargets to usage message.
1483+ - debian/rules:
1484+ + Install utilities /bin,/sbin rather than /usr/bin,/usr/sbin.
1485+ + Start open-iscsi at S25 (waiting for devices created by ifupdown
1486+ calls and before local filesystems are checked and mounted)
1487+ + stop at S41 (after local filesystems are unmounted). Don't use
1488+ umountiscsi.sh script from debian. (LP: #192080).
1489+ - debian/initiatorname.iscsi, debian/open-iscsi.postinst:
1490+ + Generate the random initiatorname during postinstall rather than in the
1491+ init script.
1492+ + Don't ship a default initiatorname.iscsi file.
1493+ - debian/open-iscsi.postinst:
1494+ + fix init script ordering on upgrades.
1495+ - debian/open-iscsi.links:
1496+ + symlink open-iscsi init script in if-up.d and if-down.d directory so
1497+ that the iscsi subsystem is started/stopped when network interfaces
1498+ are configured.
1499+ - debian/open-iscsi.postrm:
1500+ + delete iscsi configuration when the package is purged.
1501+ - utils/iscsi_discovery: De-bashify iscsi_discovery.
1502+ - usr/idbm.c: Fix build failure with new glibc. LP: #299843.
1503+ * Dropped:
1504+ - Exit without error if /sys is not available. Otherwise, it's not possible
1505+ to use this package as a build-dependency (in Debian).
1506+ - Drop upstream url in long description now that it's in the Homepage
1507+ field (in Debian).
1508+
1509+ -- Mathias Gug <mathiaz@ubuntu.com> Mon, 01 Dec 2008 10:45:03 -0500
1510+
1511 open-iscsi (2.0.870~rc3-0.6) unstable; urgency=low
1512
1513 * Non-maintainer upload.
1514@@ -961,6 +2339,47 @@ open-iscsi (2.0.869~rc4-1) experimental; urgency=low
1515
1516 -- Philipp Hug <debian@hug.cx> Sat, 12 Apr 2008 15:53:12 +0200
1517
1518+open-iscsi (2.0.865-1ubuntu5) jaunty; urgency=low
1519+
1520+ * Fix build failure with new glibc. LP: #299843.
1521+
1522+ -- Matthias Klose <doko@ubuntu.com> Thu, 27 Nov 2008 15:58:15 +0100
1523+
1524+open-iscsi (2.0.865-1ubuntu4) intrepid; urgency=low
1525+
1526+ * Exit without error if /sys is not available. Otherwise, it's not possible
1527+ to use this package as a build-dependency.
1528+
1529+ -- Soren Hansen <soren@ubuntu.com> Fri, 02 May 2008 00:57:02 +0200
1530+
1531+open-iscsi (2.0.865-1ubuntu3) hardy; urgency=low
1532+
1533+ * Migration of /usr/{bin,sbin,lib} -> to /{bin,sbin,lib}.
1534+ (LP: #208441)
1535+ * Push the shutdown scripts back. (LP: #196748)
1536+ * Update control to 3.7.3.
1537+ * Updated the maintainer according to spec.
1538+
1539+ -- Chuck Short <zulcss@ubuntu.com> Wed, 09 Apr 2008 18:09:28 -0400
1540+
1541+open-iscsi (2.0.865-1ubuntu2) hardy; urgency=low
1542+
1543+ * Fixed init script to point to the right iscsiadm. (LP: #206520)
1544+
1545+ -- Chuck Short <zulcss@ubuntu.com> Tue, 25 Mar 2008 09:53:08 -0400
1546+
1547+open-iscsi (2.0.865-1ubuntu1) hardy; urgency=low
1548+
1549+ * Add open-iscsi-udeb.
1550+ * Include iscsi_discovery.
1551+ * De-bashify iscsi_discovery.
1552+ * Start open-iscsi in single user mode.
1553+ * Properly lsb-ify init script.
1554+ * Modify Maintainer value to match the DebianMaintainerField
1555+ specification.
1556+
1557+ -- Soren Hansen <soren@ubuntu.com> Fri, 08 Feb 2008 11:56:11 +0100
1558+
1559 open-iscsi (2.0.865-1) unstable; urgency=low
1560
1561 * New upstream release
1562@@ -1023,3 +2442,4 @@ open-iscsi (1.0.485-0unreleased) dapper; urgency=low
1563 * Put database into /var/lib/open-iscsi
1564
1565 -- Philipp Hug <debian@hug.cx> Mon, 6 Mar 2006 19:20:17 +0000
1566+
1567diff --git a/debian/control b/debian/control
1568index df9c66d..0d6915d 100644
1569--- a/debian/control
1570+++ b/debian/control
1571@@ -1,7 +1,8 @@
1572 Source: open-iscsi
1573 Section: net
1574 Priority: optional
1575-Maintainer: Debian iSCSI Maintainers <open-iscsi@packages.debian.org>
1576+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
1577+XSBC-Original-Maintainer: Debian iSCSI Maintainers <open-iscsi@packages.debian.org>
1578 Uploaders:
1579 Ritesh Raj Sarraf <rrs@debian.org>,
1580 Christian Seiler <christian@iwakd.de>,
1581diff --git a/debian/extra/startup-checks.sh b/debian/extra/startup-checks.sh
1582index 5b25b6f..fc91fe2 100755
1583--- a/debian/extra/startup-checks.sh
1584+++ b/debian/extra/startup-checks.sh
1585@@ -33,7 +33,7 @@ if grep -q "^GenerateName=yes" $NAMEFILE ; then
1586 exit 1
1587 fi
1588 # Generate a unique InitiatorName and save it
1589- INAME=`/usr/sbin/iscsi-iname -p iqn.1993-08.org.debian:01`
1590+ INAME=`/sbin/iscsi-iname -p iqn.2004-10.com.ubuntu:01`
1591 if [ "$INAME" != "" ] ; then
1592 echo "## DO NOT EDIT OR REMOVE THIS FILE!" > $NAMEFILE
1593 echo "## If you remove this file, the iSCSI daemon will not start." >> $NAMEFILE
1594diff --git a/debian/open-iscsi.postinst b/debian/open-iscsi.postinst
1595index 0067515..21a20f1 100644
1596--- a/debian/open-iscsi.postinst
1597+++ b/debian/open-iscsi.postinst
1598@@ -20,7 +20,7 @@ case "$1" in
1599 # Generate a unique iSCSI InitiatorName
1600 NAMEFILE=/etc/iscsi/initiatorname.iscsi
1601 if [ ! -e $NAMEFILE ] && [ -z "$2" ] ; then
1602- INAME=$(iscsi-iname -p iqn.1993-08.org.debian:01)
1603+ INAME=$(iscsi-iname -p iqn.2004-10.com.ubuntu:01)
1604 if [ -n "$INAME" ] ; then
1605 echo "## DO NOT EDIT OR REMOVE THIS FILE!" > $NAMEFILE
1606 echo "## If you remove this file, the iSCSI daemon will not start." >> $NAMEFILE
1607diff --git a/debian/patches/fix-format-overflow-warnings.patch b/debian/patches/fix-format-overflow-warnings.patch
1608new file mode 100644
1609index 0000000..456e5e1
1610--- /dev/null
1611+++ b/debian/patches/fix-format-overflow-warnings.patch
1612@@ -0,0 +1,30 @@
1613+Description: fix format overflow warnings
1614+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/open-iscsi/+bug/2036884
1615+Forwarded: https://github.com/open-iscsi/open-iscsi/pull/413
1616+Forwarded: https://github.com/open-iscsi/open-iscsi/pull/425
1617+Author: Chris Leech <cleech@redhat.com>
1618+Author: Graham Inggs <ginggs@debian.org>
1619+Last-Update: 2023-09-22
1620+
1621+--- a/usr/discoveryd.c
1622++++ b/usr/discoveryd.c
1623+@@ -153,8 +153,8 @@
1624+ */
1625+ list_for_each_entry_safe(rec, tmp_rec, &iscsi_targets, list) {
1626+ log_debug(7, "Trying to match %s %s to %s %s %s",
1627+- targetname, iname, rec->name, rec->conn[0].address,
1628+- rec->iface.name);
1629++ targetname ? targetname : "(null)", iname ? iname : "(null)",
1630++ rec->name, rec->conn[0].address, rec->iface.name);
1631+ if (targetname && strcmp(rec->name, targetname))
1632+ continue;
1633+
1634+@@ -169,7 +169,7 @@
1635+ }
1636+
1637+ log_debug(5, "Matched %s %s, checking if in new targets.",
1638+- targetname, iname);
1639++ targetname ? targetname : "(null)", iname ? iname : "(null)");
1640+ if (!idbm_find_rec_in_list(new_rec_list, rec->name,
1641+ rec->conn[0].address,
1642+ rec->conn[0].port, &rec->iface)) {
1643diff --git a/debian/patches/series b/debian/patches/series
1644index 138a4b7..1b40fc2 100644
1645--- a/debian/patches/series
1646+++ b/debian/patches/series
1647@@ -1,3 +1,4 @@
1648 debian/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
1649 debian/multiarch-path.patch
1650 exec_prefix.patch
1651+fix-format-overflow-warnings.patch
1652diff --git a/debian/tests/README-boot-test.md b/debian/tests/README-boot-test.md
1653new file mode 100644
1654index 0000000..e45bbf0
1655--- /dev/null
1656+++ b/debian/tests/README-boot-test.md
1657@@ -0,0 +1,139 @@
1658+## open-iscsi boot test
1659+The purpose of this test (`CloudImageTest`) is to test the boot of a system
1660+using an iscsi root target. In order to accomplish that, the tests does
1661+
1662+ 1. Download Ubuntu cloud image
1663+ 2. installs the open-iscsi deb inside
1664+ 3. collect kernel and initramfs from inside
1665+ 4. register the image as a read-only iscsi target served by tgt
1666+ 5. boot kernel and initramfs with a command line to use the image as root.
1667+ And additionally attach a local disk for collecting output.
1668+ 6. provide user-data that executes commands, colects files and writes them
1669+ to the output disk and then shuts the system down.
1670+ 7. extract the collected files from the output disk and inspect them.
1671+
1672+The `CloudImageTest` uses qemu user networking.
1673+
1674+
1675+## Caveats
1676+
1677+ 1. It depends on a cloud-image being present.
1678+
1679+ Cloud-images are often not available for the first few weeks of a cycle.
1680+ If no cloud-image of 'REL' is available, then boot-test will skip.
1681+ If 'REL' is not known in distro-info-data, then test will fail.
1682+
1683+ This means that uploads of open-iscsi (or its dependencies) will not
1684+ be properly tested until a cloud-image is available, and will fail
1685+ until distro-info-data is uploaded.
1686+
1687+ 2. Installation of large packages via patch-image may fail.
1688+ An ubuntu image downloaded has only a small amount of extra space.
1689+ Installation of a new kernel into the target would probably fail.
1690+
1691+ If this becomes a problem, we could grow the disk like done at
1692+ https://gist.github.com/smoser/6a048a0e2795b48221fc44962202fa14
1693+
1694+
1695+### testing manually ###
1696+The test case in `debian/tests/test-open-iscsi.py` uses some helper tools.
1697+
1698+ * **patch-image**: this is used to install packages into the pristine image
1699+ and collect the kernel and initramfs out of the image. This allows us to
1700+ test the portions of open-iscsi that update the initramfs. Without
1701+ using the updated initramfs we wouldn't really be testing the new
1702+ open-iscsi.
1703+
1704+ It will upgrade any packages inside that are mentioned in
1705+ ADT_TEST_TRIGGERS environment. It will also install open-iscsi if
1706+ it is not in that list.
1707+
1708+ It installs packages into the target by copying the host system's
1709+ /etc/apt content in, and also includes copying local (file://) apt
1710+ repos into the target. This is necessary for the autopackage test
1711+ environment that adds local package repositories to sources.list.d.
1712+
1713+ It may also make other changes to the image to workaround bugs.
1714+ See --help output for list of bugs.
1715+
1716+ * **get-image**: This downloads an image from cloud-images.ubuntu.com. See
1717+ its Usage for more information. it downloads via stream data and verifies
1718+ download. One thing to note is that it does not overwrite existing files.
1719+
1720+ * **tgt-boot-test**: this registers an image in tgt locally, and then boots
1721+ kernel and initramfs to mount that. It knows how to build iscsi kernel
1722+ command lines.
1723+
1724+ By default, the xkvm process that is started will be allowed `60m` to
1725+ complete. This can be adjusted by setting `BOOT_TIMEOUT` in the
1726+ environment.
1727+
1728+ * **xkvm**: this is a helper/wrapper around qemu. It is taken from the curtin
1729+ projects tools/ directory. It allows some simplified command lines, and
1730+ most usefully, the '--netdev=<bridge>' argument will create a tun/tap
1731+ device and attach it to the bridge.
1732+
1733+ If the host system is not bare metal, kvm will not be
1734+ enabled in the guest that is lauched. To force use of kvm, set
1735+ _USE_KVM=1 in the environment. See 'should_try_kvm' in xkvm for details.
1736+
1737+Testing manually looks like this:
1738+
1739+ ## set up path to include debian/tests directory.
1740+ $ PATH=$PWD/debian/tests:$PATH
1741+
1742+ ## Get the image you want. This creates out.d/disk.img and disk.img.dist
1743+ $ get-image xenial.d xenial
1744+
1745+ ## patch the image with an open-iscsi, which creates xenial.d/kernel
1746+ ## and xenial.d/initrd from the kernel and initramfs inside the image.
1747+ $ apt-get download open-iscsi
1748+ $ deb=$(ls open-iscsi_*.deb | tail -n 1)
1749+ $ sudo ./debian/tests/patch-image \
1750+ --kernel=xenial.d/kernel --initrd=xenial.d/initrd
1751+ xenial.d/disk.img "$deb"
1752+
1753+ ## Boot the system, log in, look around.
1754+ $ tgt-boot-test -v xenial.d/disk.img xenial.d/kernel xenial.d/initrd
1755+
1756+
1757+### Features of tgt-boot-test ###
1758+
1759+tgt-boot-test does a number of useful things.
1760+
1761+ * determines the host address that the guest will use.
1762+ This should support ipv6 and ipv4 addresses on bridges, and
1763+ knows values that qemu's user networking uses. Flags passed to `--netdev`
1764+ are read intelligently. This can be overriden with `--host-addr`, but
1765+ it does a good job of determining what the right values are.
1766+
1767+ * provides a nocloud metadata service with a python web server that
1768+ supports ipv4 and ipv6.
1769+
1770+ * provides the ability to provide additional kernel command line options
1771+ or to provide a 'template' that references variables it knows such as
1772+ {iserver} (iscsi server) or {seed_url}.
1773+
1774+ * Sets ubuntu (passw0rd) and root password (root) and imports users
1775+ ssh keys to the ubuntu user.
1776+
1777+One thing to note is that yakkety's version of qemu does not run an ipv6
1778+dhcp server on its user-network, so a stateful dhclient request will not
1779+work.
1780+
1781+In order to create a bridge easily with a ipv6 dhcp server, you can use
1782+lxd at sufficent version (https://github.com/lxc/lxd/issues/2481).
1783+Assuming that bug is fixed, to create an ipv6 only bridge:
1784+
1785+ $ netname="ipv6-only"
1786+ $ lxc network create $netname
1787+ $ lxc network unset $netname ipv4.address
1788+ $ lxc network unset $netname ipv4.nat
1789+ $ lxc network set $netname ipv6.dhcp.stateful true
1790+
1791+Then, you can use tgt-boot-test with that:
1792+
1793+ $ PATH=$PWD/debian/tests:$PATH
1794+ $ ./debian/tests/tgt-boot-test -vv --netdev=ipv6-only \
1795+ --cmdline-ip="ip=off ip6=dhcp" \
1796+ disk.img kernel initramfs
1797diff --git a/debian/tests/control b/debian/tests/control
1798index 4285726..31aa114 100644
1799--- a/debian/tests/control
1800+++ b/debian/tests/control
1801@@ -1,6 +1,10 @@
1802 Tests: install
1803 Restrictions: needs-root, isolation-machine, breaks-testbed
1804
1805+Tests: testsuite
1806+Restrictions: needs-root isolation-machine breaks-testbed
1807+Depends: open-iscsi, python3, tgt, qemu-system, ubuntu-cloudimage-keyring, simplestreams, python3-netifaces, distro-info, cloud-image-utils, dctrl-tools, rsync
1808+
1809 Tests: nested
1810 Restrictions: needs-root, isolation-machine, breaks-testbed, allow-stderr
1811 Depends:
1812diff --git a/debian/tests/get-image b/debian/tests/get-image
1813new file mode 100755
1814index 0000000..41b903c
1815--- /dev/null
1816+++ b/debian/tests/get-image
1817@@ -0,0 +1,227 @@
1818+#!/bin/bash
1819+Usage() {
1820+ cat <<EOF
1821+${0##*/} out-directory release
1822+
1823+By default, the cloud image for 'release' is downloaded from the
1824+daily cloud image stream.
1825+
1826+Additional arguments can change behavior of what is downloaded.
1827+Some supported arguments:
1828+ * cloud-daily: use daily stream [default]
1829+ * cloud-release: use release stream rather than daily stream.
1830+ * maas-release, maas-daily: download maas images instead of cloud-image
1831+ * hwe-N: download the hwe kernel from release 'N' instead of default
1832+ this is only respected if maas stream is used.
1833+ * YYYYMMDD[.X] : download the specific build version
1834+
1835+example:
1836+ ${0##*/} xenial_dir xenial cloud-daily
1837+EOF
1838+}
1839+TEMP_D=""
1840+
1841+NO_IMAGE_AVAILABLE_RC=3
1842+
1843+cleanup() {
1844+ [ ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
1845+}
1846+VERBOSITY=1
1847+inargs() {
1848+ local n=$1 x="";
1849+ shift;
1850+ for x in "$@"; do [ "$n" = "$x" ] && return 0; done;
1851+ return 1
1852+}
1853+debug() { [ $1 -ge $VERBOSITY ] || return 0; shift; echo "$@" 1>&2; }
1854+error() { echo "$@" 1>&2; }
1855+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
1856+
1857+VERBOSITY=0
1858+TEMP_D=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) || exit 1
1859+trap cleanup EXIT
1860+
1861+arches=( ppc64el i386 amd64 )
1862+releases=( $(ubuntu-distro-info --all) )
1863+mbase="http://maas.ubuntu.com/images/ephemeral-v2"
1864+cbase="http://cloud-images.ubuntu.com"
1865+def_stream_type="cloud"
1866+stream_src=""
1867+curbase="$mbase"
1868+def_rel="xenial"
1869+vername=""
1870+
1871+[ "$1" = "-h" -o "$1" = "--help" ] && { Usage; exit 0; }
1872+[ $# -lt 2 ] && { Usage 1>&2; exit 1; }
1873+out_d="$1"
1874+shift
1875+
1876+myarch=$(uname -m)
1877+case "$myarch" in
1878+ ppc64*) def_arch="ppc64el";;
1879+ i?86) def_arch="i386";;
1880+ x86_64) def_arch="amd64";;
1881+ arm*) def_arch="armel";;
1882+esac
1883+
1884+pt=( )
1885+for x in "$@"; do
1886+ inargs "$x" "${arches[@]}" && pt[${#pt[@]}]=arch=$x && arch="$x" && continue
1887+ inargs "$x" "${releases[@]}" && pt[${#pt[@]}]="release=$x" && release=$x && continue
1888+ [ "$x" = "released" -o "$x" = "release" ] && x="releases"
1889+ case "$x" in
1890+ cloud-released|cloud-release) x="cloud-releases";;
1891+ maas-released|maas-release) x="maas-releases";;
1892+ esac
1893+
1894+ case "$x" in
1895+ maas|cloud) stream_type="$x";;
1896+ cloud-daily|maas-daily|cloud-releases|maas-releases)
1897+ stream_type="${x%-*}"
1898+ stream_sub=${x#*-};;
1899+ http://*) stream=$x;;
1900+ hwe-*) subarch="$x";;
1901+ subarch=*) subarch=${x#*=};;
1902+ *=*) pt[${#pt[@]}]="$x";;
1903+ *~*) pt[${#pt[@]}]="$x";;
1904+ [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].[0-9])
1905+ pt[${#pt[@]}]="version_name=$x"
1906+ vername="$x";;
1907+ *) fail "Confused by input token '$x'";;
1908+ esac
1909+done
1910+
1911+[ -n "$stream_type" ] || stream_type="${def_stream_type}"
1912+if [ -z "$stream" ]; then
1913+ stream_sub=${stream_sub:-daily}
1914+ case "$stream_type" in
1915+ maas) stream="$mbase/$stream_sub";;
1916+ cloud) stream="$cbase/$stream_sub";;
1917+ *) fail "unknown stream_type '$stream_type'";;
1918+ esac
1919+fi
1920+
1921+[ -n "$arch" ] || pt[${#pt[@]}]="arch=$def_arch"
1922+
1923+if [ "$stream_type" = "maas" ]; then
1924+ if [ -z "$subarch" ]; then
1925+ t=${release#?}
1926+ first_letter=${release%${t}}
1927+ subarch="hwe-${first_letter}"
1928+ error "selected subarch=${subarch} for $release"
1929+ fi
1930+ pt[${#pt[@]}]="subarch=$subarch"
1931+ ofmt="%(sha256)s %(ftype)s %(subarch)s %(item_url)s"
1932+else
1933+ ofmt="%(sha256)s %(ftype)s %(item_url)s"
1934+fi
1935+
1936+OIFS="$IFS"
1937+mkdir -p "$out_d"
1938+case "$stream" in
1939+ *.json) :;;
1940+ *) keyring="/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg";;
1941+esac
1942+
1943+needs=""
1944+[ -n "$keyring" -a ! -f "$keyring" ] &&
1945+ needs="${needs} ubuntu-cloudimage-keyring"
1946+
1947+for pair in sstream-query:simplestreams tgt-admin:tgt; do
1948+ cmd=${pair%:*}
1949+ pkg=${pair#*:}
1950+ command -v "$cmd" >/dev/null 2>&1 || needs="$needs $pkg"
1951+done
1952+
1953+if [ -n "${needs# }" ]; then
1954+ error "missing dependencies"
1955+ fail "sudo apt-get install -qy ${needs# }"
1956+fi
1957+
1958+qcmd=( sstream-query ${keyring:+"--keyring=$keyring"} ${vername:---max=1}
1959+ --output-format="$ofmt" "${stream}" datatype="image-downloads"
1960+ "${pt[@]}" )
1961+echo "${qcmd[@]}"
1962+"${qcmd[@]}" > "${TEMP_D}/qout"
1963+roots=$(awk '$2 == "root-image.gz" || $2 == "disk1.img" { print $2 }' \
1964+ "${TEMP_D}/qout" | sort -u | wc -l)
1965+if [ "$roots" = "0" ]; then
1966+ error "No image available for $release in $stream${pt:+ (${pt[*]})}"
1967+ exit ${NO_IMAGE_AVAILABLE_RC}
1968+elif [ "$roots" != "1" ]; then
1969+ error "query resulted in '$roots' root images. expect 1 and only 1"
1970+ error "cmd was ${qcmd[*]}"
1971+ cat "${TEMP_D}/qout"
1972+ fail
1973+fi
1974+
1975+set -f
1976+while read line; do
1977+ set -- $line
1978+ if [ "$stream_type" = "maas" ]; then
1979+ sha256="$1"; ftype="$2"; subarch="$3"; url="$4"
1980+ else
1981+ sha256="$1"; ftype="$2"; url="$3"
1982+ fi
1983+ case "$ftype" in
1984+ boot-kernel|boot-initrd|root-image.gz|disk1.img) :;;
1985+ *) continue
1986+ esac
1987+ if [ "$ftype" = "root-image.gz" ]; then
1988+ fname="$ftype"
1989+ image_src="$out_d/$fname"
1990+ image="$out_d/root-image"
1991+ elif [ "$ftype" = "disk1.img" ]; then
1992+ fname="disk.img.dist"
1993+ image_src="$out_d/$fname"
1994+ image="$out_d/disk.img"
1995+ else
1996+ fname="$subarch/$ftype"
1997+ fi
1998+ out_f="${out_d}/$fname"
1999+ if [ -f "$out_f" ]; then
2000+ debug 1 "reusing existing '$out_f' rather than downloading $url."
2001+ continue
2002+ fi
2003+ [ -d "${out_f%/*}" ] || mkdir -p "${out_f%/*}"
2004+ tmp="${out_f}.tmp"
2005+ wget --progress=dot:mega -O "$tmp" "$url" || {
2006+ error "Failed to download $url to $tmp."
2007+ rm -f "$tmp"
2008+ exit 3
2009+ }
2010+ debug 1 "checksumming $tmp from $url"
2011+ out=$(sha256sum "$tmp") || {
2012+ error "Failed to checksum $tmp"
2013+ rm -f "$tmp"
2014+ exit 3;
2015+ }
2016+ found=${out% *}
2017+ if [ "$found" != "$sha256" ]; then
2018+ error "$tmp from $url found sha256 of $found. expected $sha256."
2019+ ls -l "$tmp" 1>&2
2020+ rm -f "$tmp"
2021+ exit 3
2022+ fi
2023+ mv "$tmp" "$out_f" || fail "failed renaming $tmp to $out_f"
2024+ echo "$fname" "$url" >> "$out_d/contents"
2025+done < "${TEMP_D}/qout"
2026+
2027+if [ ! -f "$image" ]; then
2028+ case "$image_src" in
2029+ */root-image.gz)
2030+ debug 1 "decompressing $image_src"
2031+ zcat "$image_src" > "$image.tmp" &&
2032+ mv "$image.tmp" "$image" ||
2033+ { rm -f "$image.tmp"; exit 1; }
2034+ ;;
2035+ */disk.img.dist)
2036+ debug 1 "converting qcow2 in $image_src -> raw in $image"
2037+ qemu-img convert -O raw "$image_src" "$image.tmp" &&
2038+ mv "$image.tmp" "$image" ||
2039+ { rm -f "$image.tmp"; exit 1; }
2040+ ;;
2041+ esac
2042+fi
2043+
2044+# vi: ts=4 expandtab
2045diff --git a/debian/tests/install b/debian/tests/install
2046index 5077b7b..22a5cea 100755
2047--- a/debian/tests/install
2048+++ b/debian/tests/install
2049@@ -18,7 +18,7 @@ die_with_file()
2050 exit 1
2051 }
2052
2053-DEBIAN_FRONTEND=noninteractive apt-get -y install open-iscsi </dev/null
2054+DEBIAN_FRONTEND=noninteractive apt-get -y purge open-iscsi && apt-get -y install open-iscsi </dev/null
2055
2056 [ -d /etc/iscsi ] || die "/etc/iscsi not a directory"
2057
2058diff --git a/debian/tests/patch-image b/debian/tests/patch-image
2059new file mode 100755
2060index 0000000..f8d6988
2061--- /dev/null
2062+++ b/debian/tests/patch-image
2063@@ -0,0 +1,381 @@
2064+#!/bin/bash
2065+
2066+VERBOSITY=1
2067+TEMP_D=""
2068+
2069+error() { echo "$@" 1>&2; }
2070+fail() { local r=$?; [ $r -eq 0 ] && r=1; failrc "$r" "$@"; }
2071+failrc() { local r=$1; shift; [ $# -eq 0 ] || error "$@"; exit $r; }
2072+
2073+Usage() {
2074+ cat <<EOF
2075+Usage: ${0##*/} [options] image [packages]
2076+ Patch image, upgrading [packages].
2077+ --kernel FILE copy kernel out to FILE
2078+ --initrd FILE copy initrd out to FILE
2079+
2080+ --krd-only only copy out kernel/initrd do not change image.
2081+ this is incompatible with 'packages'
2082+ it is a short-cut to specifying all the '--no-*'
2083+ options below.
2084+
2085+ --no-copy-apt do not copy host's apt repos in.
2086+
2087+ image modifications:
2088+ --no-update-fstab do not modify fstab (LP: #1732028)
2089+
2090+ if no packages are provided, and ADT_TEST_TRIGGERS is set
2091+ in environment, then it will be read for the list of packages.
2092+ to override that behavior pass package 'none'.
2093+EOF
2094+
2095+}
2096+
2097+bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
2098+cleanup() {
2099+ [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
2100+}
2101+
2102+debug() {
2103+ local level=${1}; shift;
2104+ [ "${level}" -gt "${VERBOSITY}" ] && return
2105+ error "${@}"
2106+}
2107+
2108+adt_test_triggers_to_bin_pkgs() {
2109+ # ADT_TEST_TRIGGERS is space delimited <src>/version
2110+ # returns a scalar '_RET', caller has to expand
2111+ local tok src="" ver="" binpkgs=""
2112+ for tok in "$@"; do
2113+ src=${tok%/*}
2114+ ver=${tok#*/}
2115+ bin_packages_from_source_pkg "$src" "$ver" || return
2116+ if [ -z "${_RET}" ]; then
2117+ error "$tok: (source=$src ver=$ver) No packages available!"
2118+ return 1
2119+ fi
2120+ binpkgs="${binpkgs} ${_RET}"
2121+ done
2122+ _RET=${binpkgs# }
2123+}
2124+
2125+bin_packages_from_source_pkg() {
2126+ local pkg=$1 ver=${2} cmd="" out="" p="" ret=""
2127+ if ! command -v grep-aptavail >/dev/null; then
2128+ error "No command grep-aptavail: apt-get install dctrl-tools"
2129+ return 1
2130+ fi
2131+ cmd=( grep-aptavail --show-field=Package
2132+ --exact-match --field=Source:Package "$pkg" )
2133+ if [ -n "$ver" ]; then
2134+ cmd=( "${cmd[@]}" --and --field=Version "$ver" )
2135+ fi
2136+ out=$("${cmd[@]}" | sed 's,Package: ,,')
2137+ ret=""
2138+ for p in $out; do
2139+ ret="$ret ${p#Package: }${ver:+=${ver}}"
2140+ done
2141+ # if no version was provided, we could have multiple results
2142+ _RET=$(set -f; for i in ${ret}; do echo "$i"; done | sort -u)
2143+}
2144+
2145+update_fstab() {
2146+ # update_fstab(path) modify the fstab at path
2147+ # to remove problematic entries (LP: #1732028)
2148+ local fstab="$1"
2149+ if [ ! -e "$fstab.patch-image-dist" ]; then
2150+ cp "$fstab" "$fstab.patch-image-dist" ||
2151+ { error "failed backing up $fstab to $fstab.dist"; return 1; }
2152+ fi
2153+ sed -i '/^LABEL=UEFI/s/^/#/' "$fstab"
2154+}
2155+
2156+cat_debug_script() {
2157+ cat <<"EOF"
2158+#!/bin/sh
2159+set -f
2160+NAME=${1:-debug-pid-$$}
2161+[ "$(id -u)" = "0" ] && log="/run/${NAME}.log" || log="/tmp/${NAME}.log"
2162+
2163+msg() {
2164+ echo "===" "$@" "===" 1>&2
2165+}
2166+showcmd() {
2167+ msg "showcmd$" "$@"
2168+ "$@"
2169+}
2170+
2171+main() {
2172+ issues=$(journalctl | egrep "[.]mount: ")
2173+ if [ -z "$issues" ]; then
2174+ msg "$NAME:" "MOUNT ISSUES FOUND: NO"
2175+ else
2176+ msg "$NAME:" "MOUNT ISSUES FOUND: YES"
2177+ fi
2178+ showcmd systemctl list-units --no-pager --all --full "*.mount"
2179+ showcmd systemctl cat --no-pager --all --full "*.mount"
2180+ showcmd systemctl status --no-pager --all --full "*.mount"
2181+ showcmd cat /etc/fstab
2182+ showcmd cat /proc/1/mountinfo
2183+}
2184+
2185+main > "$log" 2>&1
2186+echo "============ $NAME ============="
2187+cat "$log"
2188+EOF
2189+}
2190+
2191+add_systemd_job() {
2192+ local target="$1" name="$2" after="$3" start="$4"
2193+ local spath="lib/systemd/system/xdebug-$name.service"
2194+ debug 1 "writing $name to $target/$spath"
2195+ cat > "$target/$spath" <<EOF
2196+[Unit]
2197+Description=Execute xdebug ${name}
2198+After=${after}
2199+
2200+[Service]
2201+Type=oneshot
2202+ExecStart=${start} ${name}
2203+RemainAfterExit=yes
2204+StandardOutput=journal+console
2205+
2206+[Install]
2207+WantedBy=multi-user.target
2208+EOF
2209+ [ $? -eq 0 ] || { error "failed writing $target/$spath"; return 1; }
2210+ local wantsdir="$target/etc/systemd/system/multi-user.target.wants"
2211+ ln -s "/$spath" "$wantsdir/" ||
2212+ { error "failed ln -s '/$spath' '$wantsdir/'"; return 1; }
2213+}
2214+
2215+insert_debug_1788188() {
2216+ # This is an attempt to collect more debug information in the
2217+ # event that the tests trigger LP: #1788188.
2218+ local target="$1"
2219+ [ "$target" = "/" -o -z "$target" ] &&
2220+ { error "target was / in insert_debug"; return 1; }
2221+ local script="usr/local/bin/debug-mounts"
2222+ cat_debug_script > "$target/$script" &&
2223+ chmod 755 "$target/$script" ||
2224+ { error "failed writing $target/script"; return 1; }
2225+ local name=""
2226+ ( set +f;
2227+ rm -f "$target/lib/systemd/system/xdebug"-*.service \
2228+ "$target/etc/systemd/system/"*.wants/xdebug*.service )
2229+ add_systemd_job "$target" network network-online.target "/$script" &&
2230+ add_systemd_job "$target" local-fs local-fs.target "/$script" ||
2231+ { error "failed adding systemd jobs"; return 1; }
2232+}
2233+
2234+main() {
2235+ local short_opts="hv"
2236+ local long_opts="help,no-copy-apt,initrd:,kernel:,verbose"
2237+ local getopt_out="" orig_args=""
2238+ orig_args=( "$@" )
2239+ getopt_out=$(getopt --name "${0##*/}" \
2240+ --options "${short_opts}" --long "${long_opts}" -- "$@") &&
2241+ eval set -- "${getopt_out}" ||
2242+ { bad_Usage; return; }
2243+
2244+ local cur="" next=""
2245+ local kernel="" initrd="" copy_apt=true krd_only=false
2246+ local update_fstab=true
2247+
2248+ while [ $# -ne 0 ]; do
2249+ cur="$1"; next="$2";
2250+ case "$cur" in
2251+ -h|--help) Usage ; exit 0;;
2252+ --krd-only) krd_only=true; shift;;
2253+ --no-copy-apt) copy_apt=false; shift;;
2254+ --no-update-fstab) update_fstab=false; shift;;
2255+ --kernel) kernel=$next; shift;;
2256+ --initrd) initrd=$next; shift;;
2257+ -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
2258+ --) shift; break;;
2259+ esac
2260+ shift;
2261+ done
2262+
2263+ [ $# -ne 0 ] || { bad_Usage "must provide at least image"; return; }
2264+
2265+ [ "$(id -u)" = "0" ] || fail "not root"
2266+ target="$1"
2267+ shift
2268+ if [ -f "$target" ]; then
2269+ local nargs=""
2270+ nargs=( "${orig_args[@]}" )
2271+ # replace the first occurance of target in orig args with _MOUNTPOINT_
2272+ for((i=0;i<${#nargs[@]};i++)); do
2273+ [ "${nargs[$i]}" = "$target" ] && nargs[$i]=_MOUNTPOINT_ && break
2274+ done
2275+ debug 1 "mic $target -- $0 ${nargs[*]}"
2276+ IMAGE="$target" exec mount-image-callback \
2277+ --system-resolvconf "$target" -- "$0" "${nargs[@]}"
2278+ fi
2279+
2280+ if [ ! -d "$target" ]; then
2281+ fail "$target: not a directory or file"
2282+ fi
2283+
2284+ local tsrc=${IMAGE:-${target}}
2285+ local packages=( )
2286+ packages=( "$@" )
2287+
2288+ if $krd_only; then
2289+ if [ "${#packages[@]}" != 0 -a "${packages[*]}" != "none" ]; then
2290+ error "--krd-only is incompatible with packages."
2291+ return 1
2292+ fi
2293+ debug 1 "--krd-only provided no changes will be done."
2294+ copy_apt=false
2295+ update_fstab=false
2296+ packages=( "none" )
2297+ fi
2298+
2299+ if [ "${#packages[@]}" = "1" -a "${packages[0]}" = "none" ]; then
2300+ packages=( )
2301+ elif [ "${#packages[@]}" -eq 0 -a -n "${ADT_TEST_TRIGGERS}" ]; then
2302+ adt_test_triggers_to_bin_pkgs ${ADT_TEST_TRIGGERS} ||
2303+ fail "failed to find binary packages " \
2304+ "from ADT_TEST_TRIGGERS=$ADT_TEST_TRIGGERS"
2305+ packages=( $_RET )
2306+ debug 1 "read ADT_TEST_TRIGGERS=$ADT_TEST_TRIGGERS to set" \
2307+ "packages=${packages[*]}"
2308+ else
2309+ local opackages="" debs="" pkg=""
2310+ opackages=( "${packages[@]}" )
2311+ packages=( )
2312+ debs=( )
2313+ for pkg in "${opackages[@]}"; do
2314+ [ -f "${pkg}" ] && debs[${#debs[@]}]="$pkg" ||
2315+ packages[${packages[@]}]="$pkg"
2316+ done
2317+ if [ "${#packages[@]}" -eq 0 -a "${#debs[@]}" -eq 0 ]; then
2318+ packages=( open-iscsi )
2319+ debug 1 "no packages or debs given, using packages=${packages[*]}"
2320+ fi
2321+ fi
2322+
2323+ # if open-iscsi is not in the packages list above, we handle it specifically
2324+ # so that even if the image did not have open-iscsi, it will get it.
2325+ local pkg="" mypkg="open-iscsi"
2326+ for pkg in "${packages[@]}"; do
2327+ case "$pkg" in
2328+ open-iscsi|open-iscsi/*) mypkg="none";;
2329+ esac
2330+ done
2331+
2332+ TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
2333+ fail "failed to make tempdir"
2334+ trap cleanup EXIT
2335+
2336+ if $copy_apt; then
2337+ local distdir="${target}/etc/apt.dist.${0##*/}"
2338+ if [ ! -d "$distdir" ]; then
2339+ mv "$target/etc/apt" "$distdir" ||
2340+ fail "failed to backup /etc/apt in $tsrc"
2341+ fi
2342+ cp -a /etc/apt "$target/etc/" ||
2343+ fail "failed to replace /etc/apt in $tsrc"
2344+
2345+ # find file:// repos in apt sources and copy them in
2346+ local file_repos=""
2347+ file_repos=$(
2348+ fm='s,.*[[:space:]]file:///*\([^[[:space:]]*\).*,/\1,p'
2349+ shopt -s nullglob
2350+ for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list; do
2351+ sed -n -e 's/#.*//' -e "$fm" "$f"
2352+ done
2353+ )
2354+ local dir="" bdir="" tdir=""
2355+ for dir in ${file_repos}; do
2356+ tdir="${target}$(dirname $dir)/$(basename ${dir})"
2357+ if [ -d "$dir" ]; then
2358+ debug 1 "copying $dir -> $tdir"
2359+ mkdir -p "$tdir" ||
2360+ fail "failed to create $tdir"
2361+ rsync --delete -a "$dir/" "$tdir" ||
2362+ fail "failed copy from $dir/ to $tdir"
2363+ fi
2364+ done
2365+ fi
2366+
2367+ if $update_fstab; then
2368+ update_fstab "$target/etc/fstab" ||
2369+ { error "failed updating /etc/fstab in target"; return 1; }
2370+ fi
2371+
2372+ insert_debug_1788188 "$target" || return 1
2373+
2374+ mount -o bind /sys "$target"/sys || :
2375+ mount -o bind /proc "$target"/proc || :
2376+ mount -o bind /dev "$target"/dev || :
2377+ mount -o bind /dev/pts "$target"/dev/pts || :
2378+
2379+ debug 1 "${#packages[@]} packages: ${packages[*]}"
2380+ if [ "${#packages[@]}" != "0" ]; then
2381+ DEBIAN_FRONTEND=noninteractive chroot "$target" sh -exc '
2382+ mypkg=$1
2383+ shift
2384+ apt-get update -q
2385+ if [ "$mypkg" != "none" ]; then
2386+ apt-get install -qy "$mypkg"
2387+ fi
2388+ apt-get install -qy --only-upgrade "$@"' \
2389+ chroot-inst "$mypkg" "${packages[@]}" ||
2390+ fail "failed to install ${packages[*]} in $target"
2391+ fi
2392+
2393+ debug 1 "${#debs[@]} debs: ${debs[*]}"
2394+ if [ "${#debs[@]}" != "0" ]; then
2395+ local tmpd=""
2396+ tmpd=$(mktemp -d "${target}/tmp/${0##*/}.XXXXXX")
2397+ cp "${debs[@]}" "$tmpd"
2398+ DEBIAN_FRONTEND=noninteractive chroot "$target" sh -exc \
2399+ 'cd "$1"; shift; dpkg -i *.deb' debinstalls "${tmpd#${target}}"
2400+ rm -Rf "${tmpd}"
2401+ fi
2402+
2403+ umount "$target"/dev/pts || :
2404+ umount "$target"/dev || :
2405+ umount "$target"/proc || :
2406+ umount "$target"/sys || :
2407+
2408+ local kpath="" ipath=""
2409+ if [ -z "$(ls -A "$target"/boot)" ]; then
2410+ # If /boot is empty, most likely there is a separate
2411+ # /boot partition in the image. This assumes it to be
2412+ # the last one in the list of partitions.
2413+ local device="$(find /dev/nbd*p* | sort | tail -n 1)"
2414+ mount "$device" "$target"/boot
2415+ fi
2416+ for f in "$target/boot/"*; do
2417+ case "${f##*/}" in
2418+ *.signed) continue;;
2419+ vmlinu?-*) kpath="$f";;
2420+ initrd.img-*) ipath="$f";;
2421+ esac
2422+ done
2423+
2424+ if [ -n "$kernel" ]; then
2425+ [ -n "$kpath" ] || fail "unable to find kernel in $tsrc"
2426+ debug 1 "using kernel ${kpath#${target}}"
2427+ cp "$kpath" "$kernel" ||
2428+ fail "failed copy $kpath to $kernel"
2429+ [ -z "$IMAGE" ] || chown "--reference=$IMAGE" "$kernel"
2430+ fi
2431+
2432+ if [ -n "$initrd" ]; then
2433+ [ -n "$ipath" ] || fail "unable to find initrd in $tsrc"
2434+ debug 1 "using initrd ${ipath#${target}}"
2435+ cp "$ipath" "$initrd" ||
2436+ fail "failed copy $ipath to $initrd"
2437+ [ -z "$IMAGE" ] || chown "--reference=$IMAGE" "$initrd"
2438+ fi
2439+
2440+}
2441+
2442+main "$@"
2443+
2444+# vi: ts=4 expandtab
2445diff --git a/debian/tests/test-open-iscsi.py b/debian/tests/test-open-iscsi.py
2446new file mode 100644
2447index 0000000..e241be9
2448--- /dev/null
2449+++ b/debian/tests/test-open-iscsi.py
2450@@ -0,0 +1,427 @@
2451+#!/usr/bin/python3
2452+#
2453+# test-open-iscsi.py quality assurance test script for open-iscsi
2454+# Copyright (C) 2011 Canonical Ltd.
2455+# Author: Jamie Strandboge <jamie@canonical.com>
2456+#
2457+# This program is free software: you can redistribute it and/or modify
2458+# it under the terms of the GNU General Public License version 3,
2459+# as published by the Free Software Foundation.
2460+#
2461+# This program is distributed in the hope that it will be useful,
2462+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2463+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2464+# GNU General Public License for more details.
2465+#
2466+# You should have received a copy of the GNU General Public License
2467+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2468+#
2469+# packages required for test to run:
2470+# QRT-Packages: open-iscsi
2471+# packages where more than one package can satisfy a runtime requirement:
2472+# QRT-Alternates:
2473+# files and directories required for the test to run:
2474+# QRT-Depends:
2475+# privilege required for the test to run (remove line if running as user is okay):
2476+# QRT-Privilege: root
2477+
2478+'''
2479+ In general, this test should be run in a virtual machine (VM) or possibly
2480+ a chroot and not on a production machine. While efforts are made to make
2481+ these tests non-destructive, there is no guarantee this script will not
2482+ alter the machine. You have been warned.
2483+
2484+ How to run in a clean VM:
2485+ $ sudo apt-get -y install <QRT-Packages> && sudo ./test-PKG.py -v'
2486+
2487+ How to run in a clean schroot named 'lucid':
2488+ $ schroot -c lucid -u root -- sh -c 'apt-get -y install <QRT-Packages> && ./test-PKG.py -v'
2489+
2490+
2491+ NOTES:
2492+ - currently only tested on Ubuntu 8.04
2493+'''
2494+
2495+from __future__ import print_function
2496+
2497+from netifaces import gateways, AF_INET
2498+import unittest, subprocess, sys, os, glob
2499+import shutil
2500+import testlib
2501+import textwrap
2502+from tempfile import mkdtemp
2503+import time
2504+
2505+# There are setup based on README.multipurpose-vm. Feel free to override.
2506+remote_server = ''
2507+username = 'ubuntu'
2508+password = 'passwd'
2509+username_in = 'ubuntu'
2510+password_in = 'ubuntupasswd'
2511+initiatorname = 'iqn.2009-10.com.example.hardy-multi:iscsi-01'
2512+
2513+COLLECT_USER_DATA = """\
2514+#cloud-config
2515+bukket:
2516+ - &get_resolved_status |
2517+ if [ "${1:--}" != "-" ]; then
2518+ exec >"$1" 2>&1
2519+ fi
2520+ if ! command -v resolvectl >/dev/null 2>&1; then
2521+ echo "resolvectl: not available."
2522+ exit
2523+ fi
2524+ if ! ( resolvectl --help | grep -q -- status ); then
2525+ echo "resolvectl: no status."
2526+ exit
2527+ fi
2528+ resolvectl status --no-pager
2529+
2530+ - &get_iscsid_status |
2531+ [ "${1:--}" != "-" ] && exec >"$1" 2>&1
2532+ udevadm settle
2533+ systemctl is-active iscsid.service
2534+ systemctl status --no-pager --full iscsid.service
2535+
2536+ - &add_and_remove_tuntap |
2537+ #!/bin/sh
2538+ # LP: #1785108 would break dns when any device was removed.
2539+ tapdev="mytap0"
2540+ echo ==== Adding $tapdev ====
2541+ ip tuntap add mode tap user root $tapdev
2542+ udevadm settle
2543+ echo ==== Removing $tapdev ====
2544+ ip tuntap del mode tap $tapdev
2545+ udevadm settle
2546+
2547+ - &collect_debug_mounts |
2548+ [ "${1:--}" != "-" ] && exec >"$1" 2>&1
2549+ [ -x /usr/local/bin/debug-mounts ] || exit 0
2550+ /usr/local/bin/debug-mounts
2551+
2552+runcmd:
2553+ - [ sh, -c, *add_and_remove_tuntap ]
2554+ - [ mkdir, -p, /output ]
2555+ - [ cp, /etc/resolv.conf, /output ]
2556+ - [ sh, -c, *get_resolved_status, --, /output/systemd-resolve-status.txt ]
2557+ - [ sh, -c, *get_iscsid_status, --, /output/iscsid-status.txt ]
2558+ - [ sh, -c, *collect_debug_mounts, --, /output/debug-mounts.txt ]
2559+ - [ sh, -c, 'journalctl --boot=0 --output=short-monotonic > /output/journal.txt' ]
2560+ - [ sh, -c, 'dpkg-query --show > /output/manifest.txt' ]
2561+ - [ tar, -C, /output, -cf, /dev/disk/by-id/virtio-output-disk, . ]
2562+
2563+power_state:
2564+ mode: poweroff
2565+ message: cloud-init finished. Shutting down.
2566+ timeout: 60
2567+"""
2568+
2569+try:
2570+ from private.qrt.OpenIscsi import PrivateOpenIscsiTest
2571+except ImportError:
2572+ class PrivateOpenIscsiTest(object):
2573+ '''Empty class'''
2574+ print("Skipping private tests", file=sys.stdout)
2575+
2576+class OpenIscsiTest(testlib.TestlibCase, PrivateOpenIscsiTest):
2577+ '''Test my thing.'''
2578+
2579+ def setUp(self):
2580+ '''Set up prior to each test_* function'''
2581+ self.pidfile = "/var/run/iscsid.pid"
2582+ self.exe = "/sbin/iscsid"
2583+ self.daemon = testlib.TestDaemon("open-iscsi")
2584+ self.initiatorname_iscsi = '/etc/iscsi/initiatorname.iscsi'
2585+ self.iscsid_conf = '/etc/iscsi/iscsid.conf'
2586+
2587+ def tearDown(self):
2588+ '''Clean up after each test_* function'''
2589+ global remote_server
2590+ global initiatorname
2591+
2592+ # If remote server is setup, convert back to manual, logout, remove
2593+ # testlib configs and restart (in that order)
2594+ if remote_server != '':
2595+ testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--op=update', '--name', 'node.startup', '--value=manual'])
2596+ testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--op=update', '--name', 'node.conn[0].startup', '--value=manual'])
2597+ testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--logout'])
2598+
2599+ testlib.config_restore(self.initiatorname_iscsi)
2600+ testlib.config_restore(self.iscsid_conf)
2601+ self.daemon.restart()
2602+
2603+ def test_discovery_with_server(self):
2604+ '''Test iscsi_discovery to remote server'''
2605+ global remote_server
2606+ global username
2607+ global password
2608+ global username_in
2609+ global password_in
2610+ global initiatorname
2611+
2612+ if remote_server == '':
2613+ return self._skipped("--remote-server not specified")
2614+
2615+ contents = '''
2616+InitiatorName=%s
2617+InitiatorAlias=ubuntu
2618+''' % (initiatorname)
2619+ testlib.config_replace(self.initiatorname_iscsi, contents, True)
2620+
2621+ contents = '''
2622+node.session.auth.authmethod = CHAP
2623+node.session.auth.username = %s
2624+node.session.auth.password = %s
2625+node.session.auth.username_in = %s
2626+node.session.auth.password_in = %s
2627+
2628+discovery.sendtargets.auth.authmethod = CHAP
2629+discovery.sendtargets.auth.username = %s
2630+discovery.sendtargets.auth.password = %s
2631+discovery.sendtargets.auth.username_in = %s
2632+discovery.sendtargets.auth.password_in = %s
2633+''' % (username, password, username_in, password_in, username, password, username_in, password_in)
2634+ testlib.config_replace(self.iscsid_conf, contents, True)
2635+
2636+ self.assertTrue(self.daemon.restart())
2637+ time.sleep(2)
2638+ self.assertTrue(self.daemon.status()[0])
2639+
2640+ rc, report = testlib.cmd(["/sbin/iscsi_discovery", remote_server])
2641+ expected = 0
2642+ result = 'Got exit code %d, expected %d\n' % (rc, expected)
2643+ self.assertEqual(expected, rc, result + report)
2644+ for i in ['starting discovery to %s' % remote_server,
2645+ 'Testing iser-login to target %s portal %s' % (initiatorname, remote_server),
2646+ 'starting to test tcp-login to target %s portal %s' % (initiatorname, remote_server),
2647+ 'discovered 1 targets at %s, connected to 1' % remote_server]:
2648+ result = "Could not find '%s' in report:\n" % i
2649+ self.assertTrue(i in report, result + report)
2650+
2651+ def test_net_interface_handler_execute_bit(self):
2652+ '''Test /lib/open-iscsi/net-interface-handler is executable.'''
2653+ nih_path = '/lib/open-iscsi/net-interface-handler'
2654+ self.assertTrue(os.access(nih_path, os.X_OK))
2655+
2656+class CloudImageTest(testlib.TestlibCase, PrivateOpenIscsiTest):
2657+ '''Test the cloud image can boot on iscsi root.
2658+
2659+ See README-boot-test.md for more information.
2660+ '''
2661+
2662+ @classmethod
2663+ def setUpClass(cls):
2664+ reason = (
2665+ "Skipped Cloud Image test on {arch}. whitelisted are: {whitelist}")
2666+ whitelisted = os.environ.get('WHITELIST_ARCHES', 'amd64').split(",")
2667+ curarch = testlib.manager.dpkg_arch
2668+ if testlib.manager.dpkg_arch not in whitelisted:
2669+ raise unittest.SkipTest(
2670+ reason.format(arch=curarch, whitelist=whitelisted))
2671+
2672+ here = os.path.dirname(os.path.abspath(__file__))
2673+ os.environ['PATH'] = "%s:%s" % (here, os.environ['PATH'])
2674+ release = os.environ.get(
2675+ "ISCSI_TEST_RELEASE", testlib.ubuntu_release())
2676+ image_d = os.path.join(here, '{}.d'.format(release))
2677+ # Download MAAS ephemeral image.
2678+ info = {'release': release,
2679+ 'image_d': image_d,
2680+ 'root_image': os.path.join(image_d, 'disk.img'),
2681+ 'kernel': os.path.join(image_d, 'kernel'),
2682+ 'initrd': os.path.join(image_d, 'initrd')}
2683+ try:
2684+ get_image(info['image_d'], release)
2685+ except subprocess.CalledProcessError as e:
2686+ if e.return_code != 3:
2687+ raise e
2688+ raise unittest.SkipTest(
2689+ "Cloud Image not available for release '%s'." % release)
2690+ if os.environ.get("NO_PATCH_IMAGE", "0") == "0":
2691+ patch_image(info['root_image'],
2692+ kernel=info['kernel'], initrd=info['initrd'])
2693+ cls.info = info
2694+ cls.here = here
2695+
2696+ def tearDown(self):
2697+ super(CloudImageTest, self).tearDown()
2698+ if os.path.exists(self.tmpdir):
2699+ shutil.rmtree(self.tmpdir)
2700+
2701+ def setUp(self):
2702+ super(CloudImageTest, self).setUp()
2703+ self.tmpdir = mkdtemp()
2704+ udp = os.path.join(self.tmpdir, 'user-data')
2705+ with open(udp, "w") as fp:
2706+ fp.write(COLLECT_USER_DATA)
2707+ self.info['user-data'] = udp
2708+
2709+ def create_output_disk(self):
2710+ path = os.path.join(self.tmpdir, 'output-disk.img')
2711+ subprocess.check_call([
2712+ 'qemu-img', 'create', '-f', 'raw', path, '10M'])
2713+ return path
2714+
2715+ def extract_files(self, path):
2716+ # get contents in a dictionary of tarball at 'path'
2717+ tmpdir = mkdtemp()
2718+ try:
2719+ subprocess.check_call(['tar', '-C', tmpdir, '-xf', path])
2720+ flist = {}
2721+ prefix = len(tmpdir) + 1
2722+ for root, dirs, files in os.walk(tmpdir):
2723+ for fname in files:
2724+ fpath = os.path.join(root, fname)
2725+ key = fpath[prefix:]
2726+ with open(fpath, "r") as fp:
2727+ flist[key] = fp.read()
2728+ return flist
2729+ finally:
2730+ shutil.rmtree(tmpdir)
2731+
2732+ def test_tgt_boot(self):
2733+ tgt_boot_cmd = os.path.join(self.here, 'tgt-boot-test')
2734+ # Add self.here to PATH so xkvm will be available to tgt-boot-test
2735+ dns_addr = '10.1.1.4'
2736+ rel_dir = '{}.d'.format(self.info['release'])
2737+ dns_search = 'example.com'
2738+ info = {'host': '10.1.1.2', 'dns': dns_addr,
2739+ 'dnssearch': dns_search, 'network': '10.1.1.0/24'}
2740+ netdev = ("--netdev=user,net={network},host={host},dns={dns},"
2741+ "dnssearch={dnssearch}").format(**info)
2742+
2743+ artifacts_dir = os.environ.get('AUTOPKGTEST_ARTIFACTS')
2744+ if artifacts_dir and not os.path.isdir(artifacts_dir):
2745+ os.makedirs(artifacts_dir)
2746+
2747+ output_disk = self.create_output_disk()
2748+ cmd = [
2749+ tgt_boot_cmd, '-v', netdev,
2750+ '--disk=%s,serial=output-disk' % output_disk,
2751+ '--user-data-add=%s' % self.info['user-data'],
2752+ self.info['root_image'], self.info['kernel'],
2753+ self.info['initrd']]
2754+ sys.stderr.write(' '.join(cmd) + "\n")
2755+
2756+ env = os.environ.copy()
2757+ env['BOOT_TIMEOUT'] = env.get('BOOT_TIMEOUT', '60m')
2758+ subprocess.check_call(cmd, env=env)
2759+
2760+ if artifacts_dir:
2761+ tgz = os.path.join(artifacts_dir, "tgt-collected.tar.gz")
2762+ shutil.copy(output_disk, tgz)
2763+ print("Copied output_disk '%s' to artifacts dir '%s'" %
2764+ (output_disk, tgz))
2765+
2766+ files = self.extract_files(output_disk)
2767+ print("collected files: %s" % files.keys())
2768+ resolvconf = files.get('resolv.conf', "NO_RESOLVCONF_FOUND")
2769+ resolve_status = files.get('systemd-resolve-status.txt')
2770+
2771+ resolvconf_id = 'generated by resolvconf'
2772+ resolved_addr = "127.0.0.53"
2773+ if resolvconf_id in resolvconf:
2774+ print("resolvconf manages resolvconf.\n")
2775+ self.assertIn(
2776+ dns_addr, resolvconf,
2777+ msg = ("%s not in resolvconf contents: \n%s" %
2778+ (dns_addr, resolvconf)))
2779+ if dns_search in resolvconf:
2780+ print("%s was found in resolv.conf." % dns_search)
2781+ elif resolved_addr in resolvconf and dns_search in resolve_status:
2782+ # zesty has resolvconf and systemd-resolved.
2783+ print("%s was in resolve_status and %s in resolv.conf" %
2784+ (resolved_addr, dns_search))
2785+ else:
2786+ raise AssertionError(
2787+ "%s domain is not being searched." % dns_search)
2788+
2789+ else:
2790+ print("systemd-resolved managing resolve.conf\n")
2791+ self.assertIn(
2792+ resolved_addr, resolvconf,
2793+ msg="%s not in resolved resolv.conf: %s" % (resolved_addr,
2794+ resolvconf))
2795+ self.assertIn(dns_addr, resolve_status,
2796+ msg=("%s not in resolvectl status: %s" %
2797+ (dns_addr, resolve_status)))
2798+ self.assertIn(dns_search, resolve_status,
2799+ msg=("search addr '%s' not in resolvectl status: %s" %
2800+ (dns_search, resolve_status)))
2801+
2802+ # iscsid-status.txt has first line output from
2803+ # 'systemctl is-active iscsid.service' and then 'systemcl status'
2804+ iscsid_status = files.get('iscsid-status.txt')
2805+ is_active = iscsid_status.splitlines()[0]
2806+ self.assertEqual(
2807+ "active", is_active,
2808+ msg=("Expected iscsid.service active, found '%s'.\n%s\n" %
2809+ (is_active, iscsid_status)))
2810+
2811+
2812+def get_image(top_d, release):
2813+ cmd = ['get-image', top_d, 'cloud-daily', release]
2814+ subprocess.check_call(cmd)
2815+
2816+
2817+def patch_image(image, packages=None, kernel=None, initrd=None):
2818+ '''Patch root-image with dep8 built open-iscsi package.'''
2819+
2820+ if packages is None:
2821+ # an empty 'packages' to patch-image still installs open-iscsi
2822+ packages = []
2823+
2824+ cmd = ['patch-image', image]
2825+ if kernel:
2826+ cmd.append('--kernel=%s' % kernel)
2827+ if initrd:
2828+ cmd.append('--initrd=%s' % initrd)
2829+ cmd.extend(packages)
2830+
2831+ subprocess.check_call(cmd)
2832+
2833+
2834+if __name__ == '__main__':
2835+ import optparse
2836+ parser = optparse.OptionParser()
2837+ parser.add_option("-v", "--verbose", dest="verbose", help="Verbose", action="store_true")
2838+ parser.add_option("-s", "--remote-server", dest="remote_server", help="Specify host with available iSCSI volumes", metavar="HOST")
2839+
2840+ parser.add_option("-n", "--initiatorname", dest="initiatorname", help="Specify initiatorname for use with --remote-server", metavar="NAME")
2841+
2842+ parser.add_option("--password", dest="password", help="Specify password for use with --remote-server", metavar="PASS")
2843+ parser.add_option("--password-in", dest="password_in", help="Specify password_in for use with --remote-server", metavar="PASS")
2844+
2845+ parser.add_option("--username", dest="username", help="Specify username for use with --remote-server", metavar="USER")
2846+ parser.add_option("--username-in", dest="username_in", help="Specify username_in for use with --remote-server", metavar="USER")
2847+
2848+ (options, args) = parser.parse_args()
2849+
2850+ if options.remote_server:
2851+ remote_server = options.remote_server
2852+
2853+ if options.username:
2854+ username = options.username
2855+ if options.password:
2856+ password = options.password
2857+ if options.username_in:
2858+ username_in = options.username_in
2859+ if options.password_in:
2860+ password_in = options.password_in
2861+ if options.initiatorname:
2862+ initiatorname = options.initiatorname
2863+ print("Connecting to remote server with:")
2864+ print(" host = %s " % remote_server)
2865+ print(' initiatorname = %s' % initiatorname)
2866+ print(' username = %s' % username)
2867+ print(' password = %s' % password)
2868+ print(' username_in = %s' % username_in)
2869+ print(' password_in = %s' % password_in)
2870+
2871+ suite = unittest.TestSuite()
2872+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(OpenIscsiTest))
2873+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
2874+ CloudImageTest))
2875+ rc = unittest.TextTestRunner(verbosity=2).run(suite)
2876+ if not rc.wasSuccessful():
2877+ sys.exit(1)
2878diff --git a/debian/tests/testlib.py b/debian/tests/testlib.py
2879new file mode 100644
2880index 0000000..dce4252
2881--- /dev/null
2882+++ b/debian/tests/testlib.py
2883@@ -0,0 +1,1488 @@
2884+from __future__ import print_function
2885+#
2886+# testlib.py quality assurance test script
2887+# Copyright (C) 2008-2016 Canonical Ltd.
2888+#
2889+# This library is free software; you can redistribute it and/or
2890+# modify it under the terms of the GNU Library General Public
2891+# License as published by the Free Software Foundation; either
2892+# version 2 of the License.
2893+#
2894+# This library is distributed in the hope that it will be useful,
2895+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2896+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2897+# Library General Public License for more details.
2898+#
2899+# You should have received a copy of the GNU Library General Public
2900+# License along with this program. If not, see
2901+# <http://www.gnu.org/licenses/>.
2902+#
2903+
2904+'''Common classes and functions for package tests.'''
2905+
2906+import crypt
2907+import glob
2908+import grp
2909+import gzip
2910+import os
2911+import os.path
2912+import platform
2913+import pwd
2914+import random
2915+import re
2916+import shutil
2917+import socket
2918+import string
2919+import subprocess
2920+import sys
2921+import tempfile
2922+import time
2923+import unittest
2924+
2925+from stat import ST_SIZE
2926+
2927+# Don't make python-pexpect mandatory
2928+try:
2929+ import pexpect
2930+except ImportError:
2931+ pass
2932+
2933+import warnings
2934+warnings.filterwarnings('ignore', message=r'.*apt_pkg\.TagFile.*', category=DeprecationWarning)
2935+try:
2936+ import apt_pkg
2937+ # cope with apt_pkg api changes.
2938+ if 'init_system' in dir(apt_pkg):
2939+ apt_pkg.init_system()
2940+ else:
2941+ apt_pkg.InitSystem()
2942+except:
2943+ # On non-Debian system, fall back to simple comparison without debianisms
2944+ class apt_pkg(object):
2945+ @staticmethod
2946+ def version_compare(one, two):
2947+ list_one = one.split('.')
2948+ list_two = two.split('.')
2949+ while len(list_one) > 0 and len(list_two) > 0:
2950+ try:
2951+ if int(list_one[0]) > int(list_two[0]):
2952+ return 1
2953+ if int(list_one[0]) < int(list_two[0]):
2954+ return -1
2955+ except:
2956+ # ugh, non-numerics in the version, fall back to
2957+ # string comparison, which will be wrong for e.g.
2958+ # 3.2 vs 3.16rc1
2959+ if list_one[0] > list_two[0]:
2960+ return 1
2961+ if list_one[0] < list_two[0]:
2962+ return -1
2963+ list_one.pop(0)
2964+ list_two.pop(0)
2965+ return 0
2966+
2967+ @staticmethod
2968+ def VersionCompare(one, two):
2969+ return apt_pkg.version_compare(one, two)
2970+
2971+bogus_nxdomain = "208.69.32.132"
2972+
2973+# http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html
2974+# This is needed so that the subprocesses that produce endless output
2975+# actually quit when the reader goes away.
2976+import signal
2977+def subprocess_setup():
2978+ # Python installs a SIGPIPE handler by default. This is usually not what
2979+ # non-Python subprocesses expect.
2980+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
2981+
2982+
2983+class TimedOutException(Exception):
2984+ def __init__(self, value="Timed Out"):
2985+ self.value = value
2986+
2987+ def __str__(self):
2988+ return repr(self.value)
2989+
2990+
2991+def _restore_backup(path):
2992+ pathbackup = path + '.autotest'
2993+ if os.path.exists(pathbackup):
2994+ shutil.move(pathbackup, path)
2995+
2996+
2997+def _save_backup(path):
2998+ pathbackup = path + '.autotest'
2999+ if os.path.exists(path) and not os.path.exists(pathbackup):
3000+ shutil.copy2(path, pathbackup)
3001+ # copy2 does not copy ownership, so do it here.
3002+ # Reference: http://docs.python.org/library/shutil.html
3003+ a = os.stat(path)
3004+ os.chown(pathbackup, a[4], a[5])
3005+
3006+
3007+def config_copydir(path):
3008+ if os.path.exists(path) and not os.path.isdir(path):
3009+ raise OSError("'%s' is not a directory" % (path))
3010+ _restore_backup(path)
3011+
3012+ pathbackup = path + '.autotest'
3013+ if os.path.exists(path):
3014+ shutil.copytree(path, pathbackup, symlinks=True)
3015+
3016+
3017+def config_replace(path, contents, append=False):
3018+ '''Replace (or append) to a config file'''
3019+ _restore_backup(path)
3020+ if os.path.exists(path):
3021+ _save_backup(path)
3022+ if append:
3023+ with open(path) as fh:
3024+ contents = fh.read() + contents
3025+ with open(path, 'w') as fh:
3026+ fh.write(contents)
3027+
3028+
3029+def config_comment(path, field):
3030+ _save_backup(path)
3031+ contents = ""
3032+ with open(path) as fh:
3033+ for line in fh:
3034+ if re.search("^\s*%s\s*=" % (field), line):
3035+ line = "#" + line
3036+ contents += line
3037+
3038+ with open(path + '.new', 'w') as new_fh:
3039+ new_fh.write(contents)
3040+ os.rename(path + '.new', path)
3041+
3042+
3043+def config_set(path, field, value, spaces=True):
3044+ _save_backup(path)
3045+ contents = ""
3046+ if spaces:
3047+ setting = '%s = %s\n' % (field, value)
3048+ else:
3049+ setting = '%s=%s\n' % (field, value)
3050+ found = False
3051+ with open(path) as fh:
3052+ for line in fh:
3053+ if re.search("^\s*%s\s*=" % (field), line):
3054+ found = True
3055+ line = setting
3056+ contents += line
3057+ if not found:
3058+ contents += setting
3059+
3060+ with open(path + '.new', 'w') as new_config:
3061+ new_config.write(contents)
3062+ os.rename(path + '.new', path)
3063+
3064+
3065+def config_patch(path, patch, depth=1):
3066+ '''Patch a config file'''
3067+ _restore_backup(path)
3068+ _save_backup(path)
3069+
3070+ handle, name = mkstemp_fill(patch)
3071+ rc = subprocess.call(['/usr/bin/patch', '-p%s' % depth, path], stdin=handle, stdout=subprocess.PIPE)
3072+ os.unlink(name)
3073+ if rc != 0:
3074+ raise Exception("Patch failed")
3075+
3076+
3077+def config_restore(path):
3078+ '''Rename a replaced config file back to its initial state'''
3079+ _restore_backup(path)
3080+
3081+
3082+def timeout(secs, f, *args):
3083+ def handler(signum, frame):
3084+ raise TimedOutException()
3085+
3086+ old = signal.signal(signal.SIGALRM, handler)
3087+ result = None
3088+ signal.alarm(secs)
3089+ try:
3090+ result = f(*args)
3091+ finally:
3092+ signal.alarm(0)
3093+ signal.signal(signal.SIGALRM, old)
3094+
3095+ return result
3096+
3097+
3098+def require_nonroot():
3099+ if os.geteuid() == 0:
3100+ print("This series of tests should be run as a regular user with sudo access, not as root.", file=sys.stderr)
3101+ sys.exit(1)
3102+
3103+
3104+def require_root():
3105+ if os.geteuid() != 0:
3106+ print("This series of tests should be run with root privileges (e.g. via sudo).", file=sys.stderr)
3107+ sys.exit(1)
3108+
3109+
3110+def require_sudo():
3111+ if os.geteuid() != 0 or os.environ.get('SUDO_USER', None) is None:
3112+ print("This series of tests must be run under sudo.", file=sys.stderr)
3113+ sys.exit(1)
3114+ if os.environ['SUDO_USER'] == 'root':
3115+ print('Please run this test using sudo from a regular user. (You ran sudo from root.)', file=sys.stderr)
3116+ sys.exit(1)
3117+
3118+
3119+def random_string(length, lower=False):
3120+ '''Return a random string, consisting of ASCII letters, with given
3121+ length.'''
3122+
3123+ s = ''
3124+ selection = string.ascii_letters
3125+ if lower:
3126+ selection = string.ascii_lowercase
3127+ maxind = len(selection) - 1
3128+ for l in range(length):
3129+ s += selection[random.randint(0, maxind)]
3130+ return s
3131+
3132+
3133+def mkstemp_fill(contents, suffix='', prefix='testlib-', dir=None):
3134+ '''As tempfile.mkstemp does, return a (file, name) pair, but with
3135+ prefilled contents.'''
3136+
3137+ handle, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
3138+ os.close(handle)
3139+ handle = open(name, "w+")
3140+ handle.write(contents)
3141+ handle.flush()
3142+ handle.seek(0)
3143+
3144+ return handle, name
3145+
3146+
3147+def create_fill(path, contents, mode=0o644):
3148+ '''Safely create a page'''
3149+ # make the temp file in the same dir as the destination file so we
3150+ # don't get invalid cross-device link errors when we rename
3151+ handle, name = mkstemp_fill(contents, dir=os.path.dirname(path))
3152+ handle.close()
3153+ os.rename(name, path)
3154+ os.chmod(path, mode)
3155+
3156+
3157+def login_exists(login):
3158+ '''Checks whether the given login exists on the system.'''
3159+
3160+ try:
3161+ pwd.getpwnam(login)
3162+ return True
3163+ except KeyError:
3164+ return False
3165+
3166+
3167+def group_exists(group):
3168+ '''Checks whether the given login exists on the system.'''
3169+
3170+ try:
3171+ grp.getgrnam(group)
3172+ return True
3173+ except KeyError:
3174+ return False
3175+
3176+
3177+def is_empty_file(path):
3178+ '''test if file is empty, returns True if so'''
3179+ with open(path) as fh:
3180+ return (len(fh.read()) == 0)
3181+
3182+
3183+def recursive_rm(dirPath, contents_only=False):
3184+ '''recursively remove directory'''
3185+ names = os.listdir(dirPath)
3186+ for name in names:
3187+ path = os.path.join(dirPath, name)
3188+ if os.path.islink(path) or not os.path.isdir(path):
3189+ os.unlink(path)
3190+ else:
3191+ recursive_rm(path)
3192+ if not contents_only:
3193+ os.rmdir(dirPath)
3194+
3195+
3196+def check_pidfile(exe, pidfile):
3197+ '''Checks if pid in pidfile is running'''
3198+ if not os.path.exists(pidfile):
3199+ return False
3200+
3201+ # get the pid
3202+ try:
3203+ with open(pidfile, 'r') as fd:
3204+ pid = fd.readline().rstrip('\n')
3205+ except:
3206+ return False
3207+
3208+ return check_pid(exe, pid)
3209+
3210+
3211+def check_pid(exe, pid):
3212+ '''Checks if pid is running'''
3213+ cmdline = "/proc/%s/cmdline" % (str(pid))
3214+ if not os.path.exists(cmdline):
3215+ return False
3216+
3217+ # get the command line
3218+ try:
3219+ with open(cmdline, 'r') as fd:
3220+ tmp = fd.readline().split('\0')
3221+ except:
3222+ return False
3223+
3224+ # this allows us to match absolute paths or just the executable name
3225+ if re.match('^' + exe + '$', tmp[0]) or \
3226+ re.match('.*/' + exe + '$', tmp[0]) or \
3227+ re.match('^' + exe + ': ', tmp[0]) or \
3228+ re.match('^\(' + exe + '\)', tmp[0]):
3229+ return True
3230+
3231+ return False
3232+
3233+
3234+def check_port(port, proto, ver=4):
3235+ '''Check if something is listening on the specified port.
3236+ WARNING: for some reason this does not work with a bind mounted /proc
3237+ '''
3238+ assert (port >= 1)
3239+ assert (port <= 65535)
3240+ assert (proto.lower() == "tcp" or proto.lower() == "udp")
3241+ assert (ver == 4 or ver == 6)
3242+
3243+ fn = "/proc/net/%s" % (proto)
3244+ if ver == 6:
3245+ fn += str(ver)
3246+
3247+ rc, report = cmd(['cat', fn])
3248+ assert (rc == 0)
3249+
3250+ hport = "%0.4x" % port
3251+
3252+ if re.search(': [0-9a-f]{8}:%s [0-9a-f]' % str(hport).lower(), report.lower()):
3253+ return True
3254+ return False
3255+
3256+
3257+def get_arch():
3258+ '''Get the current architecture'''
3259+ rc, report = cmd(['uname', '-m'])
3260+ assert (rc == 0)
3261+ return report.strip()
3262+
3263+
3264+def get_multiarch_tuple():
3265+ '''Get the current debian multiarch tuple'''
3266+
3267+ # XXX dpkg-architecture on Ubuntu 12.04 requires -q be adjacent to
3268+ # the variable name
3269+ rc, report = cmd(['dpkg-architecture', '-qDEB_HOST_MULTIARCH'])
3270+ assert (rc == 0)
3271+ return report.strip()
3272+
3273+
3274+def get_bits():
3275+ '''return the default architecture number of bits (32 or 64, usually)'''
3276+ return platform.architecture()[0][0:2]
3277+
3278+
3279+def get_memory():
3280+ '''Gets total ram and swap'''
3281+ meminfo = "/proc/meminfo"
3282+ memtotal = 0
3283+ swaptotal = 0
3284+ if not os.path.exists(meminfo):
3285+ return (False, False)
3286+
3287+ try:
3288+ fd = open(meminfo, 'r')
3289+ for line in fd.readlines():
3290+ splitline = line.split()
3291+ if splitline[0] == 'MemTotal:':
3292+ memtotal = int(splitline[1])
3293+ elif splitline[0] == 'SwapTotal:':
3294+ swaptotal = int(splitline[1])
3295+ fd.close()
3296+ except:
3297+ return (False, False)
3298+
3299+ return (memtotal, swaptotal)
3300+
3301+
3302+def is_running_in_vm():
3303+ '''Check if running under a VM'''
3304+ # add other virtualization environments here
3305+ for search in ['QEMU Virtual CPU']:
3306+ rc, report = cmd_pipe(['dmesg'], ['grep', search])
3307+ if rc == 0:
3308+ return True
3309+ return False
3310+
3311+
3312+def ubuntu_release():
3313+ '''Get the Ubuntu release'''
3314+ f = "/etc/lsb-release"
3315+ try:
3316+ size = os.stat(f)[ST_SIZE]
3317+ except:
3318+ return "UNKNOWN"
3319+
3320+ if size > 1024 * 1024:
3321+ raise IOError('Could not open "%s" (too big)' % f)
3322+
3323+ with open("/etc/lsb-release", 'r') as fh:
3324+ lines = fh.readlines()
3325+
3326+ pat = re.compile(r'DISTRIB_CODENAME')
3327+ for line in lines:
3328+ if pat.search(line):
3329+ return line.split('=')[1].rstrip('\n').rstrip('\r')
3330+
3331+ return "UNKNOWN"
3332+
3333+
3334+def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=None, env=None, shell=False, text=True):
3335+ '''Try to execute given command (array) and return its stdout, or return
3336+ a textual error if it failed.'''
3337+
3338+ try:
3339+ sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, preexec_fn=subprocess_setup, env=env, universal_newlines=text, shell=shell)
3340+ if sys.version_info[0] >= 3 and sys.version_info[1] > 3:
3341+ out, outerr = sp.communicate(input, timeout=timeout)
3342+ else:
3343+ out, outerr = sp.communicate(input)
3344+ except OSError as e:
3345+ return [127, str(e)]
3346+
3347+ # Handle redirection of stdout
3348+ if out is None:
3349+ out = ''
3350+ # Handle redirection of stderr
3351+ if outerr is None:
3352+ outerr = ''
3353+ if text == False:
3354+ out = str(out)
3355+ return [sp.returncode, out + outerr]
3356+
3357+
3358+def cmd_pipe(command1, command2, input=None, stderr=subprocess.STDOUT, stdin=None):
3359+ '''Try to pipe command1 into command2.'''
3360+ try:
3361+ sp1 = subprocess.Popen(command1, stdin=stdin, stdout=subprocess.PIPE, stderr=stderr, close_fds=True)
3362+ sp2 = subprocess.Popen(command2, stdin=sp1.stdout, stdout=subprocess.PIPE, stderr=stderr, close_fds=True, universal_newlines=True)
3363+ except OSError as e:
3364+ return [127, str(e)]
3365+
3366+ out = sp2.communicate(input)[0]
3367+ # ensure we don't leak open files and that sp1 is stopped
3368+ sp1.stdout.close()
3369+ sp1.wait()
3370+ return [sp2.returncode, out]
3371+
3372+
3373+def cwd_has_enough_space(cdir, total_bytes):
3374+ '''Determine if the partition of the current working directory has 'bytes'
3375+ free.'''
3376+ rc, df_output = cmd(['df'])
3377+ if rc != 0:
3378+ result = 'df failed, got exit code %d, expected %d\n' % (rc, 0)
3379+ raise OSError(result)
3380+ if rc != 0:
3381+ return False
3382+
3383+ kb = total_bytes / 1024
3384+
3385+ mounts = dict()
3386+ for line in df_output.splitlines():
3387+ if '/' not in line:
3388+ continue
3389+ tmp = line.split()
3390+ mounts[tmp[5]] = int(tmp[3])
3391+
3392+ cdir = os.getcwd()
3393+ while cdir != '/':
3394+ if cdir not in mounts:
3395+ cdir = os.path.dirname(cdir)
3396+ continue
3397+ return kb < mounts[cdir]
3398+
3399+ return kb < mounts['/']
3400+
3401+
3402+def get_md5(filename):
3403+ '''Gets the md5sum of the file specified'''
3404+
3405+ (rc, report) = cmd(["/usr/bin/md5sum", "-b", filename])
3406+ expected = 0
3407+ assert (expected == rc)
3408+
3409+ return report.split(' ')[0]
3410+
3411+
3412+def dpkg_compare_installed_version(pkg, check, version):
3413+ '''Gets the version for the installed package, and compares it to the
3414+ specified version.
3415+ '''
3416+ (rc, report) = cmd(["/usr/bin/dpkg", "-s", pkg])
3417+ assert (rc == 0)
3418+ assert ("Status: install ok installed" in report)
3419+ installed_version = ""
3420+ for line in report.splitlines():
3421+ if line.startswith("Version: "):
3422+ installed_version = line.split()[1]
3423+
3424+ assert (installed_version != "")
3425+
3426+ (rc, report) = cmd(["/usr/bin/dpkg", "--compare-versions", installed_version, check, version])
3427+ assert (rc == 0 or rc == 1)
3428+ if rc == 0:
3429+ return True
3430+ return False
3431+
3432+
3433+def _run_apt_command(pkg_list, apt_cmd='install'):
3434+ env = os.environ.copy()
3435+ env['DEBIAN_FRONTEND'] = 'noninteractive'
3436+ # debugging version, but on precise doesn't actually run dpkg
3437+ # command = ['apt-get', '-y', '--force-yes', '-o', 'Dpkg::Options::=--force-confold', '-o', 'Debug::pkgDPkgPM=true', apt_cmd]
3438+ command = ['apt-get', '-y', '--force-yes', '-o', 'Dpkg::Options::=--force-confold', apt_cmd]
3439+ command.extend(pkg_list)
3440+ rc, report = cmd(command)
3441+ return rc, report
3442+
3443+
3444+# note: for the following install_* functions, you probably want the
3445+# versions in the TestlibCase class (see below)
3446+def install_builddeps(src_pkg):
3447+ rc, report = _run_apt_command([src_pkg], 'build-dep')
3448+ assert(rc == 0)
3449+
3450+
3451+def install_package(package):
3452+ rc, report = _run_apt_command([package], 'install')
3453+ assert(rc == 0)
3454+
3455+
3456+def install_packages(pkg_list):
3457+ rc, report = _run_apt_command(pkg_list, 'install')
3458+ assert(rc == 0)
3459+
3460+
3461+def prepare_source(source, builder, cached_src, build_src, patch_system):
3462+ '''Download and unpack source package, installing necessary build depends,
3463+ adjusting the permissions for the 'builder' user, and returning the
3464+ directory of the unpacked source. Patch system can be one of:
3465+ - cdbs
3466+ - dpatch
3467+ - quilt
3468+ - quiltv3
3469+ - None (not the string)
3470+
3471+ This is normally used like this:
3472+
3473+ def setUp(self):
3474+ ...
3475+ self.topdir = os.getcwd()
3476+ self.cached_src = os.path.join(os.getcwd(), "source")
3477+ self.tmpdir = tempfile.mkdtemp(prefix='testlib', dir='/tmp')
3478+ self.builder = testlib.TestUser()
3479+ testlib.cmd(['chgrp', self.builder.login, self.tmpdir])
3480+ os.chmod(self.tmpdir, 0o775)
3481+
3482+ def tearDown(self):
3483+ ...
3484+ self.builder = None
3485+ self.topdir = os.getcwd()
3486+ if os.path.exists(self.tmpdir):
3487+ testlib.recursive_rm(self.tmpdir)
3488+
3489+ def test_suite_build(self):
3490+ ...
3491+ build_dir = testlib.prepare_source('foo', \
3492+ self.builder, \
3493+ self.cached_src, \
3494+ os.path.join(self.tmpdir, \
3495+ os.path.basename(self.cached_src)),
3496+ "quilt")
3497+ os.chdir(build_dir)
3498+
3499+ # Example for typical build, adjust as necessary
3500+ print("")
3501+ print(" make clean")
3502+ rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make', 'clean'])
3503+
3504+ print(" configure")
3505+ rc, report = testlib.cmd(['sudo', '-u', self.builder.login, './configure', '--prefix=%s' % self.tmpdir, '--enable-debug'])
3506+
3507+ print(" make (will take a while)")
3508+ rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make'])
3509+
3510+ print(" make check (will take a while)",)
3511+ rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make', 'check'])
3512+ expected = 0
3513+ result = 'Got exit code %d, expected %d\n' % (rc, expected)
3514+ self.assertEqual(expected, rc, result + report)
3515+
3516+ def test_suite_cleanup(self):
3517+ ...
3518+ if os.path.exists(self.cached_src):
3519+ testlib.recursive_rm(self.cached_src)
3520+
3521+ It is up to the caller to clean up cached_src and build_src (as in the
3522+ above example, often the build_src is in a tmpdir that is cleaned in
3523+ tearDown() and the cached_src is cleaned in a one time clean-up
3524+ operation (eg 'test_suite_cleanup()) which must be run after the build
3525+ suite test (obviously).
3526+ '''
3527+
3528+ # Make sure we have a clean slate
3529+ assert (os.path.exists(os.path.dirname(build_src)))
3530+ assert (not os.path.exists(build_src))
3531+
3532+ cdir = os.getcwd()
3533+ if os.path.exists(cached_src):
3534+ shutil.copytree(cached_src, build_src)
3535+ os.chdir(build_src)
3536+ else:
3537+ # Only install the build dependencies on the initial setup
3538+ install_builddeps(source)
3539+ os.makedirs(build_src)
3540+ os.chdir(build_src)
3541+
3542+ # These are always needed
3543+ pkgs = ['build-essential', 'dpkg-dev', 'fakeroot']
3544+ install_packages(pkgs)
3545+
3546+ rc, report = cmd(['apt-get', 'source', source])
3547+ assert (rc == 0)
3548+ shutil.copytree(build_src, cached_src)
3549+ print("(unpacked %s)" % os.path.basename(glob.glob('%s_*.dsc' % source)[0]), end=' ')
3550+
3551+ unpacked_dir = os.path.join(build_src, glob.glob('%s-*' % source)[0])
3552+
3553+ # Now apply the patches. Do it here so that we don't mess up our cached
3554+ # sources.
3555+ os.chdir(unpacked_dir)
3556+ assert (patch_system in ['cdbs', 'dpatch', 'quilt', 'quiltv3', None])
3557+ if patch_system is not None and patch_system != "quiltv3":
3558+ if patch_system == "quilt":
3559+ os.environ.setdefault('QUILT_PATCHES', 'debian/patches')
3560+ rc, report = cmd(['quilt', 'push', '-a'])
3561+ assert (rc == 0)
3562+ elif patch_system == "cdbs":
3563+ rc, report = cmd(['./debian/rules', 'apply-patches'])
3564+ assert (rc == 0)
3565+ elif patch_system == "dpatch":
3566+ rc, report = cmd(['dpatch', 'apply-all'])
3567+ assert (rc == 0)
3568+
3569+ cmd(['chown', '-R', '%s:%s' % (builder.uid, builder.gid), build_src])
3570+ os.chdir(cdir)
3571+
3572+ return unpacked_dir
3573+
3574+
3575+def get_changelog_version(source_dir):
3576+ '''Extract a package version from a changelog'''
3577+ package_version = ""
3578+
3579+ changelog_file = os.path.join(source_dir, "debian/changelog")
3580+
3581+ if os.path.exists(changelog_file):
3582+ changelog = open(changelog_file, 'r')
3583+ header = changelog.readline().split()
3584+ package_version = header[1].strip('()')
3585+
3586+ return package_version
3587+
3588+
3589+def _aa_status():
3590+ '''Get aa-status output'''
3591+ exe = "/usr/sbin/aa-status"
3592+ assert (os.path.exists(exe))
3593+ if os.geteuid() == 0:
3594+ return cmd([exe])
3595+ return cmd(['sudo', exe])
3596+
3597+
3598+def is_apparmor_loaded(path):
3599+ '''Check if profile is loaded'''
3600+ rc, report = _aa_status()
3601+ if rc != 0:
3602+ return False
3603+
3604+ for line in report.splitlines():
3605+ if line.endswith(path):
3606+ return True
3607+ return False
3608+
3609+
3610+def is_apparmor_confined(path):
3611+ '''Check if application is confined'''
3612+ rc, report = _aa_status()
3613+ if rc != 0:
3614+ return False
3615+
3616+ for line in report.splitlines():
3617+ if re.search('%s \(' % path, line):
3618+ return True
3619+ return False
3620+
3621+
3622+def check_apparmor(path, first_ubuntu_release, is_running=True):
3623+ '''Check if path is loaded and confined for everything higher than the
3624+ first Ubuntu release specified.
3625+
3626+ Usage:
3627+ rc, report = testlib.check_apparmor('/usr/sbin/foo', 8.04, is_running=True)
3628+ if rc < 0:
3629+ return self._skipped(report)
3630+
3631+ expected = 0
3632+ result = 'Got exit code %d, expected %d\n' % (rc, expected)
3633+ self.assertEqual(expected, rc, result + report)
3634+ '''
3635+ global manager
3636+ rc = -1
3637+
3638+ if manager.lsb_release["Release"] < first_ubuntu_release:
3639+ return (rc, "Skipped apparmor check")
3640+
3641+ if not os.path.exists('/sbin/apparmor_parser'):
3642+ return (rc, "Skipped (couldn't find apparmor_parser)")
3643+
3644+ rc = 0
3645+ msg = ""
3646+ if not is_apparmor_loaded(path):
3647+ rc = 1
3648+ msg = "Profile not loaded for '%s'" % path
3649+
3650+ # this check only makes sense it the 'path' is currently executing
3651+ if is_running and rc == 0 and not is_apparmor_confined(path):
3652+ rc = 1
3653+ msg = "'%s' is not running in enforce mode" % path
3654+
3655+ return (rc, msg)
3656+
3657+
3658+def get_gcc_version(gcc, full=True):
3659+ gcc_version = 'none'
3660+ if not gcc.startswith('/'):
3661+ gcc = '/usr/bin/%s' % (gcc)
3662+ if os.path.exists(gcc):
3663+ gcc_version = 'unknown'
3664+ lines = cmd([gcc, '-v'])[1].strip().splitlines()
3665+ version_lines = [x for x in lines if x.startswith('gcc version')]
3666+ if len(version_lines) == 1:
3667+ gcc_version = " ".join(version_lines[0].split()[2:])
3668+ if not full:
3669+ return gcc_version.split()[0]
3670+ return gcc_version
3671+
3672+
3673+def is_kdeinit_running():
3674+ '''Test if kdeinit is running'''
3675+ # applications that use kdeinit will spawn it if it isn't running in the
3676+ # test. This is a problem because it does not exit. This is a helper to
3677+ # check for it.
3678+ rc, report = cmd(['ps', 'x'])
3679+ if 'kdeinit4 Running' not in report:
3680+ print("kdeinit not running (you may start/stop any KDE application then run this script again)", file=sys.stderr)
3681+ return False
3682+ return True
3683+
3684+
3685+def get_pkgconfig_flags(libs=[]):
3686+ '''Find pkg-config flags for libraries'''
3687+ assert (len(libs) > 0)
3688+ rc, pkg_config = cmd(['pkg-config', '--cflags', '--libs'] + libs)
3689+ expected = 0
3690+ if rc != expected:
3691+ print('Got exit code %d, expected %d\n' % (rc, expected), file=sys.stderr)
3692+ assert(rc == expected)
3693+ return pkg_config.split()
3694+
3695+
3696+def cap_to_name(cap_num):
3697+ '''given an integer, return the capability name'''
3698+ rc, output = cmd(['capsh', '--decode=%x' % cap_num])
3699+ expected = 0
3700+ if rc != expected:
3701+ print('capsh: got exit code %d, expected %d\n' % (rc, expected), file=sys.stderr)
3702+ cap_name = output.strip().split('=')[1]
3703+ return cap_name
3704+
3705+
3706+def enumerate_capabilities():
3707+ i = 0
3708+ cap_list = []
3709+ done = False
3710+ while not done:
3711+ cap_name = cap_to_name(pow(2, i))
3712+ if cap_name == str(i):
3713+ done = True
3714+ else:
3715+ cap_list.append(cap_name)
3716+ i += 1
3717+ if i > 64:
3718+ done = True
3719+ return cap_list
3720+
3721+
3722+def _run_snap_install(snapname, track="latest/stable", classic=False):
3723+ # crude, but effective
3724+ if os.path.exists(os.path.join("/snap", snapname)):
3725+ return 0, ""
3726+
3727+ command = ["snap", "install", "--channel=%s" % track, snapname]
3728+ if classic:
3729+ command.append("--classic")
3730+ rc, report = cmd(command)
3731+ return rc, report
3732+
3733+
3734+def _run_snap_remove(snapname):
3735+ # crude, but effective
3736+ if not os.path.exists(os.path.join("/snap", snapname)):
3737+ return 0, ""
3738+
3739+ command = ["snap", "remove", "--purge", snapname]
3740+ rc, report = cmd(command)
3741+ return rc, report
3742+
3743+
3744+def install_snap(self, snapname, track="latest/stable", classic=False):
3745+ rc, report = _run_snap_install(snapname, track, classic)
3746+ self.assertEqual(0, rc, "Failed to install snap %s\nOutput:\n%s" %
3747+ (snapname, report))
3748+
3749+
3750+def remove_snap(self, snapname):
3751+ rc, report = _run_snap_remove(snapname)
3752+ self.assertEqual(0, rc, "Failed to install snap %s\nOutput:\n%s" %
3753+ (snapname, report))
3754+
3755+
3756+class TestDaemon:
3757+ '''Helper class to manage daemons consistently'''
3758+ def __init__(self, service_name):
3759+ '''Setup daemon attributes'''
3760+ if os.path.isfile('/usr/sbin/service') or os.path.islink('/usr/sbin/service'):
3761+ self.test_daemon_commands = ['service', service_name]
3762+ else:
3763+ self.test_daemon_commands = ['/etc/init.d/' + service_name]
3764+
3765+ def _run_command(self, action, seconds_to_wait=2):
3766+ command = list(self.test_daemon_commands)
3767+ command.append(action)
3768+ rc, report = cmd(command)
3769+ expected = 0
3770+ result = 'Got exit code %d, expected %d\n' % (rc, expected)
3771+ time.sleep(seconds_to_wait)
3772+ if expected != rc:
3773+ return False, result + report
3774+
3775+ if "fail" in report:
3776+ return False, "Found 'fail' in report\n" + report
3777+
3778+ return True, ""
3779+
3780+ def start(self):
3781+ '''Start daemon'''
3782+ return self._run_command('start')
3783+
3784+ def stop(self):
3785+ '''Stop daemon'''
3786+ return self._run_command('stop')
3787+
3788+ def reload(self):
3789+ '''Reload daemon'''
3790+ return self._run_command('force-reload')
3791+
3792+ def restart(self):
3793+ if self.test_daemon_commands[0] == 'service':
3794+ return self._run_command('restart')
3795+ else:
3796+ '''Restart daemon'''
3797+ (res, str) = self.stop()
3798+ if not res:
3799+ return res, str
3800+
3801+ (res, str) = self.start()
3802+ if not res:
3803+ return res, str
3804+
3805+ return True, ""
3806+
3807+ def force_restart(self):
3808+ '''Restart daemon even if already stopped'''
3809+ self.stop()
3810+
3811+ (res, str) = self.start()
3812+ if not res:
3813+ return res, str
3814+
3815+ return True, ""
3816+
3817+ def status(self):
3818+ '''Check daemon status'''
3819+ return self._run_command('status')
3820+
3821+
3822+class TestlibManager(object):
3823+ '''Singleton class used to set up per-test-run information'''
3824+ def __init__(self):
3825+ # Set glibc aborts to dump to stderr instead of the tty so test output
3826+ # is more sane.
3827+ os.environ.setdefault('LIBC_FATAL_STDERR_', '1')
3828+
3829+ # check verbosity
3830+ self.verbosity = False
3831+ if (len(sys.argv) > 1 and '-v' in sys.argv[1:]):
3832+ self.verbosity = True
3833+
3834+ # Load LSB release file
3835+ self.lsb_release = dict()
3836+ if not os.path.exists('/usr/bin/lsb_release') and not os.path.exists('/bin/lsb_release'):
3837+ raise OSError("Please install 'lsb-release'")
3838+ for line in subprocess.Popen(['lsb_release', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).communicate()[0].splitlines():
3839+ field, value = line.split(':', 1)
3840+ value = value.strip()
3841+ field = field.strip()
3842+ # Convert numerics
3843+ try:
3844+ value = float(value)
3845+ except:
3846+ pass
3847+ self.lsb_release.setdefault(field, value)
3848+
3849+ # FIXME: hack OEM releases into known-Ubuntu versions
3850+ if self.lsb_release['Distributor ID'] == "HP MIE (Mobile Internet Experience)":
3851+ if self.lsb_release['Release'] == 1.0:
3852+ self.lsb_release['Distributor ID'] = "Ubuntu"
3853+ self.lsb_release['Release'] = 8.04
3854+ else:
3855+ raise OSError("Unknown version of HP MIE")
3856+
3857+ # FIXME: hack to assume a most-recent release if we're not
3858+ # running under Ubuntu.
3859+ if self.lsb_release['Distributor ID'] not in ["Ubuntu", "Linaro"]:
3860+ self.lsb_release['Release'] = 10000
3861+ # Adjust Linaro release to pretend to be Ubuntu
3862+ if self.lsb_release['Distributor ID'] in ["Linaro"]:
3863+ self.lsb_release['Distributor ID'] = "Ubuntu"
3864+ self.lsb_release['Release'] -= 0.01
3865+
3866+ # Load arch
3867+ if not os.path.exists('/usr/bin/dpkg'):
3868+ machine = cmd(['uname', '-m'])[1].strip()
3869+ if machine.endswith('86'):
3870+ self.dpkg_arch = 'i386'
3871+ elif machine.endswith('_64'):
3872+ self.dpkg_arch = 'amd64'
3873+ elif machine.startswith('arm'):
3874+ self.dpkg_arch = 'armel'
3875+ else:
3876+ raise ValueError("Unknown machine type '%s'" % (machine))
3877+ else:
3878+ self.dpkg_arch = cmd(['dpkg', '--print-architecture'])[1].strip()
3879+
3880+ # Find kernel version
3881+ self.kernel_is_ubuntu = False
3882+ self.kernel_version_signature = None
3883+ self.kernel_version = cmd(["uname", "-r"])[1].strip()
3884+ versig = '/proc/version_signature'
3885+ if os.path.exists(versig):
3886+ self.kernel_is_ubuntu = True
3887+ self.kernel_version_signature = open(versig).read().strip()
3888+ self.kernel_version_ubuntu = self.kernel_version
3889+ elif os.path.exists('/usr/bin/dpkg'):
3890+ # this can easily be inaccurate but is only an issue for Dapper
3891+ rc, out = cmd(['dpkg', '-l', 'linux-image-%s' % (self.kernel_version)])
3892+ if rc == 0:
3893+ self.kernel_version_signature = out.strip().split('\n').pop().split()[2]
3894+ self.kernel_version_ubuntu = self.kernel_version_signature
3895+ if self.kernel_version_signature is None:
3896+ # Attempt to fall back to something for non-Debian-based
3897+ self.kernel_version_signature = self.kernel_version
3898+ self.kernel_version_ubuntu = self.kernel_version
3899+ # Build ubuntu version without hardware suffix
3900+ try:
3901+ self.kernel_version_ubuntu = "-".join([x for x in self.kernel_version_signature.split(' ')[1].split('-') if re.search('^[0-9]', x)])
3902+ except:
3903+ pass
3904+
3905+ # Find gcc version
3906+ self.gcc_version = get_gcc_version('gcc')
3907+
3908+ # Find libc
3909+ self.path_libc = [x.split()[2] for x in cmd(['ldd', '/bin/ls'])[1].splitlines() if x.startswith('\tlibc.so.')][0]
3910+
3911+ # Report self
3912+ if self.verbosity:
3913+ kernel = self.kernel_version_ubuntu
3914+ if kernel != self.kernel_version_signature:
3915+ kernel += " (%s)" % (self.kernel_version_signature)
3916+ print("Running test: '%s' distro: '%s %.2f' kernel: '%s' arch: '%s' uid: %d/%d SUDO_USER: '%s')" % (
3917+ sys.argv[0],
3918+ self.lsb_release['Distributor ID'],
3919+ self.lsb_release['Release'],
3920+ kernel,
3921+ self.dpkg_arch,
3922+ os.geteuid(), os.getuid(),
3923+ os.environ.get('SUDO_USER', '')), file=sys.stdout)
3924+ sys.stdout.flush()
3925+
3926+ # Additional heuristics
3927+ # if os.environ.get('SUDO_USER', os.environ.get('USER', '')) in ['mdeslaur']:
3928+ # sys.stdout.write("Replying to Marc Deslauriers in http://launchpad.net/bugs/%d: " % random.randint(600000, 980000))
3929+ # sys.stdout.flush()
3930+ # time.sleep(0.5)
3931+ # sys.stdout.write("destroyed\n")
3932+ # time.sleep(0.5)
3933+
3934+ def hello(self, msg):
3935+ print("Hello from %s" % (msg), file=sys.stderr)
3936+# The central instance
3937+manager = TestlibManager()
3938+
3939+
3940+class TestlibCase(unittest.TestCase):
3941+ def __init__(self, *args):
3942+ '''This is called for each TestCase test instance, which isn't much better
3943+ than SetUp.'''
3944+
3945+ unittest.TestCase.__init__(self, *args)
3946+
3947+ # Attach to and duplicate dicts from manager singleton
3948+ self.manager = manager
3949+ # self.manager.hello(repr(self) + repr(*args))
3950+ self.my_verbosity = self.manager.verbosity
3951+ self.lsb_release = self.manager.lsb_release
3952+ self.dpkg_arch = self.manager.dpkg_arch
3953+ self.kernel_version = self.manager.kernel_version
3954+ self.kernel_version_signature = self.manager.kernel_version_signature
3955+ self.kernel_version_ubuntu = self.manager.kernel_version_ubuntu
3956+ self.kernel_is_ubuntu = self.manager.kernel_is_ubuntu
3957+ self.gcc_version = self.manager.gcc_version
3958+ self.path_libc = self.manager.path_libc
3959+
3960+ def version_compare(self, one, two):
3961+ if 'version_compare' in dir(apt_pkg):
3962+ return apt_pkg.version_compare(one, two)
3963+ else:
3964+ return apt_pkg.VersionCompare(one, two)
3965+
3966+ def assertFileType(self, filename, filetype, strict=True):
3967+ '''Checks the file type of the file specified'''
3968+
3969+ (rc, report, out) = self._testlib_shell_cmd(["/usr/bin/file", "-b", filename])
3970+ out = out.strip()
3971+ expected = 0
3972+ # Absolutely no idea why this happens on Hardy
3973+ if self.lsb_release['Release'] == 8.04 and rc == 255 and len(out) > 0:
3974+ rc = 0
3975+ result = 'Got exit code %d, expected %d:\n%s\n' % (rc, expected, report)
3976+ self.assertEqual(expected, rc, result)
3977+
3978+ if strict:
3979+ filetype = '^%s$' % (filetype)
3980+ else:
3981+ # accept if the beginning of the line matches
3982+ filetype = '^%s' % (filetype)
3983+ result = 'File type reported by file: [%s], expected regex: [%s]\n' % (out, filetype)
3984+ self.assertNotEqual(None, re.search(filetype, out), result)
3985+
3986+ def yank_commonname_from_cert(self, certfile):
3987+ '''Extract the commonName from a given PEM'''
3988+ rc, out = cmd(['openssl', 'asn1parse', '-in', certfile])
3989+ if rc == 0:
3990+ ready = False
3991+ for line in out.splitlines():
3992+ if ready:
3993+ return line.split(':')[-1]
3994+ if ':commonName' in line:
3995+ ready = True
3996+ return socket.getfqdn()
3997+
3998+ def announce(self, text):
3999+ if self.my_verbosity:
4000+ print("(%s) " % (text), file=sys.stderr, end='')
4001+ sys.stdout.flush()
4002+
4003+ def make_clean(self):
4004+ rc, output = self.shell_cmd(['make', 'clean'])
4005+ self.assertEqual(rc, 0, output)
4006+
4007+ def get_makefile_compiler(self):
4008+ # Find potential compiler name
4009+ compiler = 'gcc'
4010+ if os.path.exists('Makefile'):
4011+ for line in open('Makefile'):
4012+ if line.startswith('CC') and '=' in line:
4013+ items = [x.strip() for x in line.split('=')]
4014+ if items[0] == 'CC':
4015+ compiler = items[1]
4016+ break
4017+ return compiler
4018+
4019+ def make_target(self, target, expected=0):
4020+ '''Compile a target and report output'''
4021+
4022+ compiler = self.get_makefile_compiler()
4023+ rc, output = self.shell_cmd(['make', target])
4024+ self.assertEqual(rc, expected, 'rc(%d)!=%d:\n' % (rc, expected) + output)
4025+ self.assertTrue('%s ' % (compiler) in output, 'Expected "%s":' % (compiler) + output)
4026+ return output
4027+
4028+ # call as return testlib.skipped()
4029+ def _skipped(self, reason=""):
4030+ '''Provide a visible way to indicate that a test was skipped'''
4031+ if reason != "":
4032+ reason = ': %s' % (reason)
4033+ self.announce("skipped%s" % (reason))
4034+ return False
4035+
4036+ def _testlib_shell_cmd(self, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=None):
4037+ argstr = "'" + "', '".join(args).strip() + "'"
4038+ rc, out = cmd(args, stdin=stdin, stdout=stdout, stderr=stderr, env=env)
4039+ report = 'Command: ' + argstr + '\nOutput:\n' + out
4040+ return rc, report, out
4041+
4042+ def shell_cmd(self, args, stdin=None):
4043+ return cmd(args, stdin=stdin)
4044+
4045+ def assertShellExitEquals(self, expected, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=None, msg="", bare_report=False):
4046+ '''Test a shell command matches a specific exit code'''
4047+ rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr, env=env)
4048+ result = 'Got exit code %d, expected %d\n' % (rc, expected)
4049+ self.assertEqual(expected, rc, msg + result + report)
4050+ if bare_report:
4051+ return out
4052+ else:
4053+ return report
4054+
4055+ def assertShellExitSuccess(self, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=None, msg="", bare_report=False):
4056+ '''Same as assertShellEquals but with an expected exit status of 0 (success).'''
4057+ return self.assertShellExitEquals(0, args, stdin, stdout, stderr, env, msg, bare_report)
4058+
4059+ # make sure exit value is in a list of expected values
4060+ def assertShellExitIn(self, expected, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg=""):
4061+ '''Test a shell command matches a specific exit code'''
4062+ rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
4063+ result = 'Got exit code %d, expected one of %s\n' % (rc, ', '.join(map(str, expected)))
4064+ self.assertIn(rc, expected, msg + result + report)
4065+
4066+ def assertShellExitNotEquals(self, unwanted, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg=""):
4067+ '''Test a shell command doesn't match a specific exit code'''
4068+ rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
4069+ result = 'Got (unwanted) exit code %d\n' % rc
4070+ self.assertNotEqual(unwanted, rc, msg + result + report)
4071+
4072+ def assertShellOutputContains(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False, expected=None):
4073+ '''Test a shell command contains a specific output'''
4074+ rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
4075+ result = 'Got exit code %d. Looking for text "%s"\n' % (rc, text)
4076+ if not invert:
4077+ self.assertTrue(text in out, msg + result + report)
4078+ else:
4079+ self.assertFalse(text in out, msg + result + report)
4080+ if expected is not None:
4081+ result = 'Got exit code %d. Expected %d (%s)\n' % (rc, expected, " ".join(args))
4082+ self.assertEqual(rc, expected, msg + result + report)
4083+
4084+ def assertShellOutputEquals(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False, expected=None):
4085+ '''Test a shell command matches a specific output'''
4086+ rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
4087+ result = 'Got exit code %d. Looking for exact text "%s" (%s)\n' % (rc, text, " ".join(args))
4088+ if not invert:
4089+ self.assertEqual(text, out, msg + result + report)
4090+ else:
4091+ self.assertNotEqual(text, out, msg + result + report)
4092+ if expected is not None:
4093+ result = 'Got exit code %d. Expected %d (%s)\n' % (rc, expected, " ".join(args))
4094+ self.assertEqual(rc, expected, msg + result + report)
4095+
4096+ def _word_find(self, report, content, invert=False):
4097+ '''Check for a specific string'''
4098+ if invert:
4099+ warning = 'Found "%s"\n' % content
4100+ self.assertTrue(content not in report, warning + report)
4101+ else:
4102+ warning = 'Could not find "%s"\n' % content
4103+ self.assertTrue(content in report, warning + report)
4104+
4105+ def _test_sysctl_value(self, path, expected, msg=None, exists=True):
4106+ sysctl = '/proc/sys/%s' % (path)
4107+ self.assertEqual(exists, os.path.exists(sysctl), sysctl)
4108+ value = None
4109+ if exists:
4110+ with open(sysctl) as sysctl_fd:
4111+ value = int(sysctl_fd.read())
4112+ report = "%s is not %d: %d" % (sysctl, expected, value)
4113+ if msg:
4114+ report += " (%s)" % (msg)
4115+ self.assertEqual(value, expected, report)
4116+ return value
4117+
4118+ def set_sysctl_value(self, path, desired):
4119+ sysctl = '/proc/sys/%s' % (path)
4120+ self.assertTrue(os.path.exists(sysctl), "%s does not exist" % (sysctl))
4121+ with open(sysctl, 'w') as sysctl_fh:
4122+ sysctl_fh.write(str(desired))
4123+ self._test_sysctl_value(path, desired)
4124+
4125+ def kernel_at_least(self, introduced):
4126+ return self.version_compare(self.kernel_version_ubuntu,
4127+ introduced) >= 0
4128+
4129+ def kernel_claims_cve_fixed(self, cve):
4130+ changelog = "/usr/share/doc/linux-image-%s/changelog.Debian.gz" % (self.kernel_version)
4131+ if os.path.exists(changelog):
4132+ for line in gzip.open(changelog):
4133+ if cve in line and "revert" not in line and "Revert" not in line:
4134+ return True
4135+ return False
4136+
4137+ def install_builddeps(self, src_pkg):
4138+ rc, report = _run_apt_command([src_pkg], 'build-dep')
4139+ self.assertEqual(0, rc, 'Failed to install build-deps for %s\nOutput:\n%s' % (src_pkg, report))
4140+
4141+ def install_package(self, package):
4142+ rc, report = _run_apt_command([package], 'install')
4143+ self.assertEqual(0, rc, 'Failed to install package %s\nOutput:\n%s' % (package, report))
4144+
4145+ def install_packages(self, pkg_list):
4146+ rc, report = _run_apt_command(pkg_list, 'install')
4147+ self.assertEqual(0, rc, 'Failed to install packages %s\nOutput:\n%s' % (','.join(pkg_list), report))
4148+
4149+ def install_snap(self, snapname, track="latest/stable", classic=False):
4150+ rc, report = _run_snap_install(snapname, track, classic)
4151+ self.assertEqual(0, rc, "Failed to install snap %s\nOutput:\n%s" %
4152+ (snapname, report))
4153+
4154+ def remove_snap(self, snapname):
4155+ rc, report = _run_snap_remove(snapname)
4156+ self.assertEqual(0, rc, "Failed to install snap %s\nOutput:\n%s" %
4157+ (snapname, report))
4158+
4159+
4160+class TestGroup:
4161+ '''Create a temporary test group and remove it again in the dtor.'''
4162+
4163+ def __init__(self, group=None, lower=False):
4164+ '''Create a new group'''
4165+
4166+ self.group = None
4167+ if group:
4168+ if group_exists(group):
4169+ raise ValueError('group name already exists')
4170+ else:
4171+ while(True):
4172+ group = random_string(7, lower=lower)
4173+ if not group_exists(group):
4174+ break
4175+
4176+ assert subprocess.call(['groupadd', group]) == 0
4177+ self.group = group
4178+ g = grp.getgrnam(self.group)
4179+ self.gid = g[2]
4180+
4181+ def __del__(self):
4182+ '''Remove the created group.'''
4183+
4184+ if self.group:
4185+ rc, report = cmd(['groupdel', self.group])
4186+ assert rc == 0
4187+
4188+
4189+class TestUser:
4190+ '''Create a temporary test user and remove it again in the dtor.'''
4191+
4192+ def __init__(self, login=None, home=True, group=None, uidmin=None, lower=False, shell=None):
4193+ '''Create a new user account with a random password.
4194+
4195+ By default, the login name is random, too, but can be explicitly
4196+ specified with 'login'. By default, a home directory is created, this
4197+ can be suppressed with 'home=False'.'''
4198+
4199+ self.login = None
4200+
4201+ if os.geteuid() != 0:
4202+ raise ValueError("You must be root to run this test")
4203+
4204+ if login:
4205+ if login_exists(login):
4206+ raise ValueError('login name already exists')
4207+ else:
4208+ while(True):
4209+ login = 't' + random_string(7, lower=lower)
4210+ if not login_exists(login):
4211+ break
4212+
4213+ # when fips is enabled, python2.7 crypt.crypt() returns None
4214+ # for DES salts for being too weak. Force sha256 with "$5$" for
4215+ # the salt. XXX in python3, the salt is optional and will
4216+ # generate strong passwords automatically.
4217+ self.salt = "$5$%s" % random_string(2)
4218+ self.password = random_string(8, lower=lower)
4219+ self.crypted = crypt.crypt(self.password, self.salt)
4220+
4221+ creation = ['useradd', '-p', self.crypted]
4222+ if home:
4223+ creation += ['-m']
4224+ if group:
4225+ creation += ['-G', group]
4226+ if uidmin:
4227+ creation += ['-K', 'UID_MIN=%d' % uidmin]
4228+ if shell:
4229+ creation += ['-s', shell]
4230+ creation += [login]
4231+ assert subprocess.call(creation) == 0
4232+ # Set GECOS
4233+ assert subprocess.call(['usermod', '-c', 'Buddy %s' % (login), login]) == 0
4234+
4235+ self.login = login
4236+ p = pwd.getpwnam(self.login)
4237+ self.uid = p[2]
4238+ self.gid = p[3]
4239+ self.gecos = p[4]
4240+ self.home = p[5]
4241+ self.shell = p[6]
4242+
4243+ def __del__(self):
4244+ '''Remove the created user account.'''
4245+
4246+ if self.login:
4247+ # sanity check the login name so we don't accidentally wipe too much
4248+ if len(self.login) > 3 and '/' not in self.login:
4249+ subprocess.call(['rm', '-rf', '/home/' + self.login, '/var/mail/' + self.login])
4250+ rc, report = cmd(['userdel', '-f', self.login])
4251+ assert rc == 0
4252+
4253+ def add_to_group(self, group):
4254+ '''Add user to the specified group name'''
4255+ rc, report = cmd(['usermod', '-G', group, self.login])
4256+ if rc != 0:
4257+ print(report)
4258+ assert rc == 0
4259+
4260+
4261+class AddUser:
4262+ '''Create a temporary test user and remove it again in the dtor.'''
4263+
4264+ def __init__(self, login=None, home=True, encrypt_home=False, group=None, lower=False, shell=None):
4265+ '''Create a new user account with a random password.
4266+
4267+ By default, the login name is random, too, but can be explicitly
4268+ specified with 'login'. By default, a home directory is created, this
4269+ can be suppressed with 'home=False'.
4270+
4271+ This class differs from the TestUser class in that the adduser/deluser
4272+ tools are used rather than the useradd/user/del tools. The adduser
4273+ program is the only commandline program that can be used to add a new
4274+ user with an encrypted home directory. It is possible that the AddUser
4275+ class may replace the TestUser class in the future.'''
4276+
4277+ self.login = None
4278+
4279+ if os.geteuid() != 0:
4280+ raise ValueError("You must be root to run this test")
4281+
4282+ if login:
4283+ if login_exists(login):
4284+ raise ValueError('login name already exists')
4285+ else:
4286+ while(True):
4287+ login = 't' + random_string(7, lower=True)
4288+ if not login_exists(login):
4289+ break
4290+
4291+ self.password = random_string(8, lower=lower)
4292+
4293+ creation = ['adduser', '--quiet']
4294+
4295+ if not home:
4296+ creation += ['--no-create-home']
4297+ elif encrypt_home:
4298+ creation += ['--encrypt-home']
4299+
4300+ if shell:
4301+ creation += ['--shell', shell]
4302+
4303+ creation += ['--gecos', 'Buddy %s' % (login), login]
4304+
4305+ child = pexpect.spawn(creation.pop(0), creation, timeout=5)
4306+ assert child.expect(b'(Enter new UNIX|New) password:') == 0
4307+ child.sendline(self.password)
4308+ assert child.expect(b'Retype new (UNIX )?password:') == 0
4309+ child.sendline(self.password)
4310+
4311+ child.wait()
4312+ child.close()
4313+ assert child.exitstatus == 0
4314+ assert child.signalstatus is None
4315+
4316+ self.login = login
4317+
4318+ if group:
4319+ assert self.add_to_group(group) == 0
4320+
4321+ p = pwd.getpwnam(self.login)
4322+ self.uid = p[2]
4323+ self.gid = p[3]
4324+ self.gecos = p[4]
4325+ self.home = p[5]
4326+ self.shell = p[6]
4327+
4328+ def __del__(self):
4329+ '''Remove the created user account.'''
4330+
4331+ if self.login:
4332+ # sanity check the login name so we don't accidentally wipe too much
4333+ rc, report = cmd(['deluser', '--remove-home', self.login])
4334+ assert rc == 0
4335+
4336+ def add_to_group(self, group):
4337+ '''Add user to the specified group name'''
4338+ rc, report = cmd(['adduser', self.login, group])
4339+ if rc != 0:
4340+ print(report)
4341+ assert rc == 0
4342+
4343+
4344+# Timeout handler using alarm() from John P. Speno's Pythonic Avocado
4345+class TimeoutFunctionException(Exception):
4346+ """Exception to raise on a timeout"""
4347+ pass
4348+
4349+
4350+class TimeoutFunction:
4351+ def __init__(self, function, timeout):
4352+ self.timeout = timeout
4353+ self.function = function
4354+
4355+ def handle_timeout(self, signum, frame):
4356+ raise TimeoutFunctionException()
4357+
4358+ def __call__(self, *args, **kwargs):
4359+ old = signal.signal(signal.SIGALRM, self.handle_timeout)
4360+ signal.alarm(self.timeout)
4361+ try:
4362+ result = self.function(*args, **kwargs)
4363+ finally:
4364+ signal.signal(signal.SIGALRM, old)
4365+ signal.alarm(0)
4366+ return result
4367+
4368+
4369+def main():
4370+ print("hi")
4371+ unittest.main()
4372diff --git a/debian/tests/testsuite b/debian/tests/testsuite
4373new file mode 100644
4374index 0000000..29cf597
4375--- /dev/null
4376+++ b/debian/tests/testsuite
4377@@ -0,0 +1,6 @@
4378+#!/bin/bash
4379+#-------------------
4380+# Testing open-iscsi
4381+#-------------------
4382+set -e
4383+python3 `dirname $0`/test-open-iscsi.py 2>&1
4384diff --git a/debian/tests/tgt-boot-test b/debian/tests/tgt-boot-test
4385new file mode 100755
4386index 0000000..af5ec50
4387--- /dev/null
4388+++ b/debian/tests/tgt-boot-test
4389@@ -0,0 +1,534 @@
4390+#!/bin/bash
4391+
4392+VERBOSITY=0
4393+TEMP_D=""
4394+DEF_WPORT=32600
4395+IPV4_NET="10.0.12"
4396+DEF_NETDEV="user,net=${IPV4_NET}.0/24,host=${IPV4_NET}.2"
4397+
4398+ISCSI_PORT=3260
4399+TGT_CONF=""
4400+HTTP_PID=""
4401+TGT_NAME=""
4402+
4403+_DEF_CMDLINE_TMPL=(
4404+ nomodeset {icmdline_parms} {cmdline_ip} ro
4405+ net.ifnames=0 BOOTIF_DEFAULT=eth0
4406+ root={root} {overlay_drive}
4407+ console=ttyS0 {cmdline_ds}
4408+ # LP: #1796137
4409+ systemd.mask=snapd.seeded.service systemd.mask=snapd.service
4410+)
4411+DEF_CMDLINE_TMPL="${_DEF_CMDLINE_TMPL[*]}"
4412+
4413+error() { echo "$@" 1>&2; }
4414+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
4415+
4416+cleanup() {
4417+ [ ! -d "$TEMP_D" ] || rm -Rf "$TEMP_D"
4418+ if [ -f "$TGT_CONF" ]; then
4419+ error "cleaning up tgt mount ${TGT_NAME}"
4420+ sudo tgt-admin --force --delete="$TGT_NAME"
4421+ sudo rm -f "$TGT_CONF"
4422+ fi
4423+ if [ -n "$HTTP_PID" ]; then
4424+ kill $HTTP_PID
4425+ fi
4426+}
4427+
4428+Usage() {
4429+ cat <<EOF
4430+Usage: ${0##*/} [ options ] image kernel initrd
4431+
4432+ put 'image' into tgt, boot 'kernel' and 'initrd' in a kvm
4433+ guest pointing to that iscsi target.
4434+
4435+ options:
4436+ -p | --webserv-port PORT serve cloud-init seed on port PORT
4437+ default: ${DEF_WPORT}
4438+ -O | --overlay-disk DISK attach DISK to guest and use it for the overlayroot
4439+ target. Use 'temp' to use a temp file.
4440+ use an existing file to use that. Use a
4441+ non-existing file to create.
4442+ -n | --netdev DEV passed through to xkvm.
4443+ if none passed, default is:
4444+ $DEF_NETDEV
4445+ -a | --host-addr ADDR will be used for iscsi host address and
4446+ cloud-init seed address. Default is read
4447+ from 'host=' in --netdev arg.
4448+ -l | --serial-log FILE write serial log to FILE default is to let output
4449+ go to console.
4450+ --cmdline TMPL template for kernel command line.
4451+ default: ${DEF_CMDLINE_TMPL}
4452+ --cmdline-add ARGS add the args to the kernel command line. default: ""
4453+ --user-data FILE user-data to provide to instance.
4454+ default: builtin
4455+ --user-data-add FILE append FILE to default user-data.
4456+EOF
4457+}
4458+
4459+bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
4460+
4461+debug() {
4462+ local level=${1}; shift;
4463+ [ "${level}" -gt "${VERBOSITY}" ] && return
4464+ error "${@}"
4465+}
4466+
4467+write_userdata() {
4468+ ## set up a user-data and meta-data for cloud-init
4469+ ## and we'll seed that through the kernel command line
4470+ ##
4471+ ## The user data we provide will allow us to log in
4472+ ## as the 'ubuntu' user with 'passw0rd'.
4473+ local out="$1" keys="${2:-[]}"
4474+ cat > "$out" <<"EOF"
4475+#cloud-config
4476+chpasswd:
4477+ expire: False
4478+ list: |
4479+ ubuntu:passw0rd
4480+ root:root
4481+ssh_pwauth: True
4482+EOF
4483+}
4484+
4485+get_ssh_pubkeys() {
4486+ # get users ssh pubkeys in a yaml list format
4487+ local keys="" d=""
4488+ keys=$( (ssh-add -L 2>/dev/null ;
4489+ [ -f ~/.ssh/id_rsa.pub ] && cat ~/.ssh/id_rsa.pub ) | sort -u )
4490+ if [ -n "$keys" ]; then
4491+ d=$(IFS=$'\n'; for i in ${keys}; do echo "'$i',"; done)
4492+ keys="[${d%,}]"
4493+ else
4494+ keys="[]"
4495+ fi
4496+ _RET="$keys"
4497+}
4498+
4499+write_metadata() {
4500+ local iid="" out="$1" pubkeys="$2"
4501+ iid=$(uuidgen 2>/dev/null || echo i-abcdefg)
4502+ {
4503+ echo "instance-id: $iid"
4504+ if [ -n "$pubkeys" ]; then
4505+ echo "public-keys: $pubkeys"
4506+ fi
4507+ } > "$out"
4508+}
4509+
4510+register_image() {
4511+ local conf="$1" name="$2" image="$3"
4512+ sudo tee "$conf" >/dev/null <<EOF
4513+<target ${name}>
4514+ readonly 1
4515+ backing-store "$image"
4516+ allow-in-use yes
4517+</target>
4518+EOF
4519+ [ $? -eq 0 ] || { error "failed to write '$conf'"; return 1; }
4520+
4521+ sudo tgt-admin "--update=$name" ||
4522+ { error "failed tgt-admin update=$name"; return 1; }
4523+}
4524+
4525+address_on_dev() {
4526+ local dev="$1" atype="${2:-inet}" out="" addr=""
4527+ out=$(ip address show dev "$dev" 2>/dev/null) ||
4528+ { error "could not get address on $1"; return 1; }
4529+ addr=$(echo "$out" |
4530+ awk '$1 == atype && $4 == "global" {
4531+ sub(/\/.*/, "", $2); print $2; exit(0); }' "atype=$atype" )
4532+ [ -n "$addr" ] || return
4533+ _RET="$addr"
4534+}
4535+
4536+find_host_addr() {
4537+ # run through --netdev args and fine 'host=' or make one up base
4538+ # on there being a net= and assume .2 for host.
4539+ # example: type=user,id=net00,net=10.0.12.0/24,host=10.0.12.2
4540+ # ipv6-net=fec0::/64,ipv6-host=fec0::2
4541+ # lxcbr0
4542+ local nd="" atype="" bridge=""
4543+ local oifs="$IFS"
4544+ for nd in "$@"; do
4545+ local host="" netaddr="" cur="" ipv4="x" ipv6="x" ntype=""
4546+ bridge=${nd%%,*}
4547+ if [ "$bridge" != "user" -a -e "/sys/class/net/$bridge" ]; then
4548+ for atype in inet inet6; do
4549+ address_on_dev "$bridge" "$atype" || continue
4550+ debug 2 "took $atype address on bridge '$bridge': $_RET";
4551+ return 0;
4552+ done
4553+ fi
4554+ cur=${nd}
4555+ while :; do
4556+ first=${cur%%,*}
4557+ rest=${cur#*,}
4558+ case "$first" in
4559+ user) ntype=user;;
4560+ ipv4=on|ipv4) ipv4=on;;
4561+ ipv4=off) ipv4=off;;
4562+ ipv6=on|ipv6) ipv6=on;;
4563+ ipv6=off) ipv6=off;;
4564+ ipv6-net=*) tmp=${first#*=};
4565+ tmp=${tmp%/*}
4566+ netaddr="${tmp%.*}:2"
4567+ ;;
4568+ net=*) tmp=${first#*=};
4569+ tmp=${tmp%/*}
4570+ netaddr="${tmp%.*}.2"
4571+ ;;
4572+ host=*|ipv6-host=) host=${first#*=};;
4573+ esac
4574+ if [ "$first" = "$rest" ]; then
4575+ # there was no ','
4576+ break
4577+ fi
4578+ cur=$rest
4579+ done
4580+ local found="" msg=""
4581+ if [ -n "$host" ]; then
4582+ found="$host"
4583+ msg="host= in '$nd'"
4584+ elif [ -n "$netaddr" ]; then
4585+ found="$netaddr"
4586+ msg="second address on net= in '$nd'";
4587+ elif [ "$ntype" = "user" ]; then
4588+ case "$ipv4/$ipv6" in
4589+ */on)
4590+ msg="known user net default host in ipv6 in '$nd'"
4591+ found="fec0::2";;
4592+ x/x|on/*)
4593+ msg="known user net default host in ipv4 in '$nd'"
4594+ found="10.0.2.2";;
4595+ esac
4596+ fi
4597+ if [ -n "$found" ]; then
4598+ debug 2 "found host address '$found' via $msg"
4599+ _RET="$found"
4600+ return 0
4601+ fi
4602+ done
4603+ return 1
4604+}
4605+
4606+
4607+get_rfc4173() {
4608+ # protocol would normally be '6' (tcp but empty is fine)
4609+ # https://tools.ietf.org/html/rfc4173
4610+ # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=804162
4611+ local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6" proto="$7"
4612+ local rfc="" auth="${user:+${user}${pass:+:${pass}}}"
4613+ rfc="iscsi:"
4614+ if [ -n "${user}" ]; then
4615+ rfc="$rfc:${user}${pass:+:${pass}}"
4616+ fi
4617+ case "$server" in
4618+ \[*\]) :;;
4619+ *:*) server="[$server]";;
4620+ esac
4621+ rfc="${server}:$proto:${port}:${lun}:${name}"
4622+ _RET="$rfc"
4623+}
4624+
4625+get_root_parm() {
4626+ local server="$1" name="$2" port="${3:-$ISCSI_PORT}"
4627+ local lun="$4" user="$5" pass="$6" proto="$7" part="$8"
4628+ local ret=""
4629+ # for ipv6 addresses, path just contains : for the server
4630+ _RET="/dev/disk/by-path/ip-$server:$port-iscsi-${name}-lun-${lun}${part:+-part$part}"
4631+}
4632+
4633+get_cmdline_params() {
4634+ local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6"
4635+ local proto="$7" initiator="$8" ret=""
4636+ ret="${initiator:+iscsi_initiator=${initiator} }"
4637+ ret="${ret}iscsi_target_name=$name "
4638+ ret="${ret}iscsi_target_ip=$server "
4639+ ret="${ret}${port:+iscsi_target_port=$port }"
4640+ ret="${ret}${initiator:+iscsi_initiator=$initiator }"
4641+ _RET=${ret% }
4642+}
4643+
4644+get_iscsi_cmd() {
4645+ local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6"
4646+ local proto="$7" initiator="$8" ret="" group=${9:-1}
4647+ _RET=( iscsistart -i "$initiator"
4648+ -t "$name" -g "$group" -a "$server" -p "$port"
4649+ ${user:+-u "$user"} ${pass:+-w "${pass}"} )
4650+}
4651+
4652+serv_http() {
4653+ local dir="$1" port="$2" check="$3"
4654+ local python="" kid=""
4655+ command -v python3 >/dev/null 2>&1 && python=python3 || python=python2
4656+ cat > "$TEMP_D/webserv" <<EOF
4657+import os, socket, sys
4658+try:
4659+ from BaseHTTPServer import HTTPServer
4660+ from SimpleHTTPServer import SimpleHTTPRequestHandler
4661+except ImportError:
4662+ from http.server import HTTPServer, SimpleHTTPRequestHandler
4663+
4664+class HTTPServerV6(HTTPServer):
4665+ address_family = socket.AF_INET6
4666+
4667+if __name__ == "__main__":
4668+ dir = sys.argv[1]
4669+ port = int(sys.argv[2])
4670+ os.chdir(dir)
4671+ server = HTTPServerV6(("::", port), SimpleHTTPRequestHandler)
4672+ server.serve_forever()
4673+EOF
4674+ $python "$TEMP_D/webserv" "$dir" "$port" &
4675+ HTTP_PID=$!
4676+ local i=0 site="127.0.0.1"
4677+ local url="http://$site:$port/$check"
4678+ while [ -d /proc/$HTTP_PID -a "$i" -lt 10 ] && i=$(($i+1)); do
4679+ no_proxy=$site wget -q -O /dev/null "$url" && return 0
4680+ sleep .5
4681+ done
4682+ return 1
4683+}
4684+
4685+render_templ() {
4686+ local tmpl="$1"
4687+ shift
4688+ local key val i="" cur="$tmpl"
4689+ for i in "$@"; do
4690+ key=${i%%=*}
4691+ val=${i#*=}
4692+ cur=${cur//\{${key}\}/${val}}
4693+ done
4694+ _RET="$cur"
4695+}
4696+
4697+get_partition() {
4698+ # return in _RET the 'auto' partition for a image.
4699+ # return partition number for a partitioned image
4700+ # return 0 for unpartitioned
4701+ # return 0 if image is partitioned, 1 if not
4702+ local img="$1"
4703+ out=$(LANG=C sfdisk --list -uS "$img" 2>&1) || {
4704+ error "failed determining if partitioned: $out";
4705+ return 1;
4706+ }
4707+ if echo "$out" | grep -q 'Device.*Start.*End'; then
4708+ _RET=1
4709+ else
4710+ _RET=0
4711+ fi
4712+}
4713+
4714+main() {
4715+ local short_opts="a:hn:O:p:l:v"
4716+ local long_opts="help,cmdline:,cmdline-add:,cmdline-ip:,disk:,host-addr:,overlay-disk:,netdev:,serial-log:,user-data:,user-data-add:,verbose,webserv-port:"
4717+ local getopt_out=""
4718+
4719+ getopt_out=$(getopt --name "${0##*/}" \
4720+ --options "${short_opts}" --long "${long_opts}" -- "$@") &&
4721+ eval set -- "${getopt_out}" ||
4722+ { bad_Usage; return; }
4723+
4724+ local cur="" next=""
4725+ local overlay_disk="" webserv_port="${DEF_WPORT}" netdevs="" host_addr=""
4726+ local serial_log="" cmdline_tmpl="${DEF_CMDLINE_TMPL}" user_data_file=""
4727+ local cmdline_add="" user_data_add="" pt=""
4728+ # The string 'BOOTIF' is replaced at runtime with the interface
4729+ # name by cloud-initramfs-dyn-netconf.
4730+ local cmdline_ip="ip=::::{iinitiator}:BOOTIF"
4731+ netdevs=( )
4732+ pt=( )
4733+
4734+ while [ $# -ne 0 ]; do
4735+ cur="$1"; next="$2";
4736+ case "$cur" in
4737+ -h|--help) Usage ; exit 0;;
4738+ --cmdline) cmdline_tmpl=$next; shift;;
4739+ --cmdline-add) cmdline_add=$next; shift;;
4740+ --cmdline-ip) cmdline_ip=$next; shift;;
4741+ --disk) pt[${#pt[@]}]="$1=$2"; shift;;
4742+ -a|--host-addr) host_addr=$next; shift;;
4743+ -O|--overlay-disk) overlay_disk=$next; shift;;
4744+ -n|--netdev) netdevs[${#netdevs[@]}]="$next"; shift;;
4745+ -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
4746+ -l|--serial-log) serial_log="$next"; shift;;
4747+ --user-data-file) user_data_file="$next"; shift;;
4748+ --user-data-add) user_data_add="$next"; shift;;
4749+ -p|--webserv-port) webserv_port=$port; shift;;
4750+ --) shift; break;;
4751+ esac
4752+ shift;
4753+ done
4754+
4755+ [ $# -eq 3 ] || { bad_Usage "expected 3 args, got $# ($*)"; return 1; }
4756+ local image_in=$1 kernel_in=$2 initrd_in=$3
4757+ for f in "$image_in" "$kernel_in" "$initrd_in"; do
4758+ [ -f "$f" ] || fail "$f: not a file"
4759+ done
4760+
4761+ local image="" kernel="" initrd=""
4762+ image=$(readlink -f "$image_in") ||
4763+ fail "cannot get full path to $image_in"
4764+ kernel=$(readlink -f "$kernel_in") ||
4765+ fail "cannot get full path to $kernel_in"
4766+ initrd=$(readlink -f "$initrd_in") ||
4767+ fail "cannot get full path to $initrd_in"
4768+
4769+ TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
4770+ fail "failed to make tempdir"
4771+ TEMP_D=$(cd "$TEMP_D" && pwd)
4772+ trap cleanup EXIT
4773+
4774+ local t_image t_kernel t_initrd
4775+ t_image="${TEMP_D}/image"
4776+ t_kernel="${TEMP_D}/kernel"
4777+ t_initrd="${TEMP_D}/initrd"
4778+
4779+ if [ "${#netdevs[@]}" -eq 0 ]; then
4780+ netdevs=( "$DEF_NETDEV" )
4781+ fi
4782+
4783+ local keys=""
4784+ mkdir -p "$TEMP_D/ci-seed"
4785+ if [ -n "${user_data_file}" ]; then
4786+ cat "${user_data_file}" > "$TEMP_D/ci-seed/user-data" ||
4787+ fail "failed to copy '$user_data_file' to ci-seed/user-data"
4788+ else
4789+ write_userdata "$TEMP_D/ci-seed/user-data" ||
4790+ fail "failed to write user-data"
4791+ fi
4792+ if [ -n "$user_data_add" ]; then
4793+ cat "$user_data_add" >> "$TEMP_D/ci-seed/user-data" ||
4794+ fail "failed to write additional user-data"
4795+ fi
4796+
4797+ get_ssh_pubkeys || fail "failed getting pubkeys"
4798+ keys="$_RET"
4799+ write_metadata "$TEMP_D/ci-seed/meta-data" "$keys" ||
4800+ fail "failed writing metadata"
4801+
4802+ if [ -z "$host_addr" ]; then
4803+ find_host_addr "${netdevs[@]}" ||
4804+ fail "failed to find host address. try --host-addr."
4805+ host_addr="$_RET"
4806+ fi
4807+ debug 1 "using host address: '${host_addr}'"
4808+
4809+ ## run a python web server to seed this
4810+ serv_http "$TEMP_D/ci-seed" "$webserv_port" "user-data" ||
4811+ fail "failed to web serv $TEMP_D/ci-seed on $webserv_port"
4812+ debug 1 "web server in pid $HTTP_PID serving ${TEMP_D}/ci-seed/ on port $webserv_port"
4813+ local seed_url="http://$host_addr:$webserv_port/"
4814+ if [ "${host_addr#*:}" != "$host_addr" ]; then
4815+ seed_url="http://[$host_addr]:$webserv_port/"
4816+ fi
4817+ debug 1 " ${seed_url}meta-data"
4818+
4819+ if [ "${image%.gz}" != "$image" ]; then
4820+ error "uncompressing $image_in -> temp-dir"
4821+ gzcat "$image" > "${TEMP_D}/image" ||
4822+ fail "failed uncompress of $image_in"
4823+ else
4824+ ln -s "$image" "$t_image" || fail "symlink to $image failed"
4825+ fi
4826+
4827+ ln -s "$kernel" "$t_kernel" &&
4828+ ln -s "$initrd" "$t_initrd" ||
4829+ fail "failed link to kernel or initrd"
4830+
4831+ local partition=""
4832+ get_partition "$t_image" ||
4833+ fail "failed to read partition from $image"
4834+ partition=${_RET}
4835+ [ "$part" = "0" ] && partition=""
4836+
4837+ TGT_NAME=${TEMP_D##*/}
4838+ TGT_NAME=${TGT_NAME//./-}
4839+ TGT_CONF="/etc/tgt/conf.d/$TGT_NAME.conf"
4840+ register_image "$TGT_CONF" "$TGT_NAME" "$t_image" ||
4841+ fail "failed to register image $t_image in tgt"
4842+
4843+ overlay_drive_kernel="overlayroot=tmpfs"
4844+ overlay_drive_xkvm=""
4845+ if [ -n "${overlay_disk}" ]; then
4846+ if [ "${overlay_disk}" = "temp" ]; then
4847+ overlay_disk="${TEMP_D}/overlay.img"
4848+ fi
4849+ if [ ! -f "$overlay_disk" ]; then
4850+ qemu-img create -f raw "$overlay_disk" 1G
4851+ mkfs.ext2 -L "delta" -F "$overlay_disk" >/dev/null 2>&1 ||
4852+ fail "failed mkfs on $overlay_disk"
4853+ overlay_drive_kernel="overlayroot=device:dev=LABEL=delta"
4854+ overlay_drive_xkvm="--disk=${overlay_disk},format=raw"
4855+ fi
4856+ fi
4857+
4858+ local iserver="${host_addr}" iname="$TGT_NAME" iport="$ISCSI_PORT"
4859+ local ilun="1" iuser="" ipass="" iproto="" iinitiator="maas-enlist"
4860+ local rfc="" root="" iscsi_cmdline_parms="" iscsi_start_cmd=""
4861+ local cmdline=""
4862+ get_rfc4173 "${iserver}" "$iname" "$iport" "$ilun" \
4863+ "$iuser" "$ipass" "$iproto"
4864+ rfc="$_RET"
4865+
4866+ get_cmdline_params "${iserver}" "$iname" "$iport" "$ilun" \
4867+ "$iuser" "$ipass" "$iproto" "$iinitiator"
4868+ iscsi_cmdline_parms="$_RET"
4869+
4870+ get_root_parm "$iserver" "$iname" "$iport" "$ilun" \
4871+ "$iuser" "$ipass" "$iproto" "$partition"
4872+ root="$_RET"
4873+
4874+ get_iscsi_cmd "$iserver" "$iname" "$iport" "$ilun" \
4875+ "$iuser" "$ipass" "$iproto" "$iinitiator"
4876+ iscsi_start_cmd=( "${_RET[@]}" )
4877+
4878+ render_templ "${cmdline_ip}" iinitiator="$iinitiator" ||
4879+ { error "failed rendering cmdline ip: ${cmdline_ip}"; return 1; }
4880+ cmdline_ip="$_RET"
4881+
4882+ render_templ "$cmdline_tmpl${cmdline_add:+ ${cmdline_add}}" \
4883+ iserver="$host_addr" iname="$TGT_NAME" iport="$ISCSI_PORT" \
4884+ ilun="$ilun" iuser="$iuser" ipass="$ipass" iproto="$iproto" \
4885+ iinitiator="$iinitiator" "rfc4173=$rfc" "root=$root" \
4886+ "seed_url=$seed_url" icmdline_parms="$iscsi_cmdline_parms" \
4887+ "overlay_drive=${overlay_drive_kernel}" \
4888+ "cmdline_ds=ds=nocloud-net;seedfrom=${seed_url}" \
4889+ "cmdline_ip=${cmdline_ip}" ||
4890+ { error "failed rendering cmdline"; return 1; }
4891+ cmdline="$_RET"
4892+
4893+ debug 1 "rfc4173: $rfc"
4894+ debug 1 "iscsi_cmdline_parms: $iscsi_cmdline_parms"
4895+ debug 1 "root: $root"
4896+ debug 1 "iscsi_start_cmd: ${iscsi_start_cmd[*]}"
4897+ debug 1 "cmdline=$cmdline"
4898+
4899+ local netdev_args=""
4900+ netdev_args=( )
4901+ for i in "${netdevs[@]}"; do
4902+ netdev_args[${#netdev_args[@]}]="--netdev=$i"
4903+ done
4904+
4905+ local mem="512" start="$SECONDS" ret=""
4906+ local cmd=""
4907+ cmd=(
4908+ ${BOOT_TIMEOUT:+timeout --kill-after=1m --signal=TERM $BOOT_TIMEOUT}
4909+ xkvm -v -v "${netdev_args[@]}" ${overlay_drive_xkvm} "${pt[@]}" --
4910+ -echr 0x5
4911+ -m $mem ${serial_log:+-serial "file:$serial_log"} -nographic
4912+ -kernel "${t_kernel}" -initrd "${t_initrd}"
4913+ -append "${cmdline}"
4914+ )
4915+ debug 1 "executing: ${cmd[*]}"
4916+ "${cmd[@]}"
4917+ ret=$?
4918+ debug 1 "xkvm returned $ret in $((SECONDS-start))s"
4919+ return $ret
4920+}
4921+
4922+main "$@"
4923+# vi: ts=4 expandtab
4924diff --git a/debian/tests/xkvm b/debian/tests/xkvm
4925new file mode 100755
4926index 0000000..9513723
4927--- /dev/null
4928+++ b/debian/tests/xkvm
4929@@ -0,0 +1,704 @@
4930+#!/bin/bash
4931+
4932+set -f
4933+
4934+VERBOSITY=0
4935+KVM_PID=""
4936+DRY_RUN=false
4937+TEMP_D=""
4938+DEF_BRIDGE="virbr0"
4939+TAPDEVS=( )
4940+# OVS_CLEANUP gets populated with bridge:devname pairs used with ovs
4941+OVS_CLEANUP=( )
4942+MAC_PREFIX="52:54:00:12:34"
4943+KVM="kvm"
4944+declare -A KVM_DEVOPTS
4945+
4946+error() { echo "$@" 1>&2; }
4947+fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
4948+
4949+bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
4950+randmac() {
4951+ # return random mac addr within final 3 tokens
4952+ local random=""
4953+ random=$(printf "%02x:%02x:%02x" \
4954+ "$((${RANDOM}%256))" "$((${RANDOM}%256))" "$((${RANDOM}%256))")
4955+ padmac "$random"
4956+}
4957+
4958+cleanup() {
4959+ [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
4960+ if [ -n "${KVM_PID}" ]; then
4961+ debug 1 "${0##*/} cleanup killing kvm pid '$KVM_PID'"
4962+ kill "$KVM_PID"
4963+ fi
4964+ if [ ${#TAPDEVS[@]} -ne 0 ]; then
4965+ local name item
4966+ for item in "${TAPDEVS[@]}"; do
4967+ [ "${item}" = "skip" ] && continue
4968+ debug 1 "removing" "$item"
4969+ name="${item%:*}"
4970+ if $DRY_RUN; then
4971+ error ip tuntap del mode tap "$name"
4972+ else
4973+ ip tuntap del mode tap "$name"
4974+ fi
4975+ [ $? -eq 0 ] || error "failed removal of $name"
4976+ done
4977+ if [ ${#OVS_CLEANUP[@]} -ne 0 ]; then
4978+ # with linux bridges, there seems to be no harm in just deleting
4979+ # the device (not detaching from the bridge). However, with
4980+ # ovs, you have to remove them from the bridge, or later it
4981+ # will refuse to add the same name.
4982+ error "cleaning up ovs ports: ${OVS_CLEANUP[@]}"
4983+ if ${DRY_RUN}; then
4984+ error sudo "$0" tap-control ovs-cleanup "${OVS_CLEANUP[@]}"
4985+ else
4986+ sudo "$0" tap-control ovs-cleanup "${OVS_CLEANUP[@]}"
4987+ fi
4988+ fi
4989+ fi
4990+}
4991+
4992+debug() {
4993+ local level=${1}; shift;
4994+ [ "${level}" -gt "${VERBOSITY}" ] && return
4995+ error "${@}"
4996+}
4997+
4998+Usage() {
4999+ cat <<EOF
5000+Usage: ${0##*/} [ options ] -- kvm-args [ ... ]
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches