Merge ~paelzer/ubuntu/+source/open-iscsi:merge-2.1.2-1-HIRSUTE into ubuntu/+source/open-iscsi:debian/sid

Proposed by Christian Ehrhardt 
Status: Merged
Approved by: Christian Ehrhardt 
Approved revision: 9901a74c936ce0e9b0f918463d0f80798f201f32
Merge reported by: Christian Ehrhardt 
Merged at revision: 9901a74c936ce0e9b0f918463d0f80798f201f32
Proposed branch: ~paelzer/ubuntu/+source/open-iscsi:merge-2.1.2-1-HIRSUTE
Merge into: ubuntu/+source/open-iscsi:debian/sid
Diff against target: 5399 lines (+4913/-71)
25 files modified
debian/changelog (+1066/-0)
debian/control (+9/-7)
debian/extra/initramfs.hook (+1/-1)
debian/extra/initramfs.local-bottom (+20/-0)
debian/extra/initramfs.local-top (+30/-2)
debian/extra/net-interface-handler (+80/-0)
debian/iscsi-network-interface.rules (+3/-0)
debian/iscsid.service (+1/-1)
debian/open-iscsi.finalrd (+40/-0)
debian/open-iscsi.postinst (+25/-40)
debian/open-iscsi.service (+6/-6)
debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch (+28/-0)
debian/patches/series (+1/-0)
debian/rules (+30/-10)
debian/tests/README-boot-test.md (+139/-0)
debian/tests/control (+4/-0)
debian/tests/get-image (+227/-0)
debian/tests/install (+5/-2)
debian/tests/patch-image (+374/-0)
debian/tests/test-open-iscsi.py (+426/-0)
debian/tests/testlib.py (+1153/-0)
debian/tests/testsuite (+7/-0)
debian/tests/tgt-boot-test (+534/-0)
debian/tests/xkvm (+704/-0)
dev/null (+0/-2)
Reviewer Review Type Date Requested Status
Robie Basak Needs Fixing
Canonical Server Pending
git-ubuntu developers Pending
Review via email: mp+394815@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

One more MP under the "carry as-is until one can spend more time" banner.
To be clear, we have a lot of Delta and discussions were going on. But
to further push or drop some this would need more time than a drive-by merge.

PPA: https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/4364/+packages
Old-MP (for old Delta discussion as reference): https://code.launchpad.net/~rafaeldtinoco/ubuntu/+source/open-iscsi/+git/open-iscsi/+merge/389567

Note on git histoy:
- The old imports/merges/history were a bit odd
- upload/2.1.1-1ubuntu2 does not fully match pkg/ubuntu/hirsute-devel by
  changes in .gitignore
- Never the less the parenting/history of pkg/ubuntu/hirsute-devel is totally
  broken and instead I'll start off of the better upload/2.1.1-1ubuntu2 which
  I used to create "split".
- You can use the tags, starting with *logical* things make sense again
 * [new tag] lp9999999/logical/2.1.1-1ubuntu2 -> lp9999999/logical/2.1.1-1ubuntu2
 * [new tag] lp9999999/new/debian -> lp9999999/new/debian
 * [new tag] lp9999999/old/debian -> lp9999999/old/debian
 * [new tag] lp9999999/old/ubuntu -> lp9999999/old/ubuntu
 * [new tag] lp9999999/reconstruct/2.1.1-1ubuntu2 -> lp9999999/reconstruct/2.1.1-1ubuntu2
 * [new tag] lp9999999/split/2.1.1-1ubuntu2 -> lp9999999/split/2.1.1-1ubuntu2

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

FYI: I tried to drop the FTFBS fix for gcc10 as you'd think Debian builds that as well.
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=957630
But on ppc64/s390x we still hit build errors due to that and need to retain hat delta.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Tests done all good except i386 which is ok to fail.
=> https://bileto.ubuntu.com/excuses/4364/hirsute.html

Revision history for this message
Robie Basak (racb) wrote :

Not being familiar with this extensive Ubuntu delta, I particularly appreciate the use of our workflow to break the delta down with clear explanations in git commits and changelog entries. Thank you!

This looks good to me except for two possible issues I spotted.

1) I don't think 6c13643 "Don't FTBFS due to warnings new in gcc10" is needed any more with this new upstream release. My local test build without it succeeded.

2) I think 5dd176f "refresh to match 2.1.2" is broken. Before, it resulted in the line:

    iscsid.startup = /bin/systemctl start iscsid.socket

whereas now it results in:

    iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.socket

No need for a re-review after you've looked at these.

Finally, not a problem with the final result, but I thought I'd mention that I think you've drifted from the original intention of what the logical tag means, which made it harder for me to review this MP. I ended up making my own logical tag to review against instead. I would have expected 71f3193 to be squashed into 1d16906 and 41112bd squashed into 90684c2 before you tagged it logical. Otherwise the range-diff doesn't match when reviewing.

review: Needs Fixing
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

1) I don't think 6c13643 "Don't FTBFS due to warnings new in gcc10" is needed any more with this new upstream release. My local test build without it succeeded.

=> I thought the same, had it test built and it fails on ppc64&s390x still without this

2) 5dd176f

I'll look into that, the surrounding context had some noise distracting me.
Indeed I have alinged to what the comment said, but to match the old delta the line has dropped iscsiuio.socket indeed
Awesome spotting on the review.
Fixed

And about logical - this was not intentionally different. The problem is that some squashing only becomes obvious once you are 3/4 through the merge. I did not go back to refresh logical with those, but yeah I might do so next time.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

To ssh://git.launchpad.net/~usd-import-team/ubuntu/+source/open-iscsi
 * [new tag] upload/2.1.2-1ubuntu1 -> upload/2.1.2-1ubuntu1

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading open-iscsi_2.1.2-1ubuntu1.dsc: done.
  Uploading open-iscsi_2.1.2.orig.tar.gz: done.
  Uploading open-iscsi_2.1.2-1ubuntu1.debian.tar.xz: done.
  Uploading open-iscsi_2.1.2-1ubuntu1_source.buildinfo: done.
  Uploading open-iscsi_2.1.2-1ubuntu1_source.changes: done.
Successfully uploaded packages.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Migrated

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index d4c171c..5fc1202 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,72 @@
1open-iscsi (2.1.2-1ubuntu1) hirsute; urgency=medium
2
3 * Merge with Debian unstable. Remaining changes:
4 - debian/tests: Add Ubuntu autopkgtest suite:
5 - README-boot-test.md
6 - tgt-boot-test: tests
7 - test-open-iscsi.py
8 - testlib.py
9 - get-image
10 - patch-image
11 - testsuite
12 - xkvm
13 - d/iscsid.service: Let iscsid systemd job run in privileged containers
14 but not in unprivileged ones
15 - d/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
16 run ipconfig to gather all DHCP config info, including DNS search
17 domain, which iBFT can't provide.
18 - Remove initramfs interfaces stamp in case no iscsi devs mounted.
19 If iscsi root was requested, but no iscsi devices were mounted, remove
20 the initramfs interfaces stamp file. Meaning, that on shutdown there is
21 no 30s delay, whilst trying to re-establish iscsi login to perform a
22 logout.
23 - add IPv6 support
24 - Source /run/net6-*.conf when needed.
25 - d/extra/initramfs.local-top: handle IPv6 configs being shipped in
26 DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
27 .interface
28 - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi logout
29 hook and recommend finalrd and busybox for the logout hook to work.
30 - Make iscsid socket-activated to only activate it as needed:
31 - debian/open-iscsi.service: do not start or check iscsid.service
32 - debian/rules: install and enable iscsid.socket
33 - debian/open-iscsi.postinst:
34 - run restart logic only if service is running on upgrade
35 - drop no longer reachable upgrade path that affects iscsid
36 - disable iscsid.service on upgrade
37 - handle iscsid.socket to be started if the service is not running yet
38 - d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
39 run when udev disks are attached.
40 - d/iscsid.service: Remove ExecStop= directive.
41 - debian/tests/install: fix tests to work with socket activation
42 - debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
43 [updated to match 2.1.2]
44 - debian/open-iscsi.service: Start open-iscsi systemd job when either
45 /etc/iscsi/nodes or /sys/class/iscsi_session have content.
46 - Prevent network interface that contains iscsi root from bouncing
47 during boot or going down during shutdown if the system is using
48 resolvconf or ifupdown:
49 - d/iscsi-network-interface.rules
50 - d/extra/net-interface-handler
51 - d/extra/initramfs.hook: add ib_iser to the list of modules included in
52 the initramfs, so that we can in principle support iscsi root on
53 infiniband.
54 - d/open-iscsi.kmod drop: (LP #1833586)
55 no static module list is needed if we let iscsid load modules itself.
56 - Stop producing udebs on i386 where we no longer have d-i or a kernel.
57 - d/extra/initramfs.local-{top,bottom}: move removal of
58 open-iscsi.interface file from local-top to local-bottom, and fix shell
59 quoting issue that would result in /run/initramfs/ open-iscsi.interface
60 always being removed (LP #1872813)
61 - debian/control, debian/rules: Fix libopeniscsiusr binary package
62 name (LP 1892228).
63 - d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds
64 and initialization, because upstream's gcc10 support is incomplete.
65 This change can be dropped when upstream has completed their gcc
66 support.
67
68 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 03 Dec 2020 14:44:39 +0100
69
1open-iscsi (2.1.2-1) unstable; urgency=medium70open-iscsi (2.1.2-1) unstable; urgency=medium
271
3 * [7f10701] New upstream version 2.1.272 * [7f10701] New upstream version 2.1.2
@@ -19,6 +88,86 @@ open-iscsi (2.1.1-2) unstable; urgency=medium
1988
20 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 14 Aug 2020 12:32:16 +053089 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 14 Aug 2020 12:32:16 +0530
2190
91open-iscsi (2.1.1-1ubuntu2) groovy; urgency=medium
92
93 * debian/control, debian/rules: Fix libopeniscsiusr binary package
94 name (LP: #1892228).
95 * debian/rules: Fix deprecated warning for dh_installinit that
96 --no-restart-on-upgrade has been replaced by --no-stop-on-upgrade,
97 which is equivalent in functionality (ref deb #837528).
98
99 -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Wed, 19 Aug 2020 19:08:47 +0000
100
101open-iscsi (2.1.1-1ubuntu1) groovy; urgency=medium
102
103 * New upstream version 2.1.1
104 * d/rules: Don't FTBFS due to warnings new in gcc10 regarding bounds
105 and initialization, because upstream's gcc10 support is incomplete.
106 This change can be dropped when upstream has completed their gcc
107 support.
108 * Merge with Debian unstable (LP: #1891374). Remaining changes:
109 - debian/tests: Add Ubuntu autopkgtest suite:
110 - README-boot-test.md
111 - tgt-boot-test: tests
112 - test-open-iscsi.py
113 - testlib.py
114 - get-image
115 - patch-image
116 - testsuite
117 - xkvm
118 - d/iscsid.service: Let iscsid systemd job run in privileged containers
119 but not in unprivileged ones
120 - d/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
121 run ipconfig to gather all DHCP config info, including DNS search
122 domain, which iBFT can't provide.
123 - Remove initramfs interfaces stamp in case no iscsi devs mounted.
124 If iscsi root was requested, but no iscsi devices were mounted, remove
125 the initramfs interfaces stamp file. Meaning, that on shutdown there is
126 no 30s delay, whilst trying to re-establish iscsi login to perform a
127 logout.
128 - add IPv6 support
129 - Source /run/net6-*.conf when needed.
130 - d/extra/initramfs.local-top: handle IPv6 configs being shipped in
131 DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
132 .interface
133 - d/rules, d/open-iscsi.finalrd, d/control: ship the finalrd iscsi logout
134 hook and recommend finalrd and busybox for the logout hook to work.
135 - Make iscsid socket-activated to only activate it as needed:
136 - debian/open-iscsi.service: do not start or check iscsid.service
137 - debian/rules: install and enable iscsid.socket
138 - debian/open-iscsi.postinst:
139 - run restart logic only if service is running on upgrade
140 - drop no longer reachable upgrade path that affects iscsid
141 - disable iscsid.service on upgrade
142 - handle iscsid.socket to be started if the service is not running yet
143 - d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
144 run when udev disks are attached.
145 - d/iscsid.service: Remove ExecStop= directive.
146 - debian/tests/install: fix tests to work with socket activation
147 - debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
148 - debian/open-iscsi.service: Start open-iscsi systemd job when either
149 /etc/iscsi/nodes or /sys/class/iscsi_session have content.
150 - Prevent network interface that contains iscsi root from bouncing
151 during boot or going down during shutdown if the system is using
152 resolvconf or ifupdown:
153 - d/iscsi-network-interface.rules
154 - d/extra/net-interface-handler
155 - d/extra/initramfs.hook: add ib_iser to the list of modules included in
156 the initramfs, so that we can in principle support iscsi root on
157 infiniband.
158 - d/open-iscsi.kmod drop: (LP #1833586)
159 no static module list is needed if we let iscsid load modules itself.
160 - Stop producing udebs on i386 where we no longer have d-i or a kernel.
161 - Use python2 instead of python in the autopkg tests: Next step for
162 open-iscsi is to revist all iscsi-root feature and autopkgtests, so
163 keep python2 to avoid re-work later.
164 - d/extra/initramfs.local-{top,bottom}: move removal of
165 open-iscsi.interface file from local-top to local-bottom, and fix shell
166 quoting issue that would result in /run/initramfs/ open-iscsi.interface
167 always being removed (LP #1872813)
168
169 -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Thu, 13 Aug 2020 04:29:43 +0000
170
22open-iscsi (2.1.1-1) experimental; urgency=medium171open-iscsi (2.1.1-1) experimental; urgency=medium
23172
24 [ Rafael David Tinoco ]173 [ Rafael David Tinoco ]
@@ -63,6 +212,98 @@ open-iscsi (2.1.1-1) experimental; urgency=medium
63212
64 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 23 Jun 2020 20:38:47 +0530213 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 23 Jun 2020 20:38:47 +0530
65214
215open-iscsi (2.0.874-7.1ubuntu6.1) focal; urgency=medium
216
217 [ Ben Swartzlander ]
218 * allow open-iscsi to disable auto-scan feature (LP: #1877617)
219 - d/p/lp1877617-Allow-disabling-auto-LUN-scans.patch
220 - d/p/lp1877617-Fix-manual-LUN-scans-feature.patch
221
222 -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com> Mon, 11 May 2020 02:03:33 +0000
223
224open-iscsi (2.0.874-7.1ubuntu6) focal; urgency=medium
225
226 * d/extra/initramfs.local-{top,bottom}: move removal of open-iscsi.interface
227 file from local-top to local-bottom, and fix shell quoting issue that
228 would result in /run/initramfs/open-iscsi.interface always being removed
229 (LP: #1872813)
230
231 -- Daniel Watkins <oddbloke@ubuntu.com> Tue, 14 Apr 2020 16:54:37 -0400
232
233open-iscsi (2.0.874-7.1ubuntu5) focal; urgency=medium
234
235 * Use python2 instead of python in the autopkg tests.
236
237 -- Matthias Klose <doko@ubuntu.com> Thu, 30 Jan 2020 10:14:16 +0100
238
239open-iscsi (2.0.874-7.1ubuntu3) eoan; urgency=medium
240
241 * Stop producing udebs on i386 where we no longer have d-i or a kernel.
242
243 -- Adam Conrad <adconrad@ubuntu.com> Wed, 09 Oct 2019 14:10:37 -0600
244
245open-iscsi (2.0.874-7.1ubuntu2) eoan; urgency=medium
246
247 * debian/open-iscsi.kmod: drop; no static module list is needed if we let
248 iscsid load modules itself. LP: #1833586.
249 * debian/extra/initramfs.hook: add ib_iser to the list of modules
250 included in the initramfs, so that we can in principle support iscsi
251 root on infiniband.
252
253 -- Steve Langasek <steve.langasek@ubuntu.com> Thu, 20 Jun 2019 13:48:46 -0700
254
255open-iscsi (2.0.874-7.1ubuntu1) eoan; urgency=low
256
257 * Merge from Debian unstable. Remaining changes:
258 - debian/tests: Add Ubuntu autopkgtest.
259 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
260 debian/open-iscsi.install:
261 Prevent network interface that contains iscsi root from bouncing
262 during boot or going down during shutdown if the system is using
263 resolvconf or ifupdown.
264 - Let iscsid systemd job run in privileged containers but not in
265 unprivileged ones
266 - Start open-iscsi systemd job when either /etc/iscsi/nodes or
267 /sys/class/iscsi_session have content
268 - add IPv6 support
269 + Source /run/net6-*.conf when needed.
270 + debian/extra/initramfs.local-top: handle IPv6 configs being
271 shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
272 can fill in /run/initramfs/open-iscsi.interface
273 - make iscsid socket-activated to only activate it as needed
274 + debian/iscsid.socket: systemd socket file for iscsid
275 + debian/open-iscsi.service: do not start or check iscsid.service
276 + debian/rules: install and enable iscsid.socket
277 + debian/patches/iscid-conf-use-systemd.socket-patch: default to the
278 socket
279 + debian/open-iscsi.postinst:
280 * run restart logic only if service is running on upgrade
281 * drop no longer reachable upgrade path that affects iscsid
282 * disable iscsid.service on upgrade
283 * handle iscsid.socket to be started if the service is not running
284 yet
285 + d/iscsi-disk.rules: Add a udev rule so that iscsid.service will be
286 run when udev disks are attached.
287 + d/iscsid.service: Remove ExecStop= directive.
288 + debian/tests/install: fix tests to work with socket activation
289 - Ship finalrd logout hook.
290 - debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
291 run ipconfig to gather all DHCP config info, including DNS search
292 domain, which iBFT can't provide.
293 - If iscsi root was requested, but no iscsi devices were mounted, remove
294 the initramfs interfaces stamp file. Meaning, that on shutdown there
295 is no 30s delay, whilst trying to re-establish iscsi login to perform
296 a logout.
297 * Dropped changes, included in Debian:
298 - Fix fail to build from source due to undefined reference to
299 minor
300 * Drop breaks on never-released version of finalrd.
301 * debian/net-interface-handler: drop upstart support, unused since bionic.
302 * Drop cleanup of upstart jobs, no longer needed post bionic.
303 * debian/tests/daemon: drop, unused.
304
305 -- Steve Langasek <steve.langasek@ubuntu.com> Mon, 29 Apr 2019 16:13:37 -0700
306
66open-iscsi (2.0.874-7) unstable; urgency=medium307open-iscsi (2.0.874-7) unstable; urgency=medium
67308
68 * [eeda27c] Enable back pristine-tar as we have now committed it309 * [eeda27c] Enable back pristine-tar as we have now committed it
@@ -78,6 +319,158 @@ open-iscsi (2.0.874-6) unstable; urgency=medium
78319
79 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 05 Oct 2018 11:31:19 +0530320 -- Ritesh Raj Sarraf <rrs@debian.org> Fri, 05 Oct 2018 11:31:19 +0530
80321
322open-iscsi (2.0.874-5ubuntu15) disco; urgency=medium
323
324 * d/iscsid.service: Remove ExecStop= directive. Letting systemd
325 handle termination prevents restart failures. (LP: #1821255)
326
327 -- Heitor R. Alves de Siqueira <halves@canonical.com> Thu, 28 Mar 2019 10:21:24 -0300
328
329open-iscsi (2.0.874-5ubuntu14) disco; urgency=medium
330
331 * debian/iscsi-disk.rules: Fix bug with LVM on top of iscsi devices.
332 (LP: #1807978)
333
334 -- Scott Moser <smoser@ubuntu.com> Tue, 11 Dec 2018 19:01:14 -0500
335
336open-iscsi (2.0.874-5ubuntu13) disco; urgency=medium
337
338 [ Robert C Jennings & Dimitri John Ledkov ]
339 * If iscsi root was requested, but no iscsi devices were mounted, remove
340 the initramfs interfaces stamp file. Meaning, that on shutdown there
341 is no 30s delay, whilst trying to re-establish iscsi login to perform
342 a logout. LP: #1800681
343
344 -- Dimitri John Ledkov <xnox@ubuntu.com> Sun, 09 Dec 2018 22:29:20 +0000
345
346open-iscsi (2.0.874-5ubuntu12) disco; urgency=medium
347
348 [Scott Moser]
349 * debian/extra/initramfs.local-top: handle iSCSI iBFT DHCP to correctly
350 run ipconfig to gather all DHCP config info, including DNS search
351 domain, which iBFT can't provide. (LP: #1806777)
352
353 -- Dan Streetman <ddstreet@canonical.com> Wed, 05 Dec 2018 11:28:12 -0500
354
355open-iscsi (2.0.874-5ubuntu11) disco; urgency=medium
356
357 * debian/tests/test-open-iscsi.py: Fix called process error.
358 If no image was available for a release, a NameError exception would be
359 raised.
360
361 -- Scott Moser <smoser@ubuntu.com> Wed, 14 Nov 2018 16:50:29 -0500
362
363open-iscsi (2.0.874-5ubuntu10) disco; urgency=medium
364
365 * d/iscsi-disk.rules, d/tests: Add a udev rule so that iscsid.service
366 will be run when udev disks are attached. (LP: #1802354)
367 * debian/tests: improve tgt boot test
368 - disable snapd and snap.seeded services to avoid unnecessary
369 resource consumption during tests.
370 - save artifacts from the test run.
371
372 -- Scott Moser <smoser@ubuntu.com> Wed, 14 Nov 2018 16:05:46 -0500
373
374open-iscsi (2.0.874-5ubuntu9) cosmic; urgency=medium
375
376 * d/net-interface-handler: replace 'domainsearch' with the correct
377 configuration option 'search' in net-interface-handler (LP: #1791108)
378
379 -- Victor Tapia <victor.tapia@canonical.com> Mon, 17 Sep 2018 15:58:34 +0200
380
381open-iscsi (2.0.874-5ubuntu8) cosmic; urgency=medium
382
383 * d/tests: insert some debug units in an attempt to diagnose any
384 occurences of bug 1788188.
385 * Fix fail to build from source due to undefined reference to
386 minor (LP: #1791154)
387
388 -- Scott Moser <smoser@ubuntu.com> Tue, 21 Aug 2018 13:33:06 -0400
389
390open-iscsi (2.0.874-5ubuntu7) cosmic; urgency=medium
391
392 * d/tests: make interactive use of tgt-boot-test more usable by
393 only using 'timeout' from the test harness.
394 * debian/tests/README-boot-test.md: minor doc fixes and whitespace.
395 * d/net-interface-handler: Apply changes only for the iscsi-root interface.
396 (LP: #1785108)
397
398 -- Scott Moser <smoser@ubuntu.com> Tue, 07 Aug 2018 16:37:13 -0400
399
400open-iscsi (2.0.874-5ubuntu6) cosmic; urgency=medium
401
402 * Ship finalrd logout hook.
403
404 -- Dimitri John Ledkov <xnox@ubuntu.com> Fri, 03 Aug 2018 15:03:51 +0100
405
406open-iscsi (2.0.874-5ubuntu5) cosmic; urgency=medium
407
408 * Harden dep8 tests against effects due to slow execution on Launchpad
409 infrastructure (LP: #1732028).
410 - debian/tests/patch-image: remove problematic fstab entries
411 - debian/tests/tgt-boot-test: ran xkvm in verbose mode
412
413 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 19 Jul 2018 18:22:39 +0200
414
415open-iscsi (2.0.874-5ubuntu4) cosmic; urgency=medium
416
417 * debian/tests/install: ignore the potential stderr of the probing command
418 that is meant to activate iscsid indirectly via the socket.
419
420 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Wed, 30 May 2018 15:42:12 +0200
421
422open-iscsi (2.0.874-5ubuntu3) cosmic; urgency=medium
423
424 * make iscsid socket activated to only activate it as-needed (LP: #1755858)
425 - debian/iscsid.socket: systemd socket file for iscsid
426 - debian/open-iscsi.service: do not start or check iscsid.service
427 - debian/rules: install and enable iscsid.socket
428 - debian/patches/iscid-conf-use-systemd.socket-patch: default to the socket
429 - debian/open-iscsi.postinst:
430 + run restart logic only if service is running on upgrade
431 + drop no more reachable upgrade path that affects iscsid
432 + disable iscsid.service on upgrade
433 + handle iscsid.socket to be started if the service is not running yet
434 - debian/tests/install: fix tests to work with socket activation
435
436 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Wed, 23 May 2018 15:50:01 +0200
437
438open-iscsi (2.0.874-5ubuntu2) bionic; urgency=medium
439
440 * debian/tests:
441 - tgt-boot-test: Use 'timeout' to force a 60m timeout of the boot test.
442 - README-boot-test.md: document environment variables BOOT_TIMEOUT
443 and _USE_KVM.
444
445 -- Scott Moser <smoser@ubuntu.com> Wed, 21 Feb 2018 13:19:17 -0500
446
447open-iscsi (2.0.874-5ubuntu1) bionic; urgency=low
448
449 * Merge with Debian unstable. Remaining changes:
450 - debian/tests: Add Ubuntu autopkgtests.
451 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
452 debian/open-iscsi.install:
453 Prevent network interface that contains iscsi root from bouncing
454 during boot or going down during shutdown.
455 Integrates with resolvconf and initramfs code that writes
456 /run/initramfs/open-iscsi.interface
457 - debian/open-iscsi.maintscript: clean up the obsolete
458 iscsi-network-interface upstart job, file on upgrade.
459 - Let iscsid systemd job run in privileged containers but not in
460 unprivileged ones
461 - Start open-iscsi systemd job when either /etc/iscsi/nodes or
462 /sys/class/iscsi_session have content
463 Based on patch by Nish Aravamudan, thanks! (LP #1576341)
464 - add IPv6 support
465 + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
466 LP #1621507
467 + Source /run/net6-*.conf when needed.
468 + debian/extra/initramfs.local-top: handle IPv6 configs being
469 shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
470 can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
471
472 -- Dimitri John Ledkov <xnox@ubuntu.com> Fri, 12 Jan 2018 14:00:59 +0000
473
81open-iscsi (2.0.874-5) unstable; urgency=high474open-iscsi (2.0.874-5) unstable; urgency=high
82475
83 * [aeb86f7] Fix multiple security issues in iscsiuio. (CVE-2017-17840)476 * [aeb86f7] Fix multiple security issues in iscsiuio. (CVE-2017-17840)
@@ -85,6 +478,74 @@ open-iscsi (2.0.874-5) unstable; urgency=high
85478
86 -- Christian Seiler <christian@iwakd.de> Sat, 23 Dec 2017 11:30:44 +0100479 -- Christian Seiler <christian@iwakd.de> Sat, 23 Dec 2017 11:30:44 +0100
87480
481open-iscsi (2.0.874-4ubuntu5) bionic; urgency=medium
482
483 * debian/tests/patch-image: mount auxilary filesystems before upgrading
484 packages. Fixes ADT tests, when triggered by packages, that need
485 /proc, /dev, etc mounted to complete the upgrade.
486
487 -- Dimitri John Ledkov <xnox@ubuntu.com> Wed, 03 Jan 2018 12:21:05 +0000
488
489open-iscsi (2.0.874-4ubuntu4) bionic; urgency=medium
490
491 * debian/tests/test-open-iscsi.py: skip test if cloud image is unavailable.
492 This solves flaky tests in restricted network environments as well as in
493 the short period after opening a new release (LP: #1731907).
494
495 -- Christian Ehrhardt <christian.ehrhardt@canonical.com> Thu, 16 Nov 2017 12:06:34 +0100
496
497open-iscsi (2.0.874-4ubuntu3) artful; urgency=medium
498
499 * debian/tests/xkvm: do not use kvm (-enable-kvm) by default if
500 operating inside a vm. nested kvm is finicky.
501
502 -- Scott Moser <smoser@ubuntu.com> Wed, 11 Oct 2017 18:14:08 -0400
503
504open-iscsi (2.0.874-4ubuntu2) artful; urgency=medium
505
506 * debian/tests/test-open-iscsi.py: query systemd-resolved if present.
507 Ubuntu images now have systemd-resolved managing /etc/resolv.conf
508 so support test if that is the case (LP: #1715468).
509
510 -- Scott Moser <smoser@ubuntu.com> Wed, 06 Sep 2017 16:20:16 -0400
511
512open-iscsi (2.0.874-4ubuntu1) artful; urgency=medium
513
514 * Merge with Debian unstable. Remaining changes:
515 - debian/tests: Add Ubuntu autopkgtests.
516 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
517 debian/open-iscsi.install:
518 Prevent network interface that contains iscsi root from bouncing
519 during boot or going down during shutdown.
520 Integrates with resolvconf and initramfs code that writes
521 /run/initramfs/open-iscsi.interface
522 - debian/open-iscsi.maintscript: clean up the obsolete
523 iscsi-network-interface upstart job, file on upgrade.
524 - Let iscsid systemd job run in privileged containers but not in
525 unprivileged ones
526 - Start open-iscsi systemd job when either /etc/iscsi/nodes or
527 /sys/class/iscsi_session have content
528 Based on patch by Nish Aravamudan, thanks! (LP #1576341)
529 - add IPv6 support
530 + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
531 LP #1621507
532 + Source /run/net6-*.conf when needed.
533 + debian/extra/initramfs.local-top: handle IPv6 configs being
534 shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
535 can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
536 * Drop:
537 - d/extra/initramfs.local-top: When booting from iBFT,
538 set the PROTO= entry in /run/net-*.conf accordingly,
539 so that other tools, such as cloud-init, can use that
540 information. (cloud-init fails if the current PROTO=none
541 is used.) (LP: #1684039) (Closes: #866213)
542 [ Fixed in Debian 2.0.874-4 ]
543 * d/t/test-open-iscsi.py: drop test_daemon test
544 - With the updates to the systemd units, the services do not run
545 unless iSCSI is configured.
546
547 -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 08 Aug 2017 16:16:27 -0700
548
88open-iscsi (2.0.874-4) unstable; urgency=medium549open-iscsi (2.0.874-4) unstable; urgency=medium
89550
90 * [0347300] initramfs: populate PROTO= entry in /run/net-*.conf from iBFT551 * [0347300] initramfs: populate PROTO= entry in /run/net-*.conf from iBFT
@@ -99,6 +560,64 @@ open-iscsi (2.0.874-3) unstable; urgency=medium
99560
100 -- Christian Seiler <christian@iwakd.de> Sun, 18 Jun 2017 22:01:22 +0200561 -- Christian Seiler <christian@iwakd.de> Sun, 18 Jun 2017 22:01:22 +0200
101562
563open-iscsi (2.0.874-2ubuntu3) artful; urgency=medium
564
565 * d/t/test-open-iscsi.py: drop test_daemon test
566 - With the updates to the systemd units, the services do not run
567 unless iSCSI is configured.
568
569 -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 08 Aug 2017 16:05:29 -0700
570
571open-iscsi (2.0.874-2ubuntu2) artful; urgency=medium
572
573 * d/extra/initramfs.local-top: When booting from iBFT,
574 set the PROTO= entry in /run/net-*.conf accordingly,
575 so that other tools, such as cloud-init, can use that
576 information. (cloud-init fails if the current PROTO=none
577 is used.) (LP: #1684039) (Closes: #866213)
578
579 -- Eric Desrochers <eric.desrochers@canonical.com> Wed, 05 Jul 2017 09:02:12 -0400
580
581open-iscsi (2.0.874-2ubuntu1) artful; urgency=medium
582
583 [ Nishanth Aravamudan ]
584 * Merge with Debian unstable. Remaining changes:
585 - debian/tests: Add Ubuntu autopkgtests.
586 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
587 debian/open-iscsi.install:
588 Prevent network interface that contains iscsi root from bouncing
589 during boot or going down during shutdown.
590 Integrates with resolvconf and initramfs code that writes
591 /run/initramfs/open-iscsi.interface
592 - debian/open-iscsi.maintscript: clean up the obsolete
593 iscsi-network-interface upstart job, file on upgrade.
594 - add IPv6 support
595 + add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
596 LP #1621507
597 + Source /run/net6-*.conf when needed.
598 + debian/extra/initramfs.local-top: handle IPv6 configs being
599 shipped in DEVICE6 or /run/net6-*.conf in the initramfs, so we
600 can fill in /run/initramfs/open-iscsi.interface (LP #1621507)
601 * Drop:
602 - Make systemd job not run in containers (LP #1576341)
603 [ This prevents running iscsi in privileged containers.
604 Fixed differently in this upload. ]
605 - Cherry-pick from Debian git repository (Christian Seiler):
606 + open-iscsi-udeb: drop Depends: libnss-files-udeb
607 (Closes #819685)
608 [ Fixed in Debian ]
609 - d/extra/initramfs.local-top whitespace change
610 [ previously undocumented ]
611
612 [ Balint Reczey ]
613 * Let iscsid systemd job run in privileged containers but not in
614 unprivileged ones
615 * Start open-iscsi systemd job when either /etc/iscsi/nodes or
616 /sys/class/iscsi_session have content
617 Based on patch by Nish Aravamudan, thanks! (LP #1576341)
618
619 -- Nishanth Aravamudan <nish.aravamudan@canonical.com> Tue, 09 May 2017 09:24:23 -0700
620
102open-iscsi (2.0.874-2) unstable; urgency=medium621open-iscsi (2.0.874-2) unstable; urgency=medium
103622
104 [ Christian Seiler ]623 [ Christian Seiler ]
@@ -238,6 +757,155 @@ open-iscsi (2.0.873+git0.3b4b4500-15) unstable; urgency=medium
238757
239 -- Christian Seiler <christian@iwakd.de> Fri, 20 May 2016 09:52:46 +0200758 -- Christian Seiler <christian@iwakd.de> Fri, 20 May 2016 09:52:46 +0200
240759
760open-iscsi (2.0.873+git0.3b4b4500-14ubuntu17) zesty; urgency=medium
761
762 * debian/tests:
763 - README-boot-test.md: mention limited space caveat.
764 - patch-image: fix handling of ADT_TEST_TRIGGERS if source package
765 built more than one binary package.
766 - test-open-iscsi.py: change to rely on patch-image
767 adding package 'open-iscsi' rather than passing it in itself.
768
769 -- Scott Moser <smoser@ubuntu.com> Thu, 16 Feb 2017 15:47:58 -0500
770
771open-iscsi (2.0.873+git0.3b4b4500-14ubuntu16) zesty; urgency=medium
772
773 * debian/tests: many improvements to the open-iscsi and tgt boot test.
774 - only run test on amd64. just avoid timeout errors or other unrelated
775 issues causing failure.
776 - debian/tests/README-boot-test.md: add doc describing the tgt-boot-test
777 - rename get-maas-eph to get-image
778 - use a cloud image instead of a maas image for booting. The value in
779 this is that we can then install open-iscsi inside the image and get an
780 updated initramfs.
781 - use subprocess.check_call rather than subprocess.call so that we
782 actually catch errors.
783 - update xkvm to what is in curtin/tools/xkvm
784 - improve updating of images to consider ADT_TEST_TRIGGERS if set.
785
786 -- Scott Moser <smoser@ubuntu.com> Tue, 14 Feb 2017 17:07:00 -0500
787
788open-iscsi (2.0.873+git0.3b4b4500-14ubuntu15) zesty; urgency=medium
789
790 * debian/tests/tgt-boot-test: set HOST_IP harder for the testsuite test.
791
792 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Sun, 29 Jan 2017 13:05:47 -0500
793
794open-iscsi (2.0.873+git0.3b4b4500-14ubuntu14) zesty; urgency=medium
795
796 * Make systemd job not run in containers (LP: #1576341)
797
798 -- Serge Hallyn <serge.hallyn@ubuntu.com> Sun, 15 Jan 2017 23:08:29 -0600
799
800open-iscsi (2.0.873+git0.3b4b4500-14ubuntu13) zesty; urgency=medium
801
802 * Fix syntax error in previous changes. LP: #1621507
803
804 -- LaMont Jones <lamont@ubuntu.com> Fri, 09 Dec 2016 12:35:45 +0100
805
806open-iscsi (2.0.873+git0.3b4b4500-14ubuntu12) zesty; urgency=medium
807
808 * debian/tests/tgt-boot-test: set HOST_IP to 10.0.2.2; it's suboptimal but
809 given the test setup this will allow the right IPs to be used to bring up
810 the iscsi target in the xkvm.
811
812 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 08 Dec 2016 11:00:12 +0100
813
814open-iscsi (2.0.873+git0.3b4b4500-14ubuntu11) zesty; urgency=medium
815
816 * debian/tests/tgt-boot-test: drop -serial stdio altogether since running
817 the VM in -nographics mode will already output to stdout.
818
819 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Tue, 22 Nov 2016 11:27:55 -0500
820
821open-iscsi (2.0.873+git0.3b4b4500-14ubuntu10) zesty; urgency=medium
822
823 * debian/tests/tgt-boot-test: always log qemu serial to stdio so we can
824 actually see what is going on during the tests.
825
826 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 17 Nov 2016 11:01:27 -0500
827
828open-iscsi (2.0.873+git0.3b4b4500-14ubuntu9) zesty; urgency=medium
829
830 [ LaMont Jones ]
831 * Clean up net-interface-handler
832 * Source /run/net6-*.conf when needed.
833
834 [ Mathieu Trudel-Lapierre ]
835 * debian/extra/initramfs.local-top: handle IPv6 configs being shipped in
836 DEVICE6 or /run/net6-*.conf in the initramfs, so we can fill in
837 /run/initramfs/open-iscsi.interface (LP: #1621507)
838
839 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Thu, 03 Nov 2016 16:30:37 -0600
840
841open-iscsi (2.0.873+git0.3b4b4500-14ubuntu8) yakkety; urgency=medium
842
843 * debian/tests/xkvm: don't --enable-kvm.
844
845 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Wed, 05 Oct 2016 12:58:21 -0400
846
847open-iscsi (2.0.873+git0.3b4b4500-14ubuntu7) yakkety; urgency=medium
848
849 * debian/tests/test-open-iscsi.py: glob to pick up open-iscsi.deb, which may
850 be named differently depending on how autopkgtests are run.
851
852 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Wed, 05 Oct 2016 09:56:25 -0400
853
854open-iscsi (2.0.873+git0.3b4b4500-14ubuntu6) yakkety; urgency=medium
855
856 * debian/tests/test-open-iscsi.py: install the open-iscsi binary into a test
857 MAAS image, so we can check bootability. Download the open-iscsi explicitly
858 to /tmp before trying to copy it; so that we don't need to depend on ugly
859 internal autopkgtest paths.
860
861 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Tue, 04 Oct 2016 09:05:56 -0400
862
863open-iscsi (2.0.873+git0.3b4b4500-14ubuntu5) yakkety; urgency=medium
864
865 * debian/tests/control: add build-needed since some of the new tests
866 appear to require that (so they can reach open-iscsi.deb which is a build
867 artifact from building in autopkgtest).
868
869 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Mon, 03 Oct 2016 16:10:54 -0400
870
871open-iscsi (2.0.873+git0.3b4b4500-14ubuntu4) yakkety; urgency=medium
872
873 * add support for IPV6{DOMAINSEARCH,DNS0,DNS1} to net-interface-handler
874 LP: #1621507
875
876 -- LaMont Jones <lamont@canonical.com> Tue, 20 Sep 2016 08:05:41 -0600
877
878open-iscsi (2.0.873+git0.3b4b4500-14ubuntu3) xenial; urgency=medium
879
880 * Cherry-pick from Debian git repository (Christian Seiler):
881 - open-iscsi-udeb: drop Depends: libnss-files-udeb (Closes: #819685)
882
883 -- Colin Watson <cjwatson@ubuntu.com> Fri, 15 Apr 2016 16:54:26 +0100
884
885open-iscsi (2.0.873+git0.3b4b4500-14ubuntu2) xenial; urgency=medium
886
887 * debian/tests: add two new tests. One to verify net-interface-handler is
888 installed executable, and one to actually test that /etc/resolv.conf is
889 updated with dhcp dns responses.
890
891 -- Diogo Matsubara <diogo.matsubara@gmail.com> Wed, 09 Mar 2016 12:56:42 -0300
892
893open-iscsi (2.0.873+git0.3b4b4500-14ubuntu1) xenial; urgency=medium
894
895 * Merge from debian. Remaining changes:
896 - debian/tests: Add Ubuntu autopkgtest.
897 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
898 debian/open-iscsi.install:
899 Prevent network interface that contains iscsi root from bouncing
900 during boot or going down during shutdown.
901 Integrates with resolvconf and initramfs code that writes
902 /run/initramfs/open-iscsi.interface
903 - debian/open-iscsi.maintscript: clean up the obsolete
904 iscsi-network-interface upstart job, file on upgrade.
905 * make debian/net-interface-handler executable (LP: #1553017)
906
907 -- Scott Moser <smoser@ubuntu.com> Fri, 04 Mar 2016 13:17:45 -0500
908
241open-iscsi (2.0.873+git0.3b4b4500-14) unstable; urgency=medium909open-iscsi (2.0.873+git0.3b4b4500-14) unstable; urgency=medium
242910
243 [ Christian Seiler ]911 [ Christian Seiler ]
@@ -250,6 +918,21 @@ open-iscsi (2.0.873+git0.3b4b4500-14) unstable; urgency=medium
250918
251 -- Christian Seiler <christian@iwakd.de> Thu, 03 Mar 2016 18:47:46 +0100919 -- Christian Seiler <christian@iwakd.de> Thu, 03 Mar 2016 18:47:46 +0100
252920
921open-iscsi (2.0.873+git0.3b4b4500-13ubuntu1) xenial; urgency=medium
922
923 * Merge from Debian (LP: #1546877). Remaining changes:
924 - debian/tests: Add Ubuntu autopkgtest.
925 - debian/iscsi-network-interface.rules, debian/net-interface-handler,
926 debian/open-iscsi.install:
927 Prevent network interface that contains iscsi root from bouncing
928 during boot or going down during shutdown.
929 Integrates with resolvconf and initramfs code that writes
930 /run/initramfs/open-iscsi.interface
931 - debian/open-iscsi.maintscript: clean up the obsolete
932 iscsi-network-interface upstart job, file on upgrade.
933
934 -- Scott Moser <smoser@ubuntu.com> Thu, 18 Feb 2016 00:53:37 -0500
935
253open-iscsi (2.0.873+git0.3b4b4500-13) unstable; urgency=medium936open-iscsi (2.0.873+git0.3b4b4500-13) unstable; urgency=medium
254937
255 [ Christian Seiler ]938 [ Christian Seiler ]
@@ -471,6 +1154,115 @@ open-iscsi (2.0.873+git0.3b4b4500-1) unstable; urgency=low
4711154
472 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 05 Nov 2013 21:45:47 +05301155 -- Ritesh Raj Sarraf <rrs@debian.org> Tue, 05 Nov 2013 21:45:47 +0530
4731156
1157open-iscsi (2.0.873-3ubuntu13) wily; urgency=medium
1158
1159 * debian/net-interface-handler: Create the resolvconf dir, to avoid failure
1160 when resolvconf did not start yet; the udev rules run in parallel with
1161 it. (LP: #1501033)
1162
1163 -- Martin Pitt <martin.pitt@ubuntu.com> Tue, 06 Oct 2015 07:05:48 +0200
1164
1165open-iscsi (2.0.873-3ubuntu12) wily; urgency=medium
1166
1167 * Drop debian/ifup@.service.conf again, it ceased to work with net.agent in
1168 wily and the whole idea of net-interface-handler is to *stop* ifupdown
1169 from fiddling with the iscsi interface. Replace with udev rules
1170 (debian/iscsi-network-interface.rules) which achieves this without relying
1171 on ifupdown or a particular init system. (LP: #1463461)
1172 * Drop debian/open-iscsi.iscsi-network-interface.upstart as well, obsolete
1173 now. Also clean it up on upgrades.
1174
1175 -- Martin Pitt <martin.pitt@ubuntu.com> Thu, 11 Jun 2015 11:58:29 +0200
1176
1177open-iscsi (2.0.873-3ubuntu11) vivid; urgency=medium
1178
1179 * Factor out logic from debian/open-iscsi.iscsi-network-interface.upstart
1180 into debian/net-interface-handler, and install the latter in debian/rules.
1181 * Add debian/ifup@.service.conf: Drop-in for ifup@.service to run
1182 net-interface-handler under systemd. (LP: #1432829)
1183
1184 -- Martin Pitt <martin.pitt@ubuntu.com> Fri, 27 Mar 2015 09:51:05 +0100
1185
1186open-iscsi (2.0.873-3ubuntu10) vivid; urgency=medium
1187
1188 * Start open-iscsi after installation and make sure initiatorname is
1189 generated. (Patch backported from Debian)
1190 * debian/tests/daemon: Stop calling the init.d script as we expect the
1191 daemon to start automatically now.
1192
1193 -- Martin Pitt <martin.pitt@ubuntu.com> Fri, 06 Mar 2015 13:17:26 +0100
1194
1195open-iscsi (2.0.873-3ubuntu9) trusty; urgency=medium
1196
1197 * Add missing python test dependency.
1198
1199 -- Martin Pitt <martin.pitt@ubuntu.com> Wed, 26 Feb 2014 16:07:37 +0100
1200
1201open-iscsi (2.0.873-3ubuntu8) trusty; urgency=medium
1202
1203 * open-iscsi-udeb: Enable builds on armhf, arm64, ppc64el, x32 (LP: #1274203)
1204
1205 -- dann frazier <dann.frazier@canonical.com> Wed, 29 Jan 2014 12:34:45 -0700
1206
1207open-iscsi (2.0.873-3ubuntu7) saucy; urgency=low
1208
1209 * Use dh_autotools-dev to update config.sub|guess.
1210
1211 -- Dmitrijs Ledkovs <dmitrij.ledkov@ubuntu.com> Fri, 11 Oct 2013 17:03:37 +0100
1212
1213open-iscsi (2.0.873-3ubuntu6) saucy; urgency=low
1214
1215 * debian/tests: Add autopkgtest.
1216
1217 -- Yolanda <yolanda.robla@canonical.com> Mon, 27 May 2013 10:39:35 +0200
1218
1219open-iscsi (2.0.873-3ubuntu5) quantal-proposed; urgency=low
1220
1221 * Ensure all udev events have been processed before trying to configure
1222 iscsi networking in the initramfs (LP: #1066945):
1223 - debian/extra/initramfs.local-top: Restore wait_for_udev call before
1224 configure_networking to ensure network devices are present.
1225
1226 -- James Page <james.page@ubuntu.com> Wed, 17 Oct 2012 12:37:43 +0100
1227
1228open-iscsi (2.0.873-3ubuntu4) quantal-proposed; urgency=low
1229
1230 * Generate initiator name on install, not first boot, ensuring that the
1231 initramfs built during install contains a valid iSCSI initiator name
1232 resulting in a iSCSI based root volume that will actually boot
1233 (LP: #1057635):
1234 - debian/{rules,initiatorname.iscsi}: Don't install a default
1235 initiatorname.iscsi.
1236 - debian/open-iscsi.postinst: Generate initiatorname.iscsi on install.
1237
1238 -- James Page <james.page@ubuntu.com> Mon, 15 Oct 2012 12:42:53 +0100
1239
1240open-iscsi (2.0.873-3ubuntu3) quantal; urgency=low
1241
1242 * debian/open-iscsi.iscsi-network-interface.upstart: fix bad syntax
1243 in 'post-stop'
1244
1245 -- Scott Moser <smoser@ubuntu.com> Mon, 17 Sep 2012 16:50:22 -0400
1246
1247open-iscsi (2.0.873-3ubuntu2) quantal; urgency=low
1248
1249 * debian/extra/initramfs.local-top: start writing
1250 /run/initramfs/open-iscsi.interface file again (LP: #1050480)
1251 * debian/open-iscsi.iscsi-network-interface.upstart: integrate with
1252 resolvconf (LP: #1050487)
1253
1254 -- Scott Moser <smoser@ubuntu.com> Mon, 17 Sep 2012 15:46:26 -0400
1255
1256open-iscsi (2.0.873-3ubuntu1) quantal; urgency=low
1257
1258 * Merge from Debian. Remaining changes: (LP: #961114, LP: #677333)
1259 - Add upstart job iscsi-network-interface
1260 - Migrate from /var/run and /lib/init/rw to /run, from /var/lock to
1261 /run/lock.
1262 * Turn open-iscsi-utils into a transitional package
1263
1264 -- Stéphane Graber <stgraber@ubuntu.com> Tue, 10 Jul 2012 13:53:52 -0400
1265
474open-iscsi (2.0.873-3) unstable; urgency=low1266open-iscsi (2.0.873-3) unstable; urgency=low
4751267
476 * [4939401] Fix build to install udeb stuff only on supported architectures1268 * [4939401] Fix build to install udeb stuff only on supported architectures
@@ -645,6 +1437,239 @@ open-iscsi (2.0.871-1) unstable; urgency=low
6451437
646 -- Ritesh Raj Sarraf <rrs@researchut.com> Sat, 06 Feb 2010 20:28:23 +05301438 -- Ritesh Raj Sarraf <rrs@researchut.com> Sat, 06 Feb 2010 20:28:23 +0530
6471439
1440open-iscsi (2.0.871-0ubuntu9) oneiric-proposed; urgency=low
1441
1442 * Make sure the upstart job triggers ifupdown's upstart script to avoid
1443 waiting 2 minutes at boot time for network to come up. (LP: #870214)
1444
1445 -- Stéphane Graber <stgraber@ubuntu.com> Tue, 11 Oct 2011 22:31:39 +0100
1446
1447open-iscsi (2.0.871-0ubuntu8) oneiric; urgency=low
1448
1449 * Disable open-iscsi init script when root is on iscsi (LP: #838809)
1450
1451 -- Stéphane Graber <stgraber@ubuntu.com> Thu, 15 Sep 2011 10:01:12 -0400
1452
1453open-iscsi (2.0.871-0ubuntu7) oneiric; urgency=low
1454
1455 * Migrate from /var/run and /lib/init/rw to /run, from /var/lock to
1456 /run/lock, and from /dev/.initramfs to /run/initramfs.
1457
1458 -- Colin Watson <cjwatson@ubuntu.com> Thu, 14 Jul 2011 17:01:42 +0100
1459
1460open-iscsi (2.0.871-0ubuntu6) oneiric; urgency=low
1461
1462 * Fix initramfs iSCSI login (many thanks to Amos Hayes for lending me a
1463 test system; LP: #728088):
1464 - Write out /dev/.initramfs/open-iscsi.interface in the same subshell as
1465 configure_networking, so that we can get at the value of DEVICE.
1466 - Wait for udev to settle before attempting to configure networking.
1467
1468 -- Colin Watson <cjwatson@ubuntu.com> Fri, 27 May 2011 23:27:31 +0100
1469
1470open-iscsi (2.0.871-0ubuntu5) maverick; urgency=low
1471
1472 * Include <sys/types.h> and <sys/stat.h> in usr/iscsi_sysfs.c for S_*
1473 macros (LP: #600953).
1474
1475 -- Colin Watson <cjwatson@ubuntu.com> Fri, 02 Jul 2010 17:08:14 +0100
1476
1477open-iscsi (2.0.871-0ubuntu4) lucid; urgency=low
1478
1479 * Revert ISCSI_NETDEVICE change; it's normally better to select the
1480 interface by MAC address (LP: #473036).
1481
1482 -- Colin Watson <cjwatson@ubuntu.com> Fri, 05 Feb 2010 12:06:06 -0800
1483
1484open-iscsi (2.0.871-0ubuntu3) lucid; urgency=low
1485
1486 * If ISCSI_NETDEVICE is set, configure that interface in the initramfs
1487 (LP: #473036).
1488
1489 -- Colin Watson <cjwatson@ubuntu.com> Fri, 22 Jan 2010 17:01:17 +0000
1490
1491open-iscsi (2.0.871-0ubuntu2) lucid; urgency=low
1492
1493 * Fix handling of ISCSI_USERNAME, ISCSI_PASSWORD, ISCSI_IN_USERNAME, and
1494 ISCSI_IN_PASSWORD in iscsi.initramfs (closes: #525053).
1495
1496 -- Colin Watson <cjwatson@ubuntu.com> Mon, 14 Dec 2009 12:24:42 +0000
1497
1498open-iscsi (2.0.871-0ubuntu1) lucid; urgency=low
1499
1500 * New upstream release.
1501 * If the root filesystem is on iSCSI, prevent the network interface used
1502 for it from being brought up or down automatically (LP: #457767).
1503 * Backport from upstream:
1504 - Allow updating of discovery records (Hannes Reinecke).
1505 - Fix discovery record use, rather than always using iscsid.conf
1506 settings (Mike Christie).
1507
1508 -- Colin Watson <cjwatson@ubuntu.com> Thu, 10 Dec 2009 18:19:20 +0000
1509
1510open-iscsi (2.0.870.1-0ubuntu12) karmic; urgency=low
1511
1512 * debian/open-iscsi-udeb.finish-install: Stop checking
1513 disk-detect/iscsi/enable, as that template doesn't exist any more.
1514
1515 -- Colin Watson <cjwatson@ubuntu.com> Fri, 02 Oct 2009 18:49:18 +0100
1516
1517open-iscsi (2.0.870.1-0ubuntu11) karmic; urgency=low
1518
1519 * open-iscsi-utils Replaces: old versions of open-iscsi.
1520 * SECURITY UPDATE: temporary file vulnerability (LP: #408915)
1521 - utils/iscsi_discovery: store iscsiadm -m discovery result in a
1522 variable rather than writing it to an insecurely-created temporary
1523 file
1524 - CVE-2009-1297
1525
1526 -- Colin Watson <cjwatson@ubuntu.com> Mon, 24 Aug 2009 23:42:10 +0100
1527
1528open-iscsi (2.0.870.1-0ubuntu10) karmic; urgency=low
1529
1530 * debian/control, debian/open-iscsi-utils.install,
1531 open-iscsi-utils.manpages : create a new binary package which
1532 contains /sbin/iscsiadm, needed for some packages to build against
1533 (eg, libvirt), but not containing the init script, LP: #414986
1534
1535 -- Dustin Kirkland <kirkland@ubuntu.com> Tue, 18 Aug 2009 08:11:34 -0500
1536
1537open-iscsi (2.0.870.1-0ubuntu9) karmic; urgency=low
1538
1539 * debian/open-iscsi.init: don't exit with error if
1540 /lib/init/rw/sendsigs.omit.d/ doesn't exist (LP: #414986)
1541
1542 -- Jamie Strandboge <jamie@ubuntu.com> Mon, 17 Aug 2009 14:12:01 -0500
1543
1544open-iscsi (2.0.870.1-0ubuntu8) karmic; urgency=low
1545
1546 * Make sure network devices are always included in the initramfs if
1547 booting with / on iSCSI.
1548 * Retry initramfs network configuration for a while until it works (LP:
1549 #237460).
1550
1551 -- Colin Watson <cjwatson@ubuntu.com> Tue, 11 Aug 2009 13:05:43 +0100
1552
1553open-iscsi (2.0.870.1-0ubuntu7) karmic; urgency=low
1554
1555 [ Colin Watson ]
1556 * debian/open-iscsi-udeb.postinst, debian/open-iscsi-udeb.templates:
1557 Remove; this is being taken over by disk-detect and partman-iscsi.
1558 * debian/control: Remove XB-Installer-Menu-Item.
1559
1560 [ Mathias Gug ]
1561 * debian/open-iscsi.postinst: Fix backwards use of update-rc.d (LP:
1562 #306678).
1563 * debian/open-iscsi.init: Overwrite existing pid file symlinks in
1564 /lib/init/rw/sendsigs.omit.d/.
1565
1566 -- Colin Watson <cjwatson@ubuntu.com> Mon, 10 Aug 2009 13:28:41 +0100
1567
1568open-iscsi (2.0.870.1-0ubuntu6) karmic; urgency=low
1569
1570 * utils/iscsi_discovery: Fix several bashisms (test ==, &> redirection,
1571 trap with numeric signals).
1572
1573 -- Colin Watson <cjwatson@ubuntu.com> Tue, 04 Aug 2009 12:30:44 +0100
1574
1575open-iscsi (2.0.870.1-0ubuntu5) karmic; urgency=low
1576
1577 * utils/iscsi_discovery: replace uses of awk with other shell voodoo, so
1578 that this works in the installer. LP: #236640.
1579 * debian/rules, debian/open-iscsi-udeb.dirs: install the open-isci-udeb
1580 finish script to /usr/lib/finish-install.d, not to /lib/finish-install.d.
1581 * debian/open-iscsi-udeb.finish-install: copy the config from the root
1582 to the correct directory in the target.
1583
1584 -- Steve Langasek <steve.langasek@ubuntu.com> Tue, 07 Jul 2009 22:10:17 -0700
1585
1586open-iscsi (2.0.870.1-0ubuntu4) karmic; urgency=low
1587
1588 * debian/extra/initramfs.hook: iscsistart is in /sbin, not /usr/sbin (LP:
1589 #364616).
1590
1591 -- Colin Watson <cjwatson@ubuntu.com> Thu, 02 Jul 2009 14:12:25 +0100
1592
1593open-iscsi (2.0.870.1-0ubuntu3) jaunty; urgency=low
1594
1595 * Invoke iscsi-iname using normal $PATH lookup rather than using an
1596 incorrect explicit path (see LP #236640).
1597
1598 -- Colin Watson <cjwatson@ubuntu.com> Thu, 09 Apr 2009 16:49:08 +0100
1599
1600open-iscsi (2.0.870.1-0ubuntu2) jaunty; urgency=low
1601
1602 * debian/control: Drop udeb dependency on crypto-modules; as best as I can
1603 tell, this is required for crc32c support, which is now built-in to the
1604 Ubuntu kernels.
1605
1606 -- Dustin Kirkland <kirkland@ubuntu.com> Tue, 03 Feb 2009 11:20:35 +0100
1607
1608open-iscsi (2.0.870.1-0ubuntu1) jaunty; urgency=low
1609
1610 * New upstream release:
1611 - Support 2.6.26/27 kernels (LP: #289470).
1612 - Fix iscsid shutdown (LP: #181188).
1613 * Merge from Debian. Remaining Ubuntu changes:
1614 - Note: Debian version isn't 870~rc3 but 869.2 which leads to a big
1615 .diff.gz file. Only files in debian/ have been considered for this merge
1616 since debian hasn't patched the source.
1617 - debian/control, debian/rules, debian/open-iscsi-udeb*:
1618 + Add open-iscsi-udeb.
1619 - debian/open-iscsi.dirs:
1620 + rename dirs to open-iscsi.dirs because of open-iscsi-udeb addition.
1621 + drop network/if-up.d/ directory since we're using symlinks instead.
1622 + utilities installed in /bin,/sbin rather than /usr/bin,/usr/sbin.
1623 - debian/open-iscsi.init:
1624 + utilities installed in /bin,/sbin rather than /usr/bin,/usr/sbin.
1625 + lsb log messages.
1626 + Don't generate initiatorname name (moved to postinst).
1627 + Support for being called from ifup/ifdown scripts.
1628 + Refactor start functions:
1629 - move daemon start to startdaemon function.
1630 - call udevadm settle rather then udevsettle (which doesn't do anything
1631 useful).
1632 - don't exit if the daemon is already running during sanitychecks.
1633 Instead check in startdaemon if the daemon needs to be started.
1634 - only start automatic targets if necessary.
1635 - add waitfordevices function: called during rcS, waits for all
1636 automatic targets to be ready. Iscsi targets are considered as
1637 local block devices - they don't need to be marked with _netdev in
1638 fstab. (LP: #227848)
1639 - start targets if not run from rcS.
1640 + Check status of iscsid daemon in addition to listing the iscsi sessions
1641 when status action is called.
1642 + Add iscsid to the list of processes that should not be killed by
1643 sendsigs during shutdown (LP: #192080).
1644 + Add starttargets, stoptargets and restarttargets to usage message.
1645 - debian/rules:
1646 + Install utilities /bin,/sbin rather than /usr/bin,/usr/sbin.
1647 + Start open-iscsi at S25 (waiting for devices created by ifupdown
1648 calls and before local filesystems are checked and mounted)
1649 + stop at S41 (after local filesystems are unmounted). Don't use
1650 umountiscsi.sh script from debian. (LP: #192080).
1651 - debian/initiatorname.iscsi, debian/open-iscsi.postinst:
1652 + Generate the random initiatorname during postinstall rather than in the
1653 init script.
1654 + Don't ship a default initiatorname.iscsi file.
1655 - debian/open-iscsi.postinst:
1656 + fix init script ordering on upgrades.
1657 - debian/open-iscsi.links:
1658 + symlink open-iscsi init script in if-up.d and if-down.d directory so
1659 that the iscsi subsystem is started/stopped when network interfaces
1660 are configured.
1661 - debian/open-iscsi.postrm:
1662 + delete iscsi configuration when the package is purged.
1663 - utils/iscsi_discovery: De-bashify iscsi_discovery.
1664 - usr/idbm.c: Fix build failure with new glibc. LP: #299843.
1665 * Dropped:
1666 - Exit without error if /sys is not available. Otherwise, it's not possible
1667 to use this package as a build-dependency (in Debian).
1668 - Drop upstream url in long description now that it's in the Homepage
1669 field (in Debian).
1670
1671 -- Mathias Gug <mathiaz@ubuntu.com> Mon, 01 Dec 2008 10:45:03 -0500
1672
648open-iscsi (2.0.870~rc3-0.6) unstable; urgency=low1673open-iscsi (2.0.870~rc3-0.6) unstable; urgency=low
6491674
650 * Non-maintainer upload.1675 * Non-maintainer upload.
@@ -744,6 +1769,47 @@ open-iscsi (2.0.869~rc4-1) experimental; urgency=low
7441769
745 -- Philipp Hug <debian@hug.cx> Sat, 12 Apr 2008 15:53:12 +02001770 -- Philipp Hug <debian@hug.cx> Sat, 12 Apr 2008 15:53:12 +0200
7461771
1772open-iscsi (2.0.865-1ubuntu5) jaunty; urgency=low
1773
1774 * Fix build failure with new glibc. LP: #299843.
1775
1776 -- Matthias Klose <doko@ubuntu.com> Thu, 27 Nov 2008 15:58:15 +0100
1777
1778open-iscsi (2.0.865-1ubuntu4) intrepid; urgency=low
1779
1780 * Exit without error if /sys is not available. Otherwise, it's not possible
1781 to use this package as a build-dependency.
1782
1783 -- Soren Hansen <soren@ubuntu.com> Fri, 02 May 2008 00:57:02 +0200
1784
1785open-iscsi (2.0.865-1ubuntu3) hardy; urgency=low
1786
1787 * Migration of /usr/{bin,sbin,lib} -> to /{bin,sbin,lib}.
1788 (LP: #208441)
1789 * Push the shutdown scripts back. (LP: #196748)
1790 * Update control to 3.7.3.
1791 * Updated the maintainer according to spec.
1792
1793 -- Chuck Short <zulcss@ubuntu.com> Wed, 09 Apr 2008 18:09:28 -0400
1794
1795open-iscsi (2.0.865-1ubuntu2) hardy; urgency=low
1796
1797 * Fixed init script to point to the right iscsiadm. (LP: #206520)
1798
1799 -- Chuck Short <zulcss@ubuntu.com> Tue, 25 Mar 2008 09:53:08 -0400
1800
1801open-iscsi (2.0.865-1ubuntu1) hardy; urgency=low
1802
1803 * Add open-iscsi-udeb.
1804 * Include iscsi_discovery.
1805 * De-bashify iscsi_discovery.
1806 * Start open-iscsi in single user mode.
1807 * Properly lsb-ify init script.
1808 * Modify Maintainer value to match the DebianMaintainerField
1809 specification.
1810
1811 -- Soren Hansen <soren@ubuntu.com> Fri, 08 Feb 2008 11:56:11 +0100
1812
747open-iscsi (2.0.865-1) unstable; urgency=low1813open-iscsi (2.0.865-1) unstable; urgency=low
7481814
749 * New upstream release1815 * New upstream release
diff --git a/debian/control b/debian/control
index 54d26b3..a0dd93f 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,8 @@
1Source: open-iscsi1Source: open-iscsi
2Section: net2Section: net
3Priority: optional3Priority: optional
4Maintainer: Debian iSCSI Maintainers <open-iscsi@packages.debian.org>4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5XSBC-Original-Maintainer: Debian iSCSI Maintainers <open-iscsi@packages.debian.org>
5Uploaders: Ritesh Raj Sarraf <rrs@debian.org>,6Uploaders: Ritesh Raj Sarraf <rrs@debian.org>,
6 Christian Seiler <christian@iwakd.de>7 Christian Seiler <christian@iwakd.de>
7Build-Depends: bison,8Build-Depends: bison,
@@ -27,8 +28,9 @@ Package: open-iscsi
27Architecture: linux-any28Architecture: linux-any
28Depends: ${misc:Depends},29Depends: ${misc:Depends},
29 ${shlibs:Depends},30 ${shlibs:Depends},
30 libopeniscsiusr,31 libopeniscsiusr0.2.0,
31 udev32 udev
33Recommends: ${busybox:Recommends}, finalrd (>= 3)
32Pre-Depends: debconf | debconf-2.034Pre-Depends: debconf | debconf-2.0
33Description: iSCSI initiator tools35Description: iSCSI initiator tools
34 The Open-iSCSI project is a high-performance, transport independent,36 The Open-iSCSI project is a high-performance, transport independent,
@@ -52,7 +54,7 @@ Description: iSCSI initiator tools
52 This package includes a daemon, iscsid, and a management utility,54 This package includes a daemon, iscsid, and a management utility,
53 iscsiadm.55 iscsiadm.
5456
55Package: libopeniscsiusr57Package: libopeniscsiusr0.2.0
56Architecture: linux-any58Architecture: linux-any
57Depends: ${misc:Depends},59Depends: ${misc:Depends},
58 ${shlibs:Depends}60 ${shlibs:Depends}
@@ -81,7 +83,7 @@ Description: iSCSI userspace library
81Package: libopeniscsiusr-dev83Package: libopeniscsiusr-dev
82Architecture: all84Architecture: all
83Depends: ${misc:Depends},85Depends: ${misc:Depends},
84 libopeniscsiusr86 libopeniscsiusr0.2.0 (= ${binary:Version})
85Enhances: open-iscsi87Enhances: open-iscsi
86Description: iSCSI userspace library headers88Description: iSCSI userspace library headers
87 The Open-iSCSI project is a high-performance, transport independent,89 The Open-iSCSI project is a high-performance, transport independent,
@@ -108,7 +110,7 @@ Package: iscsiuio
108Architecture: linux-any110Architecture: linux-any
109Depends: ${misc:Depends},111Depends: ${misc:Depends},
110 ${shlibs:Depends},112 ${shlibs:Depends},
111 libopeniscsiusr,113 libopeniscsiusr0.2.0,
112 udev114 udev
113Enhances: open-iscsi115Enhances: open-iscsi
114Description: iSCSI offloading daemon for QLogic devices116Description: iSCSI offloading daemon for QLogic devices
@@ -136,12 +138,12 @@ Package: open-iscsi-udeb
136# linux kernel udebs) must exist for these architectures - so138# linux kernel udebs) must exist for these architectures - so
137# check that before adding them to this list; the other139# check that before adding them to this list; the other
138# scsi-(core|common|...)-modules are NOT sufficient!140# scsi-(core|common|...)-modules are NOT sufficient!
139Architecture: amd64 arm64 armhf i386 ia64 mips mipsel powerpc ppc64 ppc64el s390x141Architecture: amd64 arm64 armhf ia64 mips mipsel powerpc ppc64 ppc64el s390x
140Section: debian-installer142Section: debian-installer
141Package-Type: udeb143Package-Type: udeb
142Depends: ${misc:Depends},144Depends: ${misc:Depends},
143 ${shlibs:Depends},145 ${shlibs:Depends},
144 libopeniscsiusr,146 libopeniscsiusr0.2.0,
145 udev,147 udev,
146 scsi-modules148 scsi-modules
147Description: Configure iSCSI149Description: Configure iSCSI
diff --git a/debian/extra/initramfs.hook b/debian/extra/initramfs.hook
index 6a430eb..7458571 100755
--- a/debian/extra/initramfs.hook
+++ b/debian/extra/initramfs.hook
@@ -32,7 +32,7 @@ if [ -r /etc/iscsi/iscsi.initramfs ] ; then
32 cp /etc/iscsi/iscsi.initramfs $DESTDIR/etc32 cp /etc/iscsi/iscsi.initramfs $DESTDIR/etc
33fi33fi
3434
35for x in crc32c libcrc32c iscsi_tcp libiscsi scsi_transport_iscsi iscsi_ibft; do35for x in crc32c libcrc32c ib_iser iscsi_tcp libiscsi scsi_transport_iscsi iscsi_ibft; do
36 manual_add_modules ${x}36 manual_add_modules ${x}
37done37done
38for x in cxgb3i cxgb4i; do38for x in cxgb3i cxgb4i; do
diff --git a/debian/extra/initramfs.local-bottom b/debian/extra/initramfs.local-bottom
index c32e5fe..06ddc56 100755
--- a/debian/extra/initramfs.local-bottom
+++ b/debian/extra/initramfs.local-bottom
@@ -7,4 +7,24 @@ if [ -x /sbin/iscsiuio ] && [ -e /run/initramfs/iscsiuio.pid ] ; then
7 --name iscsiuio --exec /sbin/iscsiuio || :7 --name iscsiuio --exec /sbin/iscsiuio || :
8fi8fi
99
10# Remove the interface file if no disks are present
11if [ -f /run/initramfs/open-iscsi.interface ] ; then
12 found=0
13 for disk in /dev/disk/by-path/*-iscsi-*; do
14 if [ ! -e "$disk" ] ; then
15 # If we have no matches, we stil go through the for loop once with
16 # the pattern as a string
17 continue
18 fi
19 if ! readlink -f "$disk" > /dev/null ; then
20 continue
21 fi
22 found=1
23 break;
24 done
25 if [ $found = 0 ] ; then
26 rm /run/initramfs/open-iscsi.interface
27 fi
28fi
29
10exit 030exit 0
diff --git a/debian/extra/initramfs.local-top b/debian/extra/initramfs.local-top
index 1045c50..9f3af32 100755
--- a/debian/extra/initramfs.local-top
+++ b/debian/extra/initramfs.local-top
@@ -93,6 +93,7 @@ do_iscsi_login ()
93 . /scripts/functions93 . /scripts/functions
9494
95 udevadm settle95 udevadm settle
96 IBFT_DHCP_DEVICE=""
9697
97 if [ -n "$ISCSI_AUTO" ] ; then98 if [ -n "$ISCSI_AUTO" ] ; then
98 # try to auto-configure network interface based99 # try to auto-configure network interface based
@@ -136,7 +137,13 @@ do_iscsi_login ()
136 echo "UPTIME='${UPTIME}'"137 echo "UPTIME='${UPTIME}'"
137 echo "DHCPLEASETIME='${DHCPLEASETIME}'"138 echo "DHCPLEASETIME='${DHCPLEASETIME}'"
138 echo "DOMAINSEARCH=''"139 echo "DOMAINSEARCH=''"
139 } > "/run/net-${DEVICE}.conf"140 } > "/run/net-${DEVICE}.conf.ibft"
141 if [ "$PROTO" != "dhcp" -a "$DHCPLEASETIME" = "0" ]; then
142 # this is static ibft configuration.
143 mv "/run/net-${DEVICE}.conf.ibft" "/run/net-${DEVICE}.conf"
144 else
145 IBFT_DHCP_DEVICE="$DEVICE"
146 fi
140 echo "${DEVICE}" > /run/initramfs/open-iscsi.interface147 echo "${DEVICE}" > /run/initramfs/open-iscsi.interface
141 # iscsistart -N doesn't set the default gateway. Therefore,148 # iscsistart -N doesn't set the default gateway. Therefore,
142 # we need to add it ourselves. However, the ip command is149 # we need to add it ourselves. However, the ip command is
@@ -172,9 +179,23 @@ do_iscsi_login ()
172179
173 # run configure_networking even if we have iscsi_auto, because there180 # run configure_networking even if we have iscsi_auto, because there
174 # could be other network interfaces that need to be configured181 # could be other network interfaces that need to be configured
175 # manually182 # also, if we set up DHCP iBFT, we need ipconfig to run so it creates
183 # a proper /run/net-${DEVICE}.conf file that includes the DNS search
184 # domain, which we don't get in our iBFT data (see LP: #1806777)
176 configure_networking185 configure_networking
177186
187 if [ -n "$IBFT_DHCP_DEVICE" ]; then
188 if ! [ -e "/run/net-${DEVICE}.conf" ] ; then
189 echo "WARN: ipconfig dhcp failed, using iSCSI iBFT config - DNS search domain may be missing at runtime" >&2
190 # We have DHCP iBFT, but ipconfig DHCP failed;
191 # so we should fallback to just using the iBFT config,
192 # though that will not include the DNS search domain
193 mv "/run/net-${DEVICE}.conf.ibft" "/run/net-${DEVICE}.conf"
194 # need to re-run configure_networking to process conf file
195 configure_networking
196 fi
197 fi
198
178 # Save network device we configured via configure_networking, but only199 # Save network device we configured via configure_networking, but only
179 # if we didn't already get one from autoconfiguration (then we always200 # if we didn't already get one from autoconfiguration (then we always
180 # prefer that).201 # prefer that).
@@ -186,6 +207,13 @@ do_iscsi_login ()
186 fi207 fi
187 if [ -n "${DEVICE}" ] ; then208 if [ -n "${DEVICE}" ] ; then
188 echo "${DEVICE}" > /run/initramfs/open-iscsi.interface209 echo "${DEVICE}" > /run/initramfs/open-iscsi.interface
210 else
211 for i in /run/net6-*.conf; do
212 [ -e "${i}" ] && { . "${i}" ; break ; }
213 done
214 fi
215 if [ -z "${DEVICE}" ] && [ -n "${DEVICE6}" ] ; then
216 echo "${DEVICE6}" > /run/initramfs/open-iscsi.interface
189 fi217 fi
190 fi218 fi
191219
diff --git a/debian/extra/net-interface-handler b/debian/extra/net-interface-handler
192new file mode 100755220new file mode 100755
index 0000000..9cd6e1e
--- /dev/null
+++ b/debian/extra/net-interface-handler
@@ -0,0 +1,80 @@
1#!/bin/sh -e
2# suppress configuration of network interface used
3# by iSCSI root device
4#
5# If the root filesystem is on iSCSI, then we must take care to avoid
6# changing the state of its network interface. To this end, the initramfs
7# leaves a note for us which interface was used, and we mangle
8# /run/network/ifstate manually to stop it being brought up or down
9# automatically. This is a slight layering violation, but, unfortunately,
10# ifupdown appears to have no way to do this without also running
11# /etc/network/*.d/ scripts.
12
13assert_interface() {
14 # udev sets INTERFACE to the name of the currently-processed nic.
15 [ -n "$INTERFACE" ] && return 0
16 echo "environment variable INTERFACE not set." 1>&2;
17 return 1
18}
19
20start() {
21 CR="
22"
23 assert_interface || return
24 ifile=/run/initramfs/open-iscsi.interface
25
26 [ -f "$ifile" ] && read iface < "$ifile" || return 0
27 [ "$INTERFACE" = "$iface" ] || return
28
29 if ! grep -qs "^$iface=" /run/network/ifstate; then
30 mkdir -p /run/network
31 echo "$iface=$iface" >>/run/network/ifstate
32
33 if [ -f /run/net-$iface.conf ]; then
34 conf=/run/net-$iface.conf
35 elif [ -f /run/net6-$iface.conf ]; then
36 conf=/run/net6-$iface.conf
37 else
38 conf=""
39 fi
40 if command -v resolvconf >/dev/null &&
41 [ -n "$conf" ]; then
42 . "$conf"
43 R=""
44 [ -n "$DOMAINSEARCH" ] && R="$R${CR}search $DOMAINSEARCH"
45 [ -n "$IPV6DOMAINSEARCH" ] && R="$R${CR}search $IPV6DOMAINSEARCH"
46 for ns in "$IPV4DNS0" "$IPV4DNS1" "$IPV6DNS0" "$IPV6DNS1"; do
47 [ -n "$ns" -a "$ns" != "0.0.0.0" ] && R="$R${CR}nameserver $ns"
48 done
49 if [ -n "$R" ]; then
50 # create the dir in case resolvconf did not start yet
51 mkdir -p /run/resolvconf/interface
52 resolvconf -a $iface.iscsi-network <<EOF
53${R#${CR}}
54EOF
55 fi
56 fi
57 fi
58}
59
60stop() {
61 assert_interface || return
62 ifile=/run/initramfs/open-iscsi.interface
63 [ -f "$ifile" ] && read iface < "$ifile" || return 0
64 [ "$INTERFACE" = "$iface" ] || return
65
66 if grep -qs "^$iface=" /run/network/ifstate; then
67 grep -v "^$iface=" /run/network/ifstate >/run/network/.ifstate.tmp || true
68 mv /run/network/.ifstate.tmp /run/network/ifstate
69
70 if command -v resolvconf >/dev/null; then
71 resolvconf -d $iface.iscsi-network
72 fi
73 fi
74}
75
76case "$1" in
77 start) start ;;
78 stop) stop ;;
79 *) echo "ERROR: must be called with 'start' or 'stop'" >&2; exit 1 ;;
80esac
diff --git a/debian/iscsi-network-interface.rules b/debian/iscsi-network-interface.rules
0new file mode 10064481new file mode 100644
index 0000000..e0408d7
--- /dev/null
+++ b/debian/iscsi-network-interface.rules
@@ -0,0 +1,3 @@
1# run before 80-networking.rules to run before ifupdown
2SUBSYSTEM=="net", ACTION=="add", RUN+="/lib/open-iscsi/net-interface-handler start"
3SUBSYSTEM=="net", ACTION=="remove", RUN+="/lib/open-iscsi/net-interface-handler stop"
diff --git a/debian/iscsid.service b/debian/iscsid.service
index d05953d..c98fd7e 100644
--- a/debian/iscsid.service
+++ b/debian/iscsid.service
@@ -7,13 +7,13 @@ After=network.target network-online.target
7DefaultDependencies=no7DefaultDependencies=no
8Conflicts=shutdown.target8Conflicts=shutdown.target
9Before=shutdown.target9Before=shutdown.target
10ConditionVirtualization=!private-users
1011
11[Service]12[Service]
12Type=forking13Type=forking
13PIDFile=/run/iscsid.pid14PIDFile=/run/iscsid.pid
14ExecStartPre=/lib/open-iscsi/startup-checks.sh15ExecStartPre=/lib/open-iscsi/startup-checks.sh
15ExecStart=/sbin/iscsid16ExecStart=/sbin/iscsid
16ExecStop=/sbin/iscsiadm -k 0 2
1717
18[Install]18[Install]
19WantedBy=sysinit.target19WantedBy=sysinit.target
diff --git a/debian/open-iscsi.finalrd b/debian/open-iscsi.finalrd
20new file mode 10075520new file mode 100755
index 0000000..d8c8a21
--- /dev/null
+++ b/debian/open-iscsi.finalrd
@@ -0,0 +1,40 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-3.0-only
3
4set -e
5
6if [ "$1" = "setup" ]
7then
8 . /usr/share/initramfs-tools/hook-functions
9 copy_exec /bin/grep
10 copy_exec /bin/sleep
11 copy_exec /sbin/iscsiadm
12 copy_exec /sbin/iscsid
13 # hm, not sure why expr is copied
14 copy_exec /usr/bin/expr
15 copy_file config /etc/iscsi/iscsid.conf
16 copy_file config /etc/iscsi/initiatorname.iscsi
17 exit 0
18fi
19
20# re-establish connection and logout during shutdown
21# if initramfs did bring up open-iscsi on boot
22[ -f /open-iscsi.interface ] || exit 0
23
24iscsid
25
26# After restarting iscsid, wait for an active connection.
27# Limit the wait time in case of unexpected failure of iscsid.
28MAX_RETRIES=30
29RETRY=0
30while ! iscsiadm -m session -P 1 | grep -q "iSCSI Connection State: LOGGED IN"; do
31 RETRY=$(($RETRY + 1))
32 if [ $RETRY -gt $MAX_RETRIES ]; then
33 echo "Unexpected iSCSI Connection State, forcing iSCSI logout."
34 break
35 fi
36 sleep 1
37done
38
39# Issue an iSCSI logout.
40iscsiadm -m node -u
diff --git a/debian/open-iscsi.kmod b/debian/open-iscsi.kmod
0deleted file mode 10064441deleted file mode 100644
index c5f90f3..0000000
--- a/debian/open-iscsi.kmod
+++ /dev/null
@@ -1,2 +0,0 @@
1iscsi_tcp
2ib_iser
diff --git a/debian/open-iscsi.postinst b/debian/open-iscsi.postinst
index f9867d4..505f7c1 100644
--- a/debian/open-iscsi.postinst
+++ b/debian/open-iscsi.postinst
@@ -17,16 +17,6 @@ restore_old_timeouts()
17case "$1" in17case "$1" in
18 configure)18 configure)
1919
20 # We switched over to modules-load.d logic, this is needed
21 MODULES_FILE=/lib/modules-load.d/open-iscsi.conf
22 if [ -f /etc/modules-load.d/open-iscsi.conf ] ; then
23 MODULES_FILE=/etc/modules-load.d/open-iscsi.conf
24 fi
25 grep '^[^#]' $MODULES_FILE | while read module args ; do
26 [ "$module" ] || continue
27 modprobe $module $args >/dev/null 2>&1 || true
28 done
29
30 # Compatibility symlinks20 # Compatibility symlinks
31 for file in iscsid iscsi_discovery iscsi-iname iscsistart; do21 for file in iscsid iscsi_discovery iscsi-iname iscsistart; do
32 if [ ! -e /usr/sbin/$file ]; then22 if [ ! -e /usr/sbin/$file ]; then
@@ -65,7 +55,9 @@ esac
6555
66#DEBHELPER#56#DEBHELPER#
6757
68if [ "$1" = configure ] ; then58if [ "$1" = configure ] && [ -n "$2" ] && [ -d /run/systemd/system ] &&
59 systemctl is-active iscsid.service > /dev/null
60then
69 # There already is a check in preinst with a debconf prompt that61 # There already is a check in preinst with a debconf prompt that
70 # allows the administrator to abort. Don't abort here, because62 # allows the administrator to abort. Don't abort here, because
71 # leaving the package in a half-configured state is probably worse.63 # leaving the package in a half-configured state is probably worse.
@@ -109,25 +101,9 @@ if [ "$1" = configure ] ; then
109 # Just in case something goes wrong:101 # Just in case something goes wrong:
110 sync102 sync
111103
112 # Note: 3>&- is required because iscsid doesn't close unused104 # we want to be able to be explicit to start .service, but follow policy.d
113 # FDs, but debconf/confmodule will make the fd 3 point to105 # therefore use deb-systemd-invoke
114 # the original stdout (and stdout to stderr) to make sure106 deb-systemd-invoke restart iscsid.service || true
115 # no program accidentally issues a command on stdout. On
116 # sysvinit systems this combination (iscsid not closing
117 # fds, fd 3 remaining open) will cause dpkg to wait
118 # forever for the maintscript to finish. (iscsid keeps
119 # this end of the pipe open even though the maintscript
120 # is finished, so dpkg will never receive a POLLHUP on
121 # its end of the pipe, waiting forever.) Closing fd 3
122 # here is the simplest solution. This issue does not
123 # occur with other init systems, since they start
124 # services in a clean environment without any extraneous
125 # open fds.
126 if [ -n "$2" ]; then
127 invoke-rc.d iscsid restart 3>&-
128 else
129 invoke-rc.d iscsid start 3>&-
130 fi
131107
132 RETRIES=0108 RETRIES=0
133 while cat /sys/class/iscsi_session/session*/state 2>/dev/null | grep -qv LOGGED_IN ; do109 while cat /sys/class/iscsi_session/session*/state 2>/dev/null | grep -qv LOGGED_IN ; do
@@ -149,17 +125,26 @@ if [ "$1" = configure ] ; then
149125
150 restore_old_timeouts126 restore_old_timeouts
151 trap - EXIT127 trap - EXIT
128fi
152129
153 # Don't restart (and therefore stop) open-iscsi, because we don't130if [ "$1" = configure ]; then
154 # want to logout from targets during a simple upgrade. But also,131 # With socket based activation one wants iscsid.socket to be active
155 # if for some reason there's some misconfigured target in the132 # But on upgrades the iscsid.service might already be active
156 # config that couldn't be activated, don't break postinst, so133 # Due to that directly starting iscsid.socket might fail:
157 # ignore the exit code.134 # systemd[1]: iscsid.socket: Socket service iscsid.service already active, refusing.
158 # See above for why 3>&- is here. (Technically it's not required135 # Therefore check if iscsid.service is:
159 # for postinst to work, but vgchange likes to complain about leaked136 # - active:
160 # file descriptors, and we don't need to show that message to the137 # - ok for now, do not start iscsid.socket as it would conflict
161 # user.)138 # - on a reboot .socket will be started as it is enabled
162 invoke-rc.d open-iscsi start 3>&- || true139 # - inactive:
140 # - start iscsid.socket - to be ready
141 # In both cases:
142 # - disable iscsid.service so it only starts by the socket after reboot
143 if [ -d /run/systemd/system ]; then
144 if ! systemctl is-active iscsid.service > /dev/null; then
145 deb-systemd-invoke start iscsid.socket || true
146 fi
147 fi
163fi148fi
164149
165exit 0150exit 0
diff --git a/debian/open-iscsi.service b/debian/open-iscsi.service
index a62825e..06f83fe 100644
--- a/debian/open-iscsi.service
+++ b/debian/open-iscsi.service
@@ -1,12 +1,16 @@
1[Unit]1[Unit]
2Description=Login to default iSCSI targets2Description=Login to default iSCSI targets
3Documentation=man:iscsiadm(8) man:iscsid(8)3Documentation=man:iscsiadm(8) man:iscsid(8)
4Wants=network-online.target remote-fs-pre.target iscsid.service4Wants=network-online.target remote-fs-pre.target
5After=network-online.target iscsid.service5After=network-online.target iscsid.service
6Before=remote-fs-pre.target6Before=remote-fs-pre.target
7DefaultDependencies=no7DefaultDependencies=no
8Conflicts=shutdown.target8Conflicts=shutdown.target
9Before=shutdown.target9Before=shutdown.target
10# Must have some pre-defined targets to login to
11ConditionDirectoryNotEmpty=|/etc/iscsi/nodes
12# or have a session to use via iscsid
13ConditionDirectoryNotEmpty=|/sys/class/iscsi_session
1014
11[Service]15[Service]
12Type=oneshot16Type=oneshot
@@ -15,11 +19,7 @@ RemainAfterExit=true
15# and 15 if a session is alread logged in (which we do not19# and 15 if a session is alread logged in (which we do not
16# consider an error)20# consider an error)
17SuccessExitStatus=15 2121SuccessExitStatus=15 21
18# iscsiadm will only work if iscsid is running. But we can't use a22# Note: iscsid will be socket activated by iscsiadm
19# Requires= dependency, since restarts of iscsid would then be
20# propagated to this service - and that would cause all sorts of
21# mayhem. Therefore, check it in ExecStartPre.
22ExecStartPre=/bin/systemctl --quiet is-active iscsid.service
23ExecStart=/sbin/iscsiadm -m node --loginall=automatic23ExecStart=/sbin/iscsiadm -m node --loginall=automatic
24ExecStart=/lib/open-iscsi/activate-storage.sh24ExecStart=/lib/open-iscsi/activate-storage.sh
25ExecStop=/lib/open-iscsi/umountiscsi.sh25ExecStop=/lib/open-iscsi/umountiscsi.sh
diff --git a/debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch b/debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
26new file mode 10064426new file mode 100644
index 0000000..dc31f34
--- /dev/null
+++ b/debian/patches/lp1755858-default-iscsid_conf-to-iscsid_socket.patch
@@ -0,0 +1,28 @@
1Description: default in iscid.conf to use iscsid.socket
2
3People do not want iscsid to run if not needed.
4To do so it is configured to be socket activated.
5Internally iscsid code has a fallback if the service is missing to run the
6command specified in iscsid.conf as "iscsid.startup".
7Set this to ensure the socket is active instead of calling the binary, which
8would not be what we want anyway as it would not be from the .service context.
9
10Forwarded: no (Downstream config)
11Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
12Bug-Ubuntu: https://bugs.launchpad.net/bugs/1755858
13Reviewed-by: Rafael David Tinoco <rafaeldtinoco@ubuntu.com>
14Last-Update: 2020-08-13
15
16--- a/etc/iscsid.conf
17+++ b/etc/iscsid.conf
18@@ -18,8 +18,8 @@
19 # maintainers. If you leave the iscsid daemon running all
20 # the time then leave this attribute commented out.
21 #
22-# Default for Fedora and RHEL. (uncomment to activate).
23-# iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.socket
24+# Default for Fedora and RHEL and Ubuntu. (uncomment to activate).
25+iscsid.startup = /bin/systemctl start iscsid.socket iscsiuio.socket
26 #
27 # Default if you are not using systemd (uncomment to activate)
28 # iscsid.startup = /usr/bin/service start iscsid
diff --git a/debian/patches/series b/debian/patches/series
0new file mode 10064429new file mode 100644
index 0000000..909a8f3
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
1lp1755858-default-iscsid_conf-to-iscsid_socket.patch
diff --git a/debian/rules b/debian/rules
index fd27c31..9061e2d 100755
--- a/debian/rules
+++ b/debian/rules
@@ -6,6 +6,10 @@ DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
6DPKG_EXPORT_BUILDFLAGS = 16DPKG_EXPORT_BUILDFLAGS = 1
7include /usr/share/dpkg/buildflags.mk7include /usr/share/dpkg/buildflags.mk
88
9# Fix gcc10 warnings as errors while upstream doesn't catch up
10export DEB_CFLAGS_PREPEND=-Wno-error=zero-length-bounds -Wno-error=format-overflow= -Wno-error=format-truncation= -Wno-error=maybe-uninitialized
11export DEB_CXXFLAGS_PREPEND=${DEB_CFLAGS_PREPEND}
12
9%:13%:
10 dh $@14 dh $@
1115
@@ -19,9 +23,10 @@ override_dh_auto_build:
19override_dh_auto_install:23override_dh_auto_install:
2024
21 @# libopeniscsiusr25 @# libopeniscsiusr
22 dh_install -p libopeniscsiusr libopeniscsiusr/libopeniscsiusr*.so.* usr/lib/${DEB_HOST_MULTIARCH}26 dh_install -p libopeniscsiusr0.2.0 libopeniscsiusr/libopeniscsiusr.so.* usr/lib/${DEB_HOST_MULTIARCH}
2327
24 @# libopeniscsi-dev28 @# libopeniscsi-dev
29 dh_install -p libopeniscsiusr-dev libopeniscsiusr/libopeniscsiusr.so usr/lib/${DEB_HOST_MULTIARCH}
25 dh_install -p libopeniscsiusr-dev libopeniscsiusr/libopeniscsiusr/ usr/include/30 dh_install -p libopeniscsiusr-dev libopeniscsiusr/libopeniscsiusr/ usr/include/
2631
27 @# open-iscsi32 @# open-iscsi
@@ -35,6 +40,9 @@ override_dh_auto_install:
35 dh_install -p open-iscsi debian/extra/logout-all.sh lib/open-iscsi/40 dh_install -p open-iscsi debian/extra/logout-all.sh lib/open-iscsi/
36 dh_install -p open-iscsi debian/extra/startup-checks.sh lib/open-iscsi/41 dh_install -p open-iscsi debian/extra/startup-checks.sh lib/open-iscsi/
37 dh_install -p open-iscsi debian/extra/activate-storage.sh lib/open-iscsi/42 dh_install -p open-iscsi debian/extra/activate-storage.sh lib/open-iscsi/
43 dh_install -p open-iscsi debian/extra/net-interface-handler lib/open-iscsi/
44 dh_install -p open-iscsi debian/open-iscsi.finalrd usr/share/finalrd/
45 dh_install -p open-iscsi etc/systemd/iscsid.socket lib/systemd/system/
38 mkdir -p debian/open-iscsi/usr/bin46 mkdir -p debian/open-iscsi/usr/bin
39 ln -s /sbin/iscsiadm debian/open-iscsi/usr/bin/iscsiadm47 ln -s /sbin/iscsiadm debian/open-iscsi/usr/bin/iscsiadm
40 mkdir -p debian/open-iscsi/usr/share/initramfs-tools/hooks48 mkdir -p debian/open-iscsi/usr/share/initramfs-tools/hooks
@@ -43,10 +51,9 @@ override_dh_auto_install:
43 cp -p debian/extra/initramfs.hook debian/open-iscsi/usr/share/initramfs-tools/hooks/iscsi51 cp -p debian/extra/initramfs.hook debian/open-iscsi/usr/share/initramfs-tools/hooks/iscsi
44 cp -p debian/extra/initramfs.local-top debian/open-iscsi/usr/share/initramfs-tools/scripts/local-top/iscsi52 cp -p debian/extra/initramfs.local-top debian/open-iscsi/usr/share/initramfs-tools/scripts/local-top/iscsi
45 cp -p debian/extra/initramfs.local-bottom debian/open-iscsi/usr/share/initramfs-tools/scripts/local-bottom/iscsi53 cp -p debian/extra/initramfs.local-bottom debian/open-iscsi/usr/share/initramfs-tools/scripts/local-bottom/iscsi
46 mkdir -p debian/open-iscsi/lib/modules-load.d/
47 cp -p debian/open-iscsi.kmod debian/open-iscsi/lib/modules-load.d/open-iscsi.conf
48 mkdir -p debian/open-iscsi/lib/udev/rules.d/54 mkdir -p debian/open-iscsi/lib/udev/rules.d/
49 cp -p debian/open-iscsi.rules debian/open-iscsi/lib/udev/rules.d/70-open-iscsi.rules55 cp -p debian/open-iscsi.rules debian/open-iscsi/lib/udev/rules.d/70-open-iscsi.rules
56 cp -p debian/iscsi-network-interface.rules debian/open-iscsi/lib/udev/rules.d/70-iscsi-network-interface.rules
5057
51 @# iscsiuio58 @# iscsiuio
52 dh_install -p iscsiuio iscsiuio/src/unix/iscsiuio /sbin59 dh_install -p iscsiuio iscsiuio/src/unix/iscsiuio /sbin
@@ -64,17 +71,19 @@ override_dh_auto_install:
64 dh_install -p open-iscsi-udeb debian/open-iscsi-udeb.finish-install usr/lib/finish-install.d/10open-iscsi71 dh_install -p open-iscsi-udeb debian/open-iscsi-udeb.finish-install usr/lib/finish-install.d/10open-iscsi
6572
66override_dh_installinit:73override_dh_installinit:
67 dh_installinit -p open-iscsi --name=iscsid74 dh_installinit -p open-iscsi --no-start --no-enable --no-stop-on-upgrade --name=iscsid
68 dh_installinit -p open-iscsi75 dh_installinit -p open-iscsi --no-start --no-enable --no-stop-on-upgrade
69 dh_installinit -p iscsiuio76 dh_installinit -p iscsiuio --no-start --no-enable --no-stop-on-upgrade
7077
71override_dh_systemd_enable:78override_dh_systemd_enable:
72 dh_systemd_enable -p open-iscsi --name=iscsid79 dh_systemd_enable -p open-iscsi --name=iscsid --no-enable iscsid.service
73 dh_systemd_enable -p open-iscsi80 dh_systemd_enable -p open-iscsi --name=iscsid iscsid.socket
81 dh_systemd_enable -p open-iscsi open-iscsi.service
74 dh_systemd_enable -p iscsiuio82 dh_systemd_enable -p iscsiuio
7583
76override_dh_systemd_start:84override_dh_systemd_start:
77 dh_systemd_start -p open-iscsi --no-restart-on-upgrade iscsid.service open-iscsi.service85 dh_systemd_start -p open-iscsi --no-restart-on-upgrade iscsid.socket
86 dh_systemd_start -p open-iscsi --no-restart-on-upgrade open-iscsi.service
78 dh_systemd_start -p iscsiuio --no-restart-on-upgrade iscsiuio.service87 dh_systemd_start -p iscsiuio --no-restart-on-upgrade iscsiuio.service
7988
80override_dh_installman:89override_dh_installman:
@@ -85,8 +94,19 @@ override_dh_installman:
85override_dh_installdocs:94override_dh_installdocs:
86 dh_installdocs -p open-iscsi README sysfs-documentation THANKS95 dh_installdocs -p open-iscsi README sysfs-documentation THANKS
87 dh_installdocs -p iscsiuio iscsiuio/RELEASE.TXT iscsiuio/README96 dh_installdocs -p iscsiuio iscsiuio/RELEASE.TXT iscsiuio/README
88 dh_installdocs -p libopeniscsiusr ./libopeniscsiusr/docs/doc-preclean.pl ./libopeniscsiusr/docs/kernel-doc ./libopeniscsiusr/docs/libopeniscsiusr.h.3 ./libopeniscsiusr/docs/split-man.pl97 dh_installdocs -p libopeniscsiusr0.2.0 ./libopeniscsiusr/docs/doc-preclean.pl ./libopeniscsiusr/docs/kernel-doc ./libopeniscsiusr/docs/libopeniscsiusr.h.3 ./libopeniscsiusr/docs/split-man.pl
89 dh_installdocs -p libopeniscsiusr-dev98 dh_installdocs -p libopeniscsiusr-dev
9099
91override_dh_missing:100override_dh_missing:
92 dh_missing --fail-missing101 dh_missing --fail-missing
102
103# The following is taken from the initramfs-tools package. (We recommend
104# busybox in the initramfs because otherwise we don't have access to the
105# ip utility to set the default gateway after iscsistart -N is done.)
106# On Debian we can use either busybox or busybox-static, but on Ubuntu
107# and derivatives only busybox-initramfs will work.
108BUSYBOX_PACKAGES := $(shell if dpkg-vendor --derives-from ubuntu; then echo busybox-initramfs; else echo busybox busybox-static; fi)
109
110override_dh_gencontrol:
111 echo >> debian/open-iscsi.substvars "busybox:Recommends=$(wordlist 2,100,$(BUSYBOX_PACKAGES:%=| %))"
112 dh_gencontrol
diff --git a/debian/tests/README-boot-test.md b/debian/tests/README-boot-test.md
93new file mode 100644113new file mode 100644
index 0000000..e45bbf0
--- /dev/null
+++ b/debian/tests/README-boot-test.md
@@ -0,0 +1,139 @@
1## open-iscsi boot test
2The purpose of this test (`CloudImageTest`) is to test the boot of a system
3using an iscsi root target. In order to accomplish that, the tests does
4
5 1. Download Ubuntu cloud image
6 2. installs the open-iscsi deb inside
7 3. collect kernel and initramfs from inside
8 4. register the image as a read-only iscsi target served by tgt
9 5. boot kernel and initramfs with a command line to use the image as root.
10 And additionally attach a local disk for collecting output.
11 6. provide user-data that executes commands, colects files and writes them
12 to the output disk and then shuts the system down.
13 7. extract the collected files from the output disk and inspect them.
14
15The `CloudImageTest` uses qemu user networking.
16
17
18## Caveats
19
20 1. It depends on a cloud-image being present.
21
22 Cloud-images are often not available for the first few weeks of a cycle.
23 If no cloud-image of 'REL' is available, then boot-test will skip.
24 If 'REL' is not known in distro-info-data, then test will fail.
25
26 This means that uploads of open-iscsi (or its dependencies) will not
27 be properly tested until a cloud-image is available, and will fail
28 until distro-info-data is uploaded.
29
30 2. Installation of large packages via patch-image may fail.
31 An ubuntu image downloaded has only a small amount of extra space.
32 Installation of a new kernel into the target would probably fail.
33
34 If this becomes a problem, we could grow the disk like done at
35 https://gist.github.com/smoser/6a048a0e2795b48221fc44962202fa14
36
37
38### testing manually ###
39The test case in `debian/tests/test-open-iscsi.py` uses some helper tools.
40
41 * **patch-image**: this is used to install packages into the pristine image
42 and collect the kernel and initramfs out of the image. This allows us to
43 test the portions of open-iscsi that update the initramfs. Without
44 using the updated initramfs we wouldn't really be testing the new
45 open-iscsi.
46
47 It will upgrade any packages inside that are mentioned in
48 ADT_TEST_TRIGGERS environment. It will also install open-iscsi if
49 it is not in that list.
50
51 It installs packages into the target by copying the host system's
52 /etc/apt content in, and also includes copying local (file://) apt
53 repos into the target. This is necessary for the autopackage test
54 environment that adds local package repositories to sources.list.d.
55
56 It may also make other changes to the image to workaround bugs.
57 See --help output for list of bugs.
58
59 * **get-image**: This downloads an image from cloud-images.ubuntu.com. See
60 its Usage for more information. it downloads via stream data and verifies
61 download. One thing to note is that it does not overwrite existing files.
62
63 * **tgt-boot-test**: this registers an image in tgt locally, and then boots
64 kernel and initramfs to mount that. It knows how to build iscsi kernel
65 command lines.
66
67 By default, the xkvm process that is started will be allowed `60m` to
68 complete. This can be adjusted by setting `BOOT_TIMEOUT` in the
69 environment.
70
71 * **xkvm**: this is a helper/wrapper around qemu. It is taken from the curtin
72 projects tools/ directory. It allows some simplified command lines, and
73 most usefully, the '--netdev=<bridge>' argument will create a tun/tap
74 device and attach it to the bridge.
75
76 If the host system is not bare metal, kvm will not be
77 enabled in the guest that is lauched. To force use of kvm, set
78 _USE_KVM=1 in the environment. See 'should_try_kvm' in xkvm for details.
79
80Testing manually looks like this:
81
82 ## set up path to include debian/tests directory.
83 $ PATH=$PWD/debian/tests:$PATH
84
85 ## Get the image you want. This creates out.d/disk.img and disk.img.dist
86 $ get-image xenial.d xenial
87
88 ## patch the image with an open-iscsi, which creates xenial.d/kernel
89 ## and xenial.d/initrd from the kernel and initramfs inside the image.
90 $ apt-get download open-iscsi
91 $ deb=$(ls open-iscsi_*.deb | tail -n 1)
92 $ sudo ./debian/tests/patch-image \
93 --kernel=xenial.d/kernel --initrd=xenial.d/initrd
94 xenial.d/disk.img "$deb"
95
96 ## Boot the system, log in, look around.
97 $ tgt-boot-test -v xenial.d/disk.img xenial.d/kernel xenial.d/initrd
98
99
100### Features of tgt-boot-test ###
101
102tgt-boot-test does a number of useful things.
103
104 * determines the host address that the guest will use.
105 This should support ipv6 and ipv4 addresses on bridges, and
106 knows values that qemu's user networking uses. Flags passed to `--netdev`
107 are read intelligently. This can be overriden with `--host-addr`, but
108 it does a good job of determining what the right values are.
109
110 * provides a nocloud metadata service with a python web server that
111 supports ipv4 and ipv6.
112
113 * provides the ability to provide additional kernel command line options
114 or to provide a 'template' that references variables it knows such as
115 {iserver} (iscsi server) or {seed_url}.
116
117 * Sets ubuntu (passw0rd) and root password (root) and imports users
118 ssh keys to the ubuntu user.
119
120One thing to note is that yakkety's version of qemu does not run an ipv6
121dhcp server on its user-network, so a stateful dhclient request will not
122work.
123
124In order to create a bridge easily with a ipv6 dhcp server, you can use
125lxd at sufficent version (https://github.com/lxc/lxd/issues/2481).
126Assuming that bug is fixed, to create an ipv6 only bridge:
127
128 $ netname="ipv6-only"
129 $ lxc network create $netname
130 $ lxc network unset $netname ipv4.address
131 $ lxc network unset $netname ipv4.nat
132 $ lxc network set $netname ipv6.dhcp.stateful true
133
134Then, you can use tgt-boot-test with that:
135
136 $ PATH=$PWD/debian/tests:$PATH
137 $ ./debian/tests/tgt-boot-test -vv --netdev=ipv6-only \
138 --cmdline-ip="ip=off ip6=dhcp" \
139 disk.img kernel initramfs
diff --git a/debian/tests/control b/debian/tests/control
index 7b3c9e2..026cfc9 100644
--- a/debian/tests/control
+++ b/debian/tests/control
@@ -1,6 +1,10 @@
1Tests: install1Tests: install
2Restrictions: needs-root, isolation-machine, breaks-testbed2Restrictions: needs-root, isolation-machine, breaks-testbed
33
4Tests: testsuite
5Restrictions: needs-root isolation-machine breaks-testbed
6Depends: open-iscsi, python2, tgt, qemu-system, ubuntu-cloudimage-keyring, simplestreams, python-netifaces, distro-info, cloud-image-utils, dctrl-tools, rsync
7
4Tests: nested8Tests: nested
5Restrictions: needs-root, isolation-machine, breaks-testbed, allow-stderr9Restrictions: needs-root, isolation-machine, breaks-testbed, allow-stderr
6Depends: targetcli-fb, qemu-system, qemu-utils, python3, python3-netifaces10Depends: targetcli-fb, qemu-system, qemu-utils, python3, python3-netifaces
diff --git a/debian/tests/get-image b/debian/tests/get-image
7new file mode 10075511new file mode 100755
index 0000000..41b903c
--- /dev/null
+++ b/debian/tests/get-image
@@ -0,0 +1,227 @@
1#!/bin/bash
2Usage() {
3 cat <<EOF
4${0##*/} out-directory release
5
6By default, the cloud image for 'release' is downloaded from the
7daily cloud image stream.
8
9Additional arguments can change behavior of what is downloaded.
10Some supported arguments:
11 * cloud-daily: use daily stream [default]
12 * cloud-release: use release stream rather than daily stream.
13 * maas-release, maas-daily: download maas images instead of cloud-image
14 * hwe-N: download the hwe kernel from release 'N' instead of default
15 this is only respected if maas stream is used.
16 * YYYYMMDD[.X] : download the specific build version
17
18example:
19 ${0##*/} xenial_dir xenial cloud-daily
20EOF
21}
22TEMP_D=""
23
24NO_IMAGE_AVAILABLE_RC=3
25
26cleanup() {
27 [ ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
28}
29VERBOSITY=1
30inargs() {
31 local n=$1 x="";
32 shift;
33 for x in "$@"; do [ "$n" = "$x" ] && return 0; done;
34 return 1
35}
36debug() { [ $1 -ge $VERBOSITY ] || return 0; shift; echo "$@" 1>&2; }
37error() { echo "$@" 1>&2; }
38fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
39
40VERBOSITY=0
41TEMP_D=$(mktemp -d ${TMPDIR:-/tmp}/${0##*/}.XXXXXX) || exit 1
42trap cleanup EXIT
43
44arches=( ppc64el i386 amd64 )
45releases=( $(ubuntu-distro-info --all) )
46mbase="http://maas.ubuntu.com/images/ephemeral-v2"
47cbase="http://cloud-images.ubuntu.com"
48def_stream_type="cloud"
49stream_src=""
50curbase="$mbase"
51def_rel="xenial"
52vername=""
53
54[ "$1" = "-h" -o "$1" = "--help" ] && { Usage; exit 0; }
55[ $# -lt 2 ] && { Usage 1>&2; exit 1; }
56out_d="$1"
57shift
58
59myarch=$(uname -m)
60case "$myarch" in
61 ppc64*) def_arch="ppc64el";;
62 i?86) def_arch="i386";;
63 x86_64) def_arch="amd64";;
64 arm*) def_arch="armel";;
65esac
66
67pt=( )
68for x in "$@"; do
69 inargs "$x" "${arches[@]}" && pt[${#pt[@]}]=arch=$x && arch="$x" && continue
70 inargs "$x" "${releases[@]}" && pt[${#pt[@]}]="release=$x" && release=$x && continue
71 [ "$x" = "released" -o "$x" = "release" ] && x="releases"
72 case "$x" in
73 cloud-released|cloud-release) x="cloud-releases";;
74 maas-released|maas-release) x="maas-releases";;
75 esac
76
77 case "$x" in
78 maas|cloud) stream_type="$x";;
79 cloud-daily|maas-daily|cloud-releases|maas-releases)
80 stream_type="${x%-*}"
81 stream_sub=${x#*-};;
82 http://*) stream=$x;;
83 hwe-*) subarch="$x";;
84 subarch=*) subarch=${x#*=};;
85 *=*) pt[${#pt[@]}]="$x";;
86 *~*) pt[${#pt[@]}]="$x";;
87 [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])
88 pt[${#pt[@]}]="version_name=$x"
89 vername="$x";;
90 *) fail "Confused by input token '$x'";;
91 esac
92done
93
94[ -n "$stream_type" ] || stream_type="${def_stream_type}"
95if [ -z "$stream" ]; then
96 stream_sub=${stream_sub:-daily}
97 case "$stream_type" in
98 maas) stream="$mbase/$stream_sub";;
99 cloud) stream="$cbase/$stream_sub";;
100 *) fail "unknown stream_type '$stream_type'";;
101 esac
102fi
103
104[ -n "$arch" ] || pt[${#pt[@]}]="arch=$def_arch"
105
106if [ "$stream_type" = "maas" ]; then
107 if [ -z "$subarch" ]; then
108 t=${release#?}
109 first_letter=${release%${t}}
110 subarch="hwe-${first_letter}"
111 error "selected subarch=${subarch} for $release"
112 fi
113 pt[${#pt[@]}]="subarch=$subarch"
114 ofmt="%(sha256)s %(ftype)s %(subarch)s %(item_url)s"
115else
116 ofmt="%(sha256)s %(ftype)s %(item_url)s"
117fi
118
119OIFS="$IFS"
120mkdir -p "$out_d"
121case "$stream" in
122 *.json) :;;
123 *) keyring="/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg";;
124esac
125
126needs=""
127[ -n "$keyring" -a ! -f "$keyring" ] &&
128 needs="${needs} ubuntu-cloudimage-keyring"
129
130for pair in sstream-query:simplestreams tgt-admin:tgt; do
131 cmd=${pair%:*}
132 pkg=${pair#*:}
133 command -v "$cmd" >/dev/null 2>&1 || needs="$needs $pkg"
134done
135
136if [ -n "${needs# }" ]; then
137 error "missing dependencies"
138 fail "sudo apt-get install -qy ${needs# }"
139fi
140
141qcmd=( sstream-query ${keyring:+"--keyring=$keyring"} ${vername:---max=1}
142 --output-format="$ofmt" "${stream}" datatype="image-downloads"
143 "${pt[@]}" )
144echo "${qcmd[@]}"
145"${qcmd[@]}" > "${TEMP_D}/qout"
146roots=$(awk '$2 == "root-image.gz" || $2 == "disk1.img" { print $2 }' \
147 "${TEMP_D}/qout" | sort -u | wc -l)
148if [ "$roots" = "0" ]; then
149 error "No image available for $release in $stream${pt:+ (${pt[*]})}"
150 exit ${NO_IMAGE_AVAILABLE_RC}
151elif [ "$roots" != "1" ]; then
152 error "query resulted in '$roots' root images. expect 1 and only 1"
153 error "cmd was ${qcmd[*]}"
154 cat "${TEMP_D}/qout"
155 fail
156fi
157
158set -f
159while read line; do
160 set -- $line
161 if [ "$stream_type" = "maas" ]; then
162 sha256="$1"; ftype="$2"; subarch="$3"; url="$4"
163 else
164 sha256="$1"; ftype="$2"; url="$3"
165 fi
166 case "$ftype" in
167 boot-kernel|boot-initrd|root-image.gz|disk1.img) :;;
168 *) continue
169 esac
170 if [ "$ftype" = "root-image.gz" ]; then
171 fname="$ftype"
172 image_src="$out_d/$fname"
173 image="$out_d/root-image"
174 elif [ "$ftype" = "disk1.img" ]; then
175 fname="disk.img.dist"
176 image_src="$out_d/$fname"
177 image="$out_d/disk.img"
178 else
179 fname="$subarch/$ftype"
180 fi
181 out_f="${out_d}/$fname"
182 if [ -f "$out_f" ]; then
183 debug 1 "reusing existing '$out_f' rather than downloading $url."
184 continue
185 fi
186 [ -d "${out_f%/*}" ] || mkdir -p "${out_f%/*}"
187 tmp="${out_f}.tmp"
188 wget --progress=dot:mega -O "$tmp" "$url" || {
189 error "Failed to download $url to $tmp."
190 rm -f "$tmp"
191 exit 3
192 }
193 debug 1 "checksumming $tmp from $url"
194 out=$(sha256sum "$tmp") || {
195 error "Failed to checksum $tmp"
196 rm -f "$tmp"
197 exit 3;
198 }
199 found=${out% *}
200 if [ "$found" != "$sha256" ]; then
201 error "$tmp from $url found sha256 of $found. expected $sha256."
202 ls -l "$tmp" 1>&2
203 rm -f "$tmp"
204 exit 3
205 fi
206 mv "$tmp" "$out_f" || fail "failed renaming $tmp to $out_f"
207 echo "$fname" "$url" >> "$out_d/contents"
208done < "${TEMP_D}/qout"
209
210if [ ! -f "$image" ]; then
211 case "$image_src" in
212 */root-image.gz)
213 debug 1 "decompressing $image_src"
214 zcat "$image_src" > "$image.tmp" &&
215 mv "$image.tmp" "$image" ||
216 { rm -f "$image.tmp"; exit 1; }
217 ;;
218 */disk.img.dist)
219 debug 1 "converting qcow2 in $image_src -> raw in $image"
220 qemu-img convert -O raw "$image_src" "$image.tmp" &&
221 mv "$image.tmp" "$image" ||
222 { rm -f "$image.tmp"; exit 1; }
223 ;;
224 esac
225fi
226
227# vi: ts=4 expandtab
diff --git a/debian/tests/install b/debian/tests/install
index ae2fe79..5077b7b 100755
--- a/debian/tests/install
+++ b/debian/tests/install
@@ -28,5 +28,8 @@ grep -vq '^GenerateName=yes' /etc/iscsi/initiatorname.iscsi || die_with_file /et
28grep -q '^InitiatorName=' /etc/iscsi/initiatorname.iscsi || die_with_file /etc/iscsi/initiatorname.iscsi "InitiatorName is not set"28grep -q '^InitiatorName=' /etc/iscsi/initiatorname.iscsi || die_with_file /etc/iscsi/initiatorname.iscsi "InitiatorName is not set"
2929
30# Make sure the daemon is started30# Make sure the daemon is started
31service iscsid status || die "iscsid not running"31systemctl is-active iscsid.socket || die "iscsid socket not running"
32pgrep -c iscsid >/dev/null || die "iscsid not running"32# no-op discovery to socket activate service
33iscsiadm -m discovery -t sendtargets -p 127.0.0.1 >/dev/null 2>&1|| /bin/true
34systemctl is-active iscsid.service || die "iscsid service not running"
35pgrep -c iscsid >/dev/null || die "iscsid process not running"
diff --git a/debian/tests/patch-image b/debian/tests/patch-image
33new file mode 10075536new file mode 100755
index 0000000..0688912
--- /dev/null
+++ b/debian/tests/patch-image
@@ -0,0 +1,374 @@
1#!/bin/bash
2
3VERBOSITY=1
4TEMP_D=""
5
6error() { echo "$@" 1>&2; }
7fail() { local r=$?; [ $r -eq 0 ] && r=1; failrc "$r" "$@"; }
8failrc() { local r=$1; shift; [ $# -eq 0 ] || error "$@"; exit $r; }
9
10Usage() {
11 cat <<EOF
12Usage: ${0##*/} [options] image [packages]
13 Patch image, upgrading [packages].
14 --kernel FILE copy kernel out to FILE
15 --initrd FILE copy initrd out to FILE
16
17 --krd-only only copy out kernel/initrd do not change image.
18 this is incompatible with 'packages'
19 it is a short-cut to specifying all the '--no-*'
20 options below.
21
22 --no-copy-apt do not copy host's apt repos in.
23
24 image modifications:
25 --no-update-fstab do not modify fstab (LP: #1732028)
26
27 if no packages are provided, and ADT_TEST_TRIGGERS is set
28 in environment, then it will be read for the list of packages.
29 to override that behavior pass package 'none'.
30EOF
31
32}
33
34bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
35cleanup() {
36 [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
37}
38
39debug() {
40 local level=${1}; shift;
41 [ "${level}" -gt "${VERBOSITY}" ] && return
42 error "${@}"
43}
44
45adt_test_triggers_to_bin_pkgs() {
46 # ADT_TEST_TRIGGERS is space delimited <src>/version
47 # returns a scalar '_RET', caller has to expand
48 local tok src="" ver="" binpkgs=""
49 for tok in "$@"; do
50 src=${tok%/*}
51 ver=${tok#*/}
52 bin_packages_from_source_pkg "$src" "$ver" || return
53 if [ -z "${_RET}" ]; then
54 error "$tok: (source=$src ver=$ver) No packages available!"
55 return 1
56 fi
57 binpkgs="${binpkgs} ${_RET}"
58 done
59 _RET=${binpkgs# }
60}
61
62bin_packages_from_source_pkg() {
63 local pkg=$1 ver=${2} cmd="" out="" p="" ret=""
64 if ! command -v grep-aptavail >/dev/null; then
65 error "No command grep-aptavail: apt-get install dctrl-tools"
66 return 1
67 fi
68 cmd=( grep-aptavail --show-field=Package
69 --exact-match --field=Source:Package "$pkg" )
70 if [ -n "$ver" ]; then
71 cmd=( "${cmd[@]}" --and --field=Version "$ver" )
72 fi
73 out=$("${cmd[@]}" | sed 's,Package: ,,')
74 ret=""
75 for p in $out; do
76 ret="$ret ${p#Package: }${ver:+=${ver}}"
77 done
78 # if no version was provided, we could have multiple results
79 _RET=$(set -f; for i in ${ret}; do echo "$i"; done | sort -u)
80}
81
82update_fstab() {
83 # update_fstab(path) modify the fstab at path
84 # to remove problematic entries (LP: #1732028)
85 local fstab="$1"
86 if [ ! -e "$fstab.patch-image-dist" ]; then
87 cp "$fstab" "$fstab.patch-image-dist" ||
88 { error "failed backing up $fstab to $fstab.dist"; return 1; }
89 fi
90 sed -i '/^LABEL=UEFI/s/^/#/' "$fstab"
91}
92
93cat_debug_script() {
94 cat <<"EOF"
95#!/bin/sh
96set -f
97NAME=${1:-debug-pid-$$}
98[ "$(id -u)" = "0" ] && log="/run/${NAME}.log" || log="/tmp/${NAME}.log"
99
100msg() {
101 echo "===" "$@" "===" 1>&2
102}
103showcmd() {
104 msg "showcmd$" "$@"
105 "$@"
106}
107
108main() {
109 issues=$(journalctl | egrep "[.]mount: ")
110 if [ -z "$issues" ]; then
111 msg "$NAME:" "MOUNT ISSUES FOUND: NO"
112 else
113 msg "$NAME:" "MOUNT ISSUES FOUND: YES"
114 fi
115 showcmd systemctl list-units --no-pager --all --full "*.mount"
116 showcmd systemctl cat --no-pager --all --full "*.mount"
117 showcmd systemctl status --no-pager --all --full "*.mount"
118 showcmd cat /etc/fstab
119 showcmd cat /proc/1/mountinfo
120}
121
122main > "$log" 2>&1
123echo "============ $NAME ============="
124cat "$log"
125EOF
126}
127
128add_systemd_job() {
129 local target="$1" name="$2" after="$3" start="$4"
130 local spath="lib/systemd/system/xdebug-$name.service"
131 debug 1 "writing $name to $target/$spath"
132 cat > "$target/$spath" <<EOF
133[Unit]
134Description=Execute xdebug ${name}
135After=${after}
136
137[Service]
138Type=oneshot
139ExecStart=${start} ${name}
140RemainAfterExit=yes
141StandardOutput=journal+console
142
143[Install]
144WantedBy=multi-user.target
145EOF
146 [ $? -eq 0 ] || { error "failed writing $target/$spath"; return 1; }
147 local wantsdir="$target/etc/systemd/system/multi-user.target.wants"
148 ln -s "/$spath" "$wantsdir/" ||
149 { error "failed ln -s '/$spath' '$wantsdir/'"; return 1; }
150}
151
152insert_debug_1788188() {
153 # This is an attempt to collect more debug information in the
154 # event that the tests trigger LP: #1788188.
155 local target="$1"
156 [ "$target" = "/" -o -z "$target" ] &&
157 { error "target was / in insert_debug"; return 1; }
158 local script="usr/local/bin/debug-mounts"
159 cat_debug_script > "$target/$script" &&
160 chmod 755 "$target/$script" ||
161 { error "failed writing $target/script"; return 1; }
162 local name=""
163 ( set +f;
164 rm -f "$target/lib/systemd/system/xdebug"-*.service \
165 "$target/etc/systemd/system/"*.wants/xdebug*.service )
166 add_systemd_job "$target" network network-online.target "/$script" &&
167 add_systemd_job "$target" local-fs local-fs.target "/$script" ||
168 { error "failed adding systemd jobs"; return 1; }
169}
170
171main() {
172 local short_opts="hv"
173 local long_opts="help,no-copy-apt,initrd:,kernel:,verbose"
174 local getopt_out="" orig_args=""
175 orig_args=( "$@" )
176 getopt_out=$(getopt --name "${0##*/}" \
177 --options "${short_opts}" --long "${long_opts}" -- "$@") &&
178 eval set -- "${getopt_out}" ||
179 { bad_Usage; return; }
180
181 local cur="" next=""
182 local kernel="" initrd="" copy_apt=true krd_only=false
183 local update_fstab=true
184
185 while [ $# -ne 0 ]; do
186 cur="$1"; next="$2";
187 case "$cur" in
188 -h|--help) Usage ; exit 0;;
189 --krd-only) krd_only=true; shift;;
190 --no-copy-apt) copy_apt=false; shift;;
191 --no-update-fstab) update_fstab=false; shift;;
192 --kernel) kernel=$next; shift;;
193 --initrd) initrd=$next; shift;;
194 -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
195 --) shift; break;;
196 esac
197 shift;
198 done
199
200 [ $# -ne 0 ] || { bad_Usage "must provide at least image"; return; }
201
202 [ "$(id -u)" = "0" ] || fail "not root"
203 target="$1"
204 shift
205 if [ -f "$target" ]; then
206 local nargs=""
207 nargs=( "${orig_args[@]}" )
208 # replace the first occurance of target in orig args with _MOUNTPOINT_
209 for((i=0;i<${#nargs[@]};i++)); do
210 [ "${nargs[$i]}" = "$target" ] && nargs[$i]=_MOUNTPOINT_ && break
211 done
212 debug 1 "mic $target -- $0 ${nargs[*]}"
213 IMAGE="$target" exec mount-image-callback \
214 --system-resolvconf "$target" -- "$0" "${nargs[@]}"
215 fi
216
217 if [ ! -d "$target" ]; then
218 fail "$target: not a directory or file"
219 fi
220
221 local tsrc=${IMAGE:-${target}}
222 local packages=( )
223 packages=( "$@" )
224
225 if $krd_only; then
226 if [ "${#packages[@]}" != 0 -a "${packages[*]}" != "none" ]; then
227 error "--krd-only is incompatible with packages."
228 return 1
229 fi
230 debug 1 "--krd-only provided no changes will be done."
231 copy_apt=false
232 update_fstab=false
233 packages=( "none" )
234 fi
235
236 if [ "${#packages[@]}" = "1" -a "${packages[0]}" = "none" ]; then
237 packages=( )
238 elif [ "${#packages[@]}" -eq 0 -a -n "${ADT_TEST_TRIGGERS}" ]; then
239 adt_test_triggers_to_bin_pkgs ${ADT_TEST_TRIGGERS} ||
240 fail "failed to find binary packages " \
241 "from ADT_TEST_TRIGGERS=$ADT_TEST_TRIGGERS"
242 packages=( $_RET )
243 debug 1 "read ADT_TEST_TRIGGERS=$ADT_TEST_TRIGGERS to set" \
244 "packages=${packages[*]}"
245 else
246 local opackages="" debs="" pkg=""
247 opackages=( "${packages[@]}" )
248 packages=( )
249 debs=( )
250 for pkg in "${opackages[@]}"; do
251 [ -f "${pkg}" ] && debs[${#debs[@]}]="$pkg" ||
252 packages[${packages[@]}]="$pkg"
253 done
254 if [ "${#packages[@]}" -eq 0 -a "${#debs[@]}" -eq 0 ]; then
255 packages=( open-iscsi )
256 debug 1 "no packages or debs given, using packages=${packages[*]}"
257 fi
258 fi
259
260 # if open-iscsi is not in the packages list above, we handle it specifically
261 # so that even if the image did not have open-iscsi, it will get it.
262 local pkg="" mypkg="open-iscsi"
263 for pkg in "${packages[@]}"; do
264 case "$pkg" in
265 open-iscsi|open-iscsi/*) mypkg="none";;
266 esac
267 done
268
269 TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
270 fail "failed to make tempdir"
271 trap cleanup EXIT
272
273 if $copy_apt; then
274 local distdir="${target}/etc/apt.dist.${0##*/}"
275 if [ ! -d "$distdir" ]; then
276 mv "$target/etc/apt" "$distdir" ||
277 fail "failed to backup /etc/apt in $tsrc"
278 fi
279 cp -a /etc/apt "$target/etc/" ||
280 fail "failed to replace /etc/apt in $tsrc"
281
282 # find file:// repos in apt sources and copy them in
283 local file_repos=""
284 file_repos=$(
285 fm='s,.*[[:space:]]file:///*\([^[[:space:]]*\).*,/\1,p'
286 shopt -s nullglob
287 for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.list; do
288 sed -n -e 's/#.*//' -e "$fm" "$f"
289 done
290 )
291 local dir="" bdir="" tdir=""
292 for dir in ${file_repos}; do
293 tdir="${target}$(dirname $dir)/$(basename ${dir})"
294 if [ -d "$dir" ]; then
295 debug 1 "copying $dir -> $tdir"
296 mkdir -p "$tdir" ||
297 fail "failed to create $tdir"
298 rsync --delete -a "$dir/" "$tdir" ||
299 fail "failed copy from $dir/ to $tdir"
300 fi
301 done
302 fi
303
304 if $update_fstab; then
305 update_fstab "$target/etc/fstab" ||
306 { error "failed updating /etc/fstab in target"; return 1; }
307 fi
308
309 insert_debug_1788188 "$target" || return 1
310
311 mount -o bind /sys "$target"/sys || :
312 mount -o bind /proc "$target"/proc || :
313 mount -o bind /dev "$target"/dev || :
314 mount -o bind /dev/pts "$target"/dev/pts || :
315
316 debug 1 "${#packages[@]} packages: ${packages[*]}"
317 if [ "${#packages[@]}" != "0" ]; then
318 DEBIAN_FRONTEND=noninteractive chroot "$target" sh -exc '
319 mypkg=$1
320 shift
321 apt-get update -q
322 if [ "$mypkg" != "none" ]; then
323 apt-get install -qy "$mypkg"
324 fi
325 apt-get install -qy --only-upgrade "$@"' \
326 chroot-inst "$mypkg" "${packages[@]}" ||
327 fail "failed to install ${packages[*]} in $target"
328 fi
329
330 debug 1 "${#debs[@]} debs: ${debs[*]}"
331 if [ "${#debs[@]}" != "0" ]; then
332 local tmpd=""
333 tmpd=$(mktemp -d "${target}/tmp/${0##*/}.XXXXXX")
334 cp "${debs[@]}" "$tmpd"
335 DEBIAN_FRONTEND=noninteractive chroot "$target" sh -exc \
336 'cd "$1"; shift; dpkg -i *.deb' debinstalls "${tmpd#${target}}"
337 rm -Rf "${tmpd}"
338 fi
339
340 umount "$target"/dev/pts || :
341 umount "$target"/dev || :
342 umount "$target"/proc || :
343 umount "$target"/sys || :
344
345 local kpath="" ipath=""
346 for f in "$target/boot/"*; do
347 case "${f##*/}" in
348 *.signed) continue;;
349 vmlinu?-*) kpath="$f";;
350 initrd.img-*) ipath="$f";;
351 esac
352 done
353
354 if [ -n "$kernel" ]; then
355 [ -n "$kpath" ] || fail "unable to find kernel in $tsrc"
356 debug 1 "using kernel ${kpath#${target}}"
357 cp "$kpath" "$kernel" ||
358 fail "failed copy $kpath to $kernel"
359 [ -z "$IMAGE" ] || chown "--reference=$IMAGE" "$kernel"
360 fi
361
362 if [ -n "$initrd" ]; then
363 [ -n "$ipath" ] || fail "unable to find initrd in $tsrc"
364 debug 1 "using initrd ${ipath#${target}}"
365 cp "$ipath" "$initrd" ||
366 fail "failed copy $ipath to $initrd"
367 [ -z "$IMAGE" ] || chown "--reference=$IMAGE" "$initrd"
368 fi
369
370}
371
372main "$@"
373
374# vi: ts=4 expandtab
diff --git a/debian/tests/test-open-iscsi.py b/debian/tests/test-open-iscsi.py
0new file mode 100644375new file mode 100644
index 0000000..cce02fb
--- /dev/null
+++ b/debian/tests/test-open-iscsi.py
@@ -0,0 +1,426 @@
1#!/usr/bin/python2
2#
3# test-open-iscsi.py quality assurance test script for open-iscsi
4# Copyright (C) 2011 Canonical Ltd.
5# Author: Jamie Strandboge <jamie@canonical.com>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 3,
9# as published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#
19# packages required for test to run:
20# QRT-Packages: open-iscsi
21# packages where more than one package can satisfy a runtime requirement:
22# QRT-Alternates:
23# files and directories required for the test to run:
24# QRT-Depends:
25# privilege required for the test to run (remove line if running as user is okay):
26# QRT-Privilege: root
27
28'''
29 In general, this test should be run in a virtual machine (VM) or possibly
30 a chroot and not on a production machine. While efforts are made to make
31 these tests non-destructive, there is no guarantee this script will not
32 alter the machine. You have been warned.
33
34 How to run in a clean VM:
35 $ sudo apt-get -y install python-unit <QRT-Packages> && sudo ./test-PKG.py -v'
36
37 How to run in a clean schroot named 'lucid':
38 $ schroot -c lucid -u root -- sh -c 'apt-get -y install python-unit <QRT-Packages> && ./test-PKG.py -v'
39
40
41 NOTES:
42 - currently only tested on Ubuntu 8.04
43'''
44
45
46from netifaces import gateways, AF_INET
47import unittest, subprocess, sys, os, glob
48import shutil
49import testlib
50import textwrap
51from tempfile import mkdtemp
52import time
53
54# There are setup based on README.multipurpose-vm. Feel free to override.
55remote_server = ''
56username = 'ubuntu'
57password = 'passwd'
58username_in = 'ubuntu'
59password_in = 'ubuntupasswd'
60initiatorname = 'iqn.2009-10.com.example.hardy-multi:iscsi-01'
61
62COLLECT_USER_DATA = """\
63#cloud-config
64bukket:
65 - &get_resolved_status |
66 if [ "${1:--}" != "-" ]; then
67 exec >"$1" 2>&1
68 fi
69 if ! command -v systemd-resolve >/dev/null 2>&1; then
70 echo "systemd-resolve: not available."
71 exit
72 fi
73 if ! ( systemd-resolve --help | grep -q -- --status ); then
74 echo "systemd-resolve: no --status."
75 exit
76 fi
77 systemd-resolve --status --no-pager
78
79 - &get_iscsid_status |
80 [ "${1:--}" != "-" ] && exec >"$1" 2>&1
81 udevadm settle
82 systemctl is-active iscsid.service
83 systemctl status --no-pager --full iscsid.service
84
85 - &add_and_remove_tuntap |
86 #!/bin/sh
87 # LP: #1785108 would break dns when any device was removed.
88 tapdev="mytap0"
89 echo ==== Adding $tapdev ====
90 ip tuntap add mode tap user root $tapdev
91 udevadm settle
92 echo ==== Removing $tapdev ====
93 ip tuntap del mode tap $tapdev
94 udevadm settle
95
96 - &collect_debug_mounts |
97 [ "${1:--}" != "-" ] && exec >"$1" 2>&1
98 [ -x /usr/local/bin/debug-mounts ] || exit 0
99 /usr/local/bin/debug-mounts
100
101runcmd:
102 - [ sh, -c, *add_and_remove_tuntap ]
103 - [ mkdir, -p, /output ]
104 - [ cp, /etc/resolv.conf, /output ]
105 - [ sh, -c, *get_resolved_status, --, /output/systemd-resolve-status.txt ]
106 - [ sh, -c, *get_iscsid_status, --, /output/iscsid-status.txt ]
107 - [ sh, -c, *collect_debug_mounts, --, /output/debug-mounts.txt ]
108 - [ sh, -c, 'journalctl --boot=0 --output=short-monotonic > /output/journal.txt' ]
109 - [ sh, -c, 'dpkg-query --show > /output/manifest.txt' ]
110 - [ tar, -C, /output, -cf, /dev/disk/by-id/virtio-output-disk, . ]
111
112power_state:
113 mode: poweroff
114 message: cloud-init finished. Shutting down.
115 timeout: 60
116"""
117
118try:
119 from private.qrt.OpenIscsi import PrivateOpenIscsiTest
120except ImportError:
121 class PrivateOpenIscsiTest(object):
122 '''Empty class'''
123 print >>sys.stdout, "Skipping private tests"
124
125class OpenIscsiTest(testlib.TestlibCase, PrivateOpenIscsiTest):
126 '''Test my thing.'''
127
128 def setUp(self):
129 '''Set up prior to each test_* function'''
130 self.pidfile = "/var/run/iscsid.pid"
131 self.exe = "/sbin/iscsid"
132 self.daemon = testlib.TestDaemon(["service", "open-iscsi"])
133 self.initiatorname_iscsi = '/etc/iscsi/initiatorname.iscsi'
134 self.iscsid_conf = '/etc/iscsi/iscsid.conf'
135
136 def tearDown(self):
137 '''Clean up after each test_* function'''
138 global remote_server
139 global initiatorname
140
141 # If remote server is setup, convert back to manual, logout, remove
142 # testlib configs and restart (in that order)
143 if remote_server != '':
144 testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--op=update', '--name', 'node.startup', '--value=manual'])
145 testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--op=update', '--name', 'node.conn[0].startup', '--value=manual'])
146 testlib.cmd(['iscsiadm', '-m', 'node', '--targetname', initiatorname, '-p', '%s:3260' % remote_server, '--logout'])
147
148 testlib.config_restore(self.initiatorname_iscsi)
149 testlib.config_restore(self.iscsid_conf)
150 self.daemon.restart()
151
152 def test_discovery_with_server(self):
153 '''Test iscsi_discovery to remote server'''
154 global remote_server
155 global username
156 global password
157 global username_in
158 global password_in
159 global initiatorname
160
161 if remote_server == '':
162 return self._skipped("--remote-server not specified")
163
164 contents = '''
165InitiatorName=%s
166InitiatorAlias=ubuntu
167''' % (initiatorname)
168 testlib.config_replace(self.initiatorname_iscsi, contents, True)
169
170 contents = '''
171node.session.auth.authmethod = CHAP
172node.session.auth.username = %s
173node.session.auth.password = %s
174node.session.auth.username_in = %s
175node.session.auth.password_in = %s
176
177discovery.sendtargets.auth.authmethod = CHAP
178discovery.sendtargets.auth.username = %s
179discovery.sendtargets.auth.password = %s
180discovery.sendtargets.auth.username_in = %s
181discovery.sendtargets.auth.password_in = %s
182''' % (username, password, username_in, password_in, username, password, username_in, password_in)
183 testlib.config_replace(self.iscsid_conf, contents, True)
184
185 self.assertTrue(self.daemon.restart())
186 time.sleep(2)
187 self.assertTrue(self.daemon.status()[0])
188
189 rc, report = testlib.cmd(["/sbin/iscsi_discovery", remote_server])
190 expected = 0
191 result = 'Got exit code %d, expected %d\n' % (rc, expected)
192 self.assertEquals(expected, rc, result + report)
193 for i in ['starting discovery to %s' % remote_server,
194 'Testing iser-login to target %s portal %s' % (initiatorname, remote_server),
195 'starting to test tcp-login to target %s portal %s' % (initiatorname, remote_server),
196 'discovered 1 targets at %s, connected to 1' % remote_server]:
197 result = "Could not find '%s' in report:\n" % i
198 self.assertTrue(i in report, result + report)
199
200 def test_net_interface_handler_execute_bit(self):
201 '''Test /lib/open-iscsi/net-interface-handler is executable.'''
202 nih_path = '/lib/open-iscsi/net-interface-handler'
203 self.assertTrue(os.access(nih_path, os.X_OK))
204
205class CloudImageTest(testlib.TestlibCase, PrivateOpenIscsiTest):
206 '''Test the cloud image can boot on iscsi root.
207
208 See README-boot-test.md for more information.
209 '''
210
211 @classmethod
212 def setUpClass(cls):
213 reason = (
214 "Skipped Cloud Image test on {arch}. whitelisted are: {whitelist}")
215 whitelisted = os.environ.get('WHITELIST_ARCHES', 'amd64').split(",")
216 curarch = testlib.manager.dpkg_arch
217 if testlib.manager.dpkg_arch not in whitelisted:
218 raise unittest.SkipTest(
219 reason.format(arch=curarch, whitelist=whitelisted))
220
221 here = os.path.dirname(os.path.abspath(__file__))
222 os.environ['PATH'] = "%s:%s" % (here, os.environ['PATH'])
223 release = os.environ.get(
224 "ISCSI_TEST_RELEASE", testlib.ubuntu_release())
225 image_d = os.path.join(here, '{}.d'.format(release))
226 # Download MAAS ephemeral image.
227 info = {'release': release,
228 'image_d': image_d,
229 'root_image': os.path.join(image_d, 'disk.img'),
230 'kernel': os.path.join(image_d, 'kernel'),
231 'initrd': os.path.join(image_d, 'initrd')}
232 try:
233 get_image(info['image_d'], release)
234 except subprocess.CalledProcessError as e:
235 if e.return_code != 3:
236 raise e
237 raise unittest.SkipTest(
238 "Cloud Image not available for release '%s'." % release)
239 if os.environ.get("NO_PATCH_IMAGE", "0") == "0":
240 patch_image(info['root_image'],
241 kernel=info['kernel'], initrd=info['initrd'])
242 cls.info = info
243 cls.here = here
244
245 def tearDown(self):
246 super(CloudImageTest, self).tearDown()
247 if os.path.exists(self.tmpdir):
248 shutil.rmtree(self.tmpdir)
249
250 def setUp(self):
251 super(CloudImageTest, self).setUp()
252 self.tmpdir = mkdtemp()
253 udp = os.path.join(self.tmpdir, 'user-data')
254 with open(udp, "w") as fp:
255 fp.write(COLLECT_USER_DATA)
256 self.info['user-data'] = udp
257
258 def create_output_disk(self):
259 path = os.path.join(self.tmpdir, 'output-disk.img')
260 subprocess.check_call([
261 'qemu-img', 'create', '-f', 'raw', path, '10M'])
262 return path
263
264 def extract_files(self, path):
265 # get contents in a dictionary of tarball at 'path'
266 tmpdir = mkdtemp()
267 try:
268 subprocess.check_call(['tar', '-C', tmpdir, '-xf', path])
269 flist = {}
270 prefix = len(tmpdir) + 1
271 for root, dirs, files in os.walk(tmpdir):
272 for fname in files:
273 fpath = os.path.join(root, fname)
274 key = fpath[prefix:]
275 with open(fpath, "r") as fp:
276 flist[key] = fp.read()
277 return flist
278 finally:
279 shutil.rmtree(tmpdir)
280
281 def test_tgt_boot(self):
282 tgt_boot_cmd = os.path.join(self.here, 'tgt-boot-test')
283 # Add self.here to PATH so xkvm will be available to tgt-boot-test
284 dns_addr = '10.1.1.4'
285 rel_dir = '{}.d'.format(self.info['release'])
286 dns_search = 'example.com'
287 info = {'host': '10.1.1.2', 'dns': dns_addr,
288 'dnssearch': dns_search, 'network': '10.1.1.0/24'}
289 netdev = ("--netdev=user,net={network},host={host},dns={dns},"
290 "dnssearch={dnssearch}").format(**info)
291
292 artifacts_dir = os.environ.get('AUTOPKGTEST_ARTIFACTS')
293 if artifacts_dir and not os.path.isdir(artifacts_dir):
294 os.makedirs(artifacts_dir)
295
296 output_disk = self.create_output_disk()
297 cmd = [
298 tgt_boot_cmd, '-v', netdev,
299 '--disk=%s,serial=output-disk' % output_disk,
300 '--user-data-add=%s' % self.info['user-data'],
301 self.info['root_image'], self.info['kernel'],
302 self.info['initrd']]
303 sys.stderr.write(' '.join(cmd) + "\n")
304
305 env = os.environ.copy()
306 env['BOOT_TIMEOUT'] = env.get('BOOT_TIMEOUT', '60m')
307 subprocess.check_call(cmd, env=env)
308
309 if artifacts_dir:
310 tgz = os.path.join(artifacts_dir, "tgt-collected.tar.gz")
311 shutil.copy(output_disk, tgz)
312 print("Copied output_disk '%s' to artifacts dir '%s'" %
313 (output_disk, tgz))
314
315 files = self.extract_files(output_disk)
316 print("collected files: %s" % files.keys())
317 resolvconf = files.get('resolv.conf', "NO_RESOLVCONF_FOUND")
318 resolve_status = files.get('systemd-resolve-status.txt')
319
320 resolvconf_id = 'generated by resolvconf'
321 resolved_addr = "127.0.0.53"
322 if resolvconf_id in resolvconf:
323 print("resolvconf manages resolvconf.\n")
324 self.assertIn(
325 dns_addr, resolvconf,
326 msg = ("%s not in resolvconf contents: \n%s" %
327 (dns_addr, resolvconf)))
328 if dns_search in resolvconf:
329 print("%s was found in resolv.conf." % dns_search)
330 elif resolved_addr in resolvconf and dns_search in resolve_status:
331 # zesty has resolvconf and systemd-resolved.
332 print("%s was in resolve_status and %s in resolv.conf" %
333 (resolved_addr, dns_search))
334 else:
335 raise AssertionError(
336 "%s domain is not being searched." % dns_search)
337
338 else:
339 print("systemd-resolved managing resolve.conf\n")
340 self.assertIn(
341 resolved_addr, resolvconf,
342 msg="%s not in resolved resolv.conf: %s" % (resolved_addr,
343 resolvconf))
344 self.assertIn(dns_addr, resolve_status,
345 msg=("%s not in systemd-resolve status: %s" %
346 (dns_addr, resolve_status)))
347 self.assertIn(dns_search, resolve_status,
348 msg=("search addr '%s' not in systemd-resolve status: %s" %
349 (dns_search, resolve_status)))
350
351 # iscsid-status.txt has first line output from
352 # 'systemctl is-active iscsid.service' and then 'systemcl status'
353 iscsid_status = files.get('iscsid-status.txt')
354 is_active = iscsid_status.splitlines()[0]
355 self.assertEqual(
356 "active", is_active,
357 msg=("Expected iscsid.service active, found '%s'.\n%s\n" %
358 (is_active, iscsid_status)))
359
360
361def get_image(top_d, release):
362 cmd = ['get-image', top_d, 'cloud-daily', release]
363 subprocess.check_call(cmd)
364
365
366def patch_image(image, packages=None, kernel=None, initrd=None):
367 '''Patch root-image with dep8 built open-iscsi package.'''
368
369 if packages is None:
370 # an empty 'packages' to patch-image still installs open-iscsi
371 packages = []
372
373 cmd = ['patch-image', image]
374 if kernel:
375 cmd.append('--kernel=%s' % kernel)
376 if initrd:
377 cmd.append('--initrd=%s' % initrd)
378 cmd.extend(packages)
379
380 subprocess.check_call(cmd)
381
382
383if __name__ == '__main__':
384 import optparse
385 parser = optparse.OptionParser()
386 parser.add_option("-v", "--verbose", dest="verbose", help="Verbose", action="store_true")
387 parser.add_option("-s", "--remote-server", dest="remote_server", help="Specify host with available iSCSI volumes", metavar="HOST")
388
389 parser.add_option("-n", "--initiatorname", dest="initiatorname", help="Specify initiatorname for use with --remote-server", metavar="NAME")
390
391 parser.add_option("--password", dest="password", help="Specify password for use with --remote-server", metavar="PASS")
392 parser.add_option("--password-in", dest="password_in", help="Specify password_in for use with --remote-server", metavar="PASS")
393
394 parser.add_option("--username", dest="username", help="Specify username for use with --remote-server", metavar="USER")
395 parser.add_option("--username-in", dest="username_in", help="Specify username_in for use with --remote-server", metavar="USER")
396
397 (options, args) = parser.parse_args()
398
399 if options.remote_server:
400 remote_server = options.remote_server
401
402 if options.username:
403 username = options.username
404 if options.password:
405 password = options.password
406 if options.username_in:
407 username_in = options.username_in
408 if options.password_in:
409 password_in = options.password_in
410 if options.initiatorname:
411 initiatorname = options.initiatorname
412 print "Connecting to remote server with:"
413 print " host = %s " % remote_server
414 print ' initiatorname = %s' % initiatorname
415 print ' username = %s' % username
416 print ' password = %s' % password
417 print ' username_in = %s' % username_in
418 print ' password_in = %s' % password_in
419
420 suite = unittest.TestSuite()
421 suite.addTest(unittest.TestLoader().loadTestsFromTestCase(OpenIscsiTest))
422 suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
423 CloudImageTest))
424 rc = unittest.TextTestRunner(verbosity=2).run(suite)
425 if not rc.wasSuccessful():
426 sys.exit(1)
diff --git a/debian/tests/testlib.py b/debian/tests/testlib.py
0new file mode 100644427new file mode 100644
index 0000000..b17c3fc
--- /dev/null
+++ b/debian/tests/testlib.py
@@ -0,0 +1,1153 @@
1#
2# testlib.py quality assurance test script
3# Copyright (C) 2008-2011 Canonical Ltd.
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Library General Public
7# License as published by the Free Software Foundation; either
8# version 2 of the License.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Library General Public License for more details.
14#
15# You should have received a copy of the GNU Library General Public
16# License along with this program. If not, see
17# <http://www.gnu.org/licenses/>.
18#
19
20'''Common classes and functions for package tests.'''
21
22import string, random, crypt, subprocess, pwd, grp, signal, time, unittest, tempfile, shutil, os, os.path, re, glob
23import sys, socket, gzip
24from stat import *
25from encodings import string_escape
26
27import warnings
28warnings.filterwarnings('ignore', message=r'.*apt_pkg\.TagFile.*', category=DeprecationWarning)
29try:
30 import apt_pkg
31 apt_pkg.InitSystem();
32except:
33 # On non-Debian system, fall back to simple comparison without debianisms
34 class apt_pkg(object):
35 def VersionCompare(one, two):
36 list_one = one.split('.')
37 list_two = two.split('.')
38 while len(list_one)>0 and len(list_two)>0:
39 if list_one[0] > list_two[0]:
40 return 1
41 if list_one[0] < list_two[0]:
42 return -1
43 list_one.pop(0)
44 list_two.pop(0)
45 return 0
46
47bogus_nxdomain = "208.69.32.132"
48
49# http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html
50# This is needed so that the subprocesses that produce endless output
51# actually quit when the reader goes away.
52import signal
53def subprocess_setup():
54 # Python installs a SIGPIPE handler by default. This is usually not what
55 # non-Python subprocesses expect.
56 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
57
58class TimedOutException(Exception):
59 def __init__(self, value = "Timed Out"):
60 self.value = value
61 def __str__(self):
62 return repr(self.value)
63
64def _restore_backup(path):
65 pathbackup = path + '.autotest'
66 if os.path.exists(pathbackup):
67 shutil.move(pathbackup, path)
68
69def _save_backup(path):
70 pathbackup = path + '.autotest'
71 if os.path.exists(path) and not os.path.exists(pathbackup):
72 shutil.copy2(path, pathbackup)
73 # copy2 does not copy ownership, so do it here.
74 # Reference: http://docs.python.org/library/shutil.html
75 a = os.stat(path)
76 os.chown(pathbackup, a[4], a[5])
77
78def config_copydir(path):
79 if os.path.exists(path) and not os.path.isdir(path):
80 raise OSError, "'%s' is not a directory" % (path)
81 _restore_backup(path)
82
83 pathbackup = path + '.autotest'
84 if os.path.exists(path):
85 shutil.copytree(path, pathbackup, symlinks=True)
86
87def config_replace(path,contents,append=False):
88 '''Replace (or append) to a config file'''
89 _restore_backup(path)
90 if os.path.exists(path):
91 _save_backup(path)
92 if append:
93 contents = file(path).read() + contents
94 open(path, 'w').write(contents)
95
96def config_comment(path, field):
97 _save_backup(path)
98 contents = ""
99 for line in file(path):
100 if re.search("^\s*%s\s*=" % (field), line):
101 line = "#" + line
102 contents += line
103
104 open(path+'.new', 'w').write(contents)
105 os.rename(path+'.new', path)
106
107def config_set(path, field, value, spaces=True):
108 _save_backup(path)
109 contents = ""
110 if spaces==True:
111 setting = '%s = %s\n' % (field, value)
112 else:
113 setting = '%s=%s\n' % (field, value)
114 found = False
115 for line in file(path):
116 if re.search("^\s*%s\s*=" % (field), line):
117 found = True
118 line = setting
119 contents += line
120 if not found:
121 contents += setting
122
123 open(path+'.new', 'w').write(contents)
124 os.rename(path+'.new', path)
125
126def config_patch(path, patch, depth=1):
127 '''Patch a config file'''
128 _restore_backup(path)
129 _save_backup(path)
130
131 handle, name = mkstemp_fill(patch)
132 rc = subprocess.call(['/usr/bin/patch', '-p%s' %(depth), path], stdin=handle, stdout=subprocess.PIPE)
133 os.unlink(name)
134 if rc != 0:
135 raise Exception("Patch failed")
136
137def config_restore(path):
138 '''Rename a replaced config file back to its initial state'''
139 _restore_backup(path)
140
141def timeout(secs, f, *args):
142 def handler(signum, frame):
143 raise TimedOutException()
144
145 old = signal.signal(signal.SIGALRM, handler)
146 result = None
147 signal.alarm(secs)
148 try:
149 result = f(*args)
150 finally:
151 signal.alarm(0)
152 signal.signal(signal.SIGALRM, old)
153
154 return result
155
156def require_nonroot():
157 if os.geteuid() == 0:
158 print >>sys.stderr, "This series of tests should be run as a regular user with sudo access, not as root."
159 sys.exit(1)
160
161def require_root():
162 if os.geteuid() != 0:
163 print >>sys.stderr, "This series of tests should be run with root privileges (e.g. via sudo)."
164 sys.exit(1)
165
166def require_sudo():
167 if os.geteuid() != 0 or os.environ.get('SUDO_USER', None) == None:
168 print >>sys.stderr, "This series of tests must be run under sudo."
169 sys.exit(1)
170 if os.environ['SUDO_USER'] == 'root':
171 print >>sys.stderr, 'Please run this test using sudo from a regular user. (You ran sudo from root.)'
172 sys.exit(1)
173
174def random_string(length,lower=False):
175 '''Return a random string, consisting of ASCII letters, with given
176 length.'''
177
178 s = ''
179 selection = string.letters
180 if lower:
181 selection = string.lowercase
182 maxind = len(selection)-1
183 for l in range(length):
184 s += selection[random.randint(0, maxind)]
185 return s
186
187def mkstemp_fill(contents,suffix='',prefix='testlib-',dir=None):
188 '''As tempfile.mkstemp does, return a (file, name) pair, but with
189 prefilled contents.'''
190
191 handle, name = tempfile.mkstemp(suffix=suffix,prefix=prefix,dir=dir)
192 os.close(handle)
193 handle = file(name,"w+")
194 handle.write(contents)
195 handle.flush()
196 handle.seek(0)
197
198 return handle, name
199
200def create_fill(path, contents, mode=0644):
201 '''Safely create a page'''
202 # make the temp file in the same dir as the destination file so we
203 # don't get invalid cross-device link errors when we rename
204 handle, name = mkstemp_fill(contents, dir=os.path.dirname(path))
205 handle.close()
206 os.rename(name, path)
207 os.chmod(path, mode)
208
209def login_exists(login):
210 '''Checks whether the given login exists on the system.'''
211
212 try:
213 pwd.getpwnam(login)
214 return True
215 except KeyError:
216 return False
217
218def group_exists(group):
219 '''Checks whether the given login exists on the system.'''
220
221 try:
222 grp.getgrnam(group)
223 return True
224 except KeyError:
225 return False
226
227def recursive_rm(dirPath, contents_only=False):
228 '''recursively remove directory'''
229 names = os.listdir(dirPath)
230 for name in names:
231 path = os.path.join(dirPath, name)
232 if os.path.islink(path) or not os.path.isdir(path):
233 os.unlink(path)
234 else:
235 recursive_rm(path)
236 if contents_only == False:
237 os.rmdir(dirPath)
238
239def check_pidfile(exe, pidfile):
240 '''Checks if pid in pidfile is running'''
241 if not os.path.exists(pidfile):
242 return False
243
244 # get the pid
245 try:
246 fd = open(pidfile, 'r')
247 pid = fd.readline().rstrip('\n')
248 fd.close()
249 except:
250 return False
251
252 return check_pid(exe, pid)
253
254def check_pid(exe, pid):
255 '''Checks if pid is running'''
256 cmdline = "/proc/%s/cmdline" % (str(pid))
257 if not os.path.exists(cmdline):
258 return False
259
260 # get the command line
261 try:
262 fd = open(cmdline, 'r')
263 tmp = fd.readline().split('\0')
264 fd.close()
265 except:
266 return False
267
268 # this allows us to match absolute paths or just the executable name
269 if re.match('^' + exe + '$', tmp[0]) or \
270 re.match('.*/' + exe + '$', tmp[0]) or \
271 re.match('^' + exe + ': ', tmp[0]) or \
272 re.match('^\(' + exe + '\)', tmp[0]):
273 return True
274
275 return False
276
277def check_port(port, proto, ver=4):
278 '''Check if something is listening on the specified port.
279 WARNING: for some reason this does not work with a bind mounted /proc
280 '''
281 assert (port >= 1)
282 assert (port <= 65535)
283 assert (proto.lower() == "tcp" or proto.lower() == "udp")
284 assert (ver == 4 or ver == 6)
285
286 fn = "/proc/net/%s" % (proto)
287 if ver == 6:
288 fn += str(ver)
289
290 rc, report = cmd(['cat', fn])
291 assert (rc == 0)
292
293 hport = "%0.4x" % port
294
295 if re.search(': [0-9a-f]{8}:%s [0-9a-f]' % str(hport).lower(), report.lower()):
296 return True
297 return False
298
299def get_arch():
300 '''Get the current architecture'''
301 rc, report = cmd(['uname', '-m'])
302 assert (rc == 0)
303 return report.strip()
304
305def get_memory():
306 '''Gets total ram and swap'''
307 meminfo = "/proc/meminfo"
308 memtotal = 0
309 swaptotal = 0
310 if not os.path.exists(meminfo):
311 return (False, False)
312
313 try:
314 fd = open(meminfo, 'r')
315 for line in fd.readlines():
316 splitline = line.split()
317 if splitline[0] == 'MemTotal:':
318 memtotal = int(splitline[1])
319 elif splitline[0] == 'SwapTotal:':
320 swaptotal = int(splitline[1])
321 fd.close()
322 except:
323 return (False, False)
324
325 return (memtotal,swaptotal)
326
327def is_running_in_vm():
328 '''Check if running under a VM'''
329 # add other virtualization environments here
330 for search in ['QEMU Virtual CPU']:
331 rc, report = cmd_pipe(['dmesg'], ['grep', search])
332 if rc == 0:
333 return True
334 return False
335
336def ubuntu_release():
337 '''Get the Ubuntu release'''
338 f = "/etc/lsb-release"
339 try:
340 size = os.stat(f)[ST_SIZE]
341 except:
342 return "UNKNOWN"
343
344 if size > 1024*1024:
345 raise IOError, 'Could not open "%s" (too big)' % f
346
347 try:
348 fh = open("/etc/lsb-release", 'r')
349 except:
350 raise
351
352 lines = fh.readlines()
353 fh.close()
354
355 pat = re.compile(r'DISTRIB_CODENAME')
356 for line in lines:
357 if pat.search(line):
358 return line.split('=')[1].rstrip('\n').rstrip('\r')
359
360 return "UNKNOWN"
361
362def cmd(command, input = None, stderr = subprocess.STDOUT, stdout = subprocess.PIPE, stdin = None, timeout = None):
363 '''Try to execute given command (array) and return its stdout, or return
364 a textual error if it failed.'''
365
366 try:
367 sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, preexec_fn=subprocess_setup)
368 except OSError, e:
369 return [127, str(e)]
370
371 out, outerr = sp.communicate(input)
372 # Handle redirection of stdout
373 if out == None:
374 out = ''
375 # Handle redirection of stderr
376 if outerr == None:
377 outerr = ''
378 return [sp.returncode,out+outerr]
379
380def cmd_pipe(command1, command2, input = None, stderr = subprocess.STDOUT, stdin = None):
381 '''Try to pipe command1 into command2.'''
382 try:
383 sp1 = subprocess.Popen(command1, stdin=stdin, stdout=subprocess.PIPE, stderr=stderr, close_fds=True)
384 sp2 = subprocess.Popen(command2, stdin=sp1.stdout, stdout=subprocess.PIPE, stderr=stderr, close_fds=True)
385 except OSError, e:
386 return [127, str(e)]
387
388 out = sp2.communicate(input)[0]
389 return [sp2.returncode,out]
390
391def cwd_has_enough_space(cdir, total_bytes):
392 '''Determine if the partition of the current working directory has 'bytes'
393 free.'''
394 rc, df_output = cmd(['df'])
395 result = 'Got exit code %d, expected %d\n' % (rc, 0)
396 if rc != 0:
397 return False
398
399 kb = total_bytes / 1024
400
401 mounts = dict()
402 for line in df_output.splitlines():
403 if '/' not in line:
404 continue
405 tmp = line.split()
406 mounts[tmp[5]] = int(tmp[3])
407
408 cdir = os.getcwd()
409 while cdir != '/':
410 if not mounts.has_key(cdir):
411 cdir = os.path.dirname(cdir)
412 continue
413 if kb < mounts[cdir]:
414 return True
415 else:
416 return False
417
418 if kb < mounts['/']:
419 return True
420
421 return False
422
423def get_md5(filename):
424 '''Gets the md5sum of the file specified'''
425
426 (rc, report) = cmd(["/usr/bin/md5sum", "-b", filename])
427 expected = 0
428 assert (expected == rc)
429
430 return report.split(' ')[0]
431
432def dpkg_compare_installed_version(pkg, check, version):
433 '''Gets the version for the installed package, and compares it to the
434 specified version.
435 '''
436 (rc, report) = cmd(["/usr/bin/dpkg", "-s", pkg])
437 assert (rc == 0)
438 assert ("Status: install ok installed" in report)
439 installed_version = ""
440 for line in report.splitlines():
441 if line.startswith("Version: "):
442 installed_version = line.split()[1]
443
444 assert (installed_version != "")
445
446 (rc, report) = cmd(["/usr/bin/dpkg", "--compare-versions", installed_version, check, version])
447 assert (rc == 0 or rc == 1)
448 if rc == 0:
449 return True
450 return False
451
452def prepare_source(source, builder, cached_src, build_src, patch_system):
453 '''Download and unpack source package, installing necessary build depends,
454 adjusting the permissions for the 'builder' user, and returning the
455 directory of the unpacked source. Patch system can be one of:
456 - cdbs
457 - dpatch
458 - quilt
459 - quiltv3
460 - None (not the string)
461
462 This is normally used like this:
463
464 def setUp(self):
465 ...
466 self.topdir = os.getcwd()
467 self.cached_src = os.path.join(os.getcwd(), "source")
468 self.tmpdir = tempfile.mkdtemp(prefix='testlib', dir='/tmp')
469 self.builder = testlib.TestUser()
470 testlib.cmd(['chgrp', self.builder.login, self.tmpdir])
471 os.chmod(self.tmpdir, 0775)
472
473 def tearDown(self):
474 ...
475 self.builder = None
476 self.topdir = os.getcwd()
477 if os.path.exists(self.tmpdir):
478 testlib.recursive_rm(self.tmpdir)
479
480 def test_suite_build(self):
481 ...
482 build_dir = testlib.prepare_source('foo', \
483 self.builder, \
484 self.cached_src, \
485 os.path.join(self.tmpdir, \
486 os.path.basename(self.cached_src)),
487 "quilt")
488 os.chdir(build_dir)
489
490 # Example for typical build, adjust as necessary
491 print ""
492 print " make clean"
493 rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make', 'clean'])
494
495 print " configure"
496 rc, report = testlib.cmd(['sudo', '-u', self.builder.login, './configure', '--prefix=%s' % self.tmpdir, '--enable-debug'])
497
498 print " make (will take a while)"
499 rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make'])
500
501 print " make check (will take a while)",
502 rc, report = testlib.cmd(['sudo', '-u', self.builder.login, 'make', 'check'])
503 expected = 0
504 result = 'Got exit code %d, expected %d\n' % (rc, expected)
505 self.assertEquals(expected, rc, result + report)
506
507 def test_suite_cleanup(self):
508 ...
509 if os.path.exists(self.cached_src):
510 testlib.recursive_rm(self.cached_src)
511
512 It is up to the caller to clean up cached_src and build_src (as in the
513 above example, often the build_src is in a tmpdir that is cleaned in
514 tearDown() and the cached_src is cleaned in a one time clean-up
515 operation (eg 'test_suite_cleanup()) which must be run after the build
516 suite test (obviously).
517 '''
518
519 # Make sure we have a clean slate
520 assert (os.path.exists(os.path.dirname(build_src)))
521 assert (not os.path.exists(build_src))
522
523 cdir = os.getcwd()
524 if os.path.exists(cached_src):
525 shutil.copytree(cached_src, build_src)
526 os.chdir(build_src)
527 else:
528 # Only install the build dependencies on the initial setup
529 rc, report = cmd(['apt-get','-y','--force-yes','build-dep',source])
530 assert (rc == 0)
531
532 os.makedirs(build_src)
533 os.chdir(build_src)
534
535 # These are always needed
536 pkgs = ['build-essential', 'dpkg-dev', 'fakeroot']
537 rc, report = cmd(['apt-get','-y','--force-yes','install'] + pkgs)
538 assert (rc == 0)
539
540 rc, report = cmd(['apt-get','source',source])
541 assert (rc == 0)
542 shutil.copytree(build_src, cached_src)
543
544 unpacked_dir = os.path.join(build_src, glob.glob('%s-*' % source)[0])
545
546 # Now apply the patches. Do it here so that we don't mess up our cached
547 # sources.
548 os.chdir(unpacked_dir)
549 assert (patch_system in ['cdbs', 'dpatch', 'quilt', 'quiltv3', None])
550 if patch_system != None and patch_system != "quiltv3":
551 if patch_system == "quilt":
552 os.environ.setdefault('QUILT_PATCHES','debian/patches')
553 rc, report = cmd(['quilt', 'push', '-a'])
554 assert (rc == 0)
555 elif patch_system == "cdbs":
556 rc, report = cmd(['./debian/rules', 'apply-patches'])
557 assert (rc == 0)
558 elif patch_system == "dpatch":
559 rc, report = cmd(['dpatch', 'apply-all'])
560 assert (rc == 0)
561
562 cmd(['chown', '-R', '%s:%s' % (builder.uid, builder.gid), build_src])
563 os.chdir(cdir)
564
565 return unpacked_dir
566
567def _aa_status():
568 '''Get aa-status output'''
569 exe = "/usr/sbin/aa-status"
570 assert (os.path.exists(exe))
571 if os.geteuid() == 0:
572 return cmd([exe])
573 return cmd(['sudo', exe])
574
575def is_apparmor_loaded(path):
576 '''Check if profile is loaded'''
577 rc, report = _aa_status()
578 if rc != 0:
579 return False
580
581 for line in report.splitlines():
582 if line.endswith(path):
583 return True
584 return False
585
586def is_apparmor_confined(path):
587 '''Check if application is confined'''
588 rc, report = _aa_status()
589 if rc != 0:
590 return False
591
592 for line in report.splitlines():
593 if re.search('%s \(' % path, line):
594 return True
595 return False
596
597def check_apparmor(path, first_ubuntu_release, is_running=True):
598 '''Check if path is loaded and confined for everything higher than the
599 first Ubuntu release specified.
600
601 Usage:
602 rc, report = testlib.check_apparmor('/usr/sbin/foo', 8.04, is_running=True)
603 if rc < 0:
604 return self._skipped(report)
605
606 expected = 0
607 result = 'Got exit code %d, expected %d\n' % (rc, expected)
608 self.assertEquals(expected, rc, result + report)
609 '''
610 global manager
611 rc = -1
612
613 if manager.lsb_release["Release"] < first_ubuntu_release:
614 return (rc, "Skipped apparmor check")
615
616 if not os.path.exists('/sbin/apparmor_parser'):
617 return (rc, "Skipped (couldn't find apparmor_parser)")
618
619 rc = 0
620 msg = ""
621 if not is_apparmor_loaded(path):
622 rc = 1
623 msg = "Profile not loaded for '%s'" % path
624
625 # this check only makes sense it the 'path' is currently executing
626 if is_running and rc == 0 and not is_apparmor_confined(path):
627 rc = 1
628 msg = "'%s' is not running in enforce mode" % path
629
630 return (rc, msg)
631
632def get_gcc_version(gcc, full=True):
633 gcc_version = 'none'
634 if not gcc.startswith('/'):
635 gcc = '/usr/bin/%s' % (gcc)
636 if os.path.exists(gcc):
637 gcc_version = 'unknown'
638 lines = cmd([gcc,'-v'])[1].strip().splitlines()
639 version_lines = [x for x in lines if x.startswith('gcc version')]
640 if len(version_lines) == 1:
641 gcc_version = " ".join(version_lines[0].split()[2:])
642 if not full:
643 return gcc_version.split()[0]
644 return gcc_version
645
646def is_kdeinit_running():
647 '''Test if kdeinit is running'''
648 # applications that use kdeinit will spawn it if it isn't running in the
649 # test. This is a problem because it does not exit. This is a helper to
650 # check for it.
651 rc, report = cmd(['ps', 'x'])
652 if 'kdeinit4 Running' not in report:
653 print >>sys.stderr, ("kdeinit not running (you may start/stop any KDE application then run this script again)")
654 return False
655 return True
656
657def get_pkgconfig_flags(libs=[]):
658 '''Find pkg-config flags for libraries'''
659 assert (len(libs) > 0)
660 rc, pkg_config = cmd(['pkg-config', '--cflags', '--libs'] + libs)
661 expected = 0
662 if rc != expected:
663 print >>sys.stderr, 'Got exit code %d, expected %d\n' % (rc, expected)
664 assert(rc == expected)
665 return pkg_config.split()
666
667class TestDaemon:
668 '''Helper class to manage daemons consistently'''
669 def __init__(self, init):
670 '''Setup daemon attributes'''
671 self.initscript = init
672
673 def _build_command(self, suffix):
674 command = []
675 if isinstance(self.initscript, list):
676 command.extend(self.initscript)
677 else:
678 command.append(self.initscript)
679 command.append(suffix)
680 return command
681
682 def start(self):
683 '''Start daemon'''
684 rc, report = cmd(self._build_command('start'))
685 expected = 0
686 result = 'Got exit code %d, expected %d\n' % (rc, expected)
687 time.sleep(2)
688 if expected != rc:
689 return (False, result + report)
690
691 if "fail" in report:
692 return (False, "Found 'fail' in report\n" + report)
693
694 return (True, "")
695
696 def stop(self):
697 '''Stop daemon'''
698 rc, report = cmd(self._build_command('stop'))
699 expected = 0
700 result = 'Got exit code %d, expected %d\n' % (rc, expected)
701 if expected != rc:
702 return (False, result + report)
703
704 if "fail" in report:
705 return (False, "Found 'fail' in report\n" + report)
706
707 return (True, "")
708
709 def reload(self):
710 '''Reload daemon'''
711 rc, report = cmd(self._build_command('force-reload'))
712 expected = 0
713 result = 'Got exit code %d, expected %d\n' % (rc, expected)
714 if expected != rc:
715 return (False, result + report)
716
717 if "fail" in report:
718 return (False, "Found 'fail' in report\n" + report)
719
720 return (True, "")
721
722 def restart(self):
723 '''Restart daemon'''
724 (res, str) = self.stop()
725 if not res:
726 return (res, str)
727
728 (res, str) = self.start()
729 if not res:
730 return (res, str)
731
732 return (True, "")
733
734 def status(self):
735 '''Check daemon status'''
736 rc, report = cmd(self._build_command('status'))
737 expected = 0
738 result = 'Got exit code %d, expected %d\n' % (rc, expected)
739 if expected != rc:
740 return (False, result + report)
741
742 if "fail" in report:
743 return (False, "Found 'fail' in report\n" + report)
744
745 return (True, "")
746
747class TestlibManager(object):
748 '''Singleton class used to set up per-test-run information'''
749 def __init__(self):
750 # Set glibc aborts to dump to stderr instead of the tty so test output
751 # is more sane.
752 os.environ.setdefault('LIBC_FATAL_STDERR_','1')
753
754 # check verbosity
755 self.verbosity = False
756 if (len(sys.argv) > 1 and '-v' in sys.argv[1:]):
757 self.verbosity = True
758
759 # Load LSB release file
760 self.lsb_release = dict()
761 if not os.path.exists('/usr/bin/lsb_release') and not os.path.exists('/bin/lsb_release'):
762 raise OSError, "Please install 'lsb-release'"
763 for line in subprocess.Popen(['lsb_release','-a'],stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0].splitlines():
764 field, value = line.split(':',1)
765 value=value.strip()
766 field=field.strip()
767 # Convert numerics
768 try:
769 value = float(value)
770 except:
771 pass
772 self.lsb_release.setdefault(field,value)
773
774 # FIXME: hack OEM releases into known-Ubuntu versions
775 if self.lsb_release['Distributor ID'] == "HP MIE (Mobile Internet Experience)":
776 if self.lsb_release['Release'] == 1.0:
777 self.lsb_release['Distributor ID'] = "Ubuntu"
778 self.lsb_release['Release'] = 8.04
779 else:
780 raise OSError, "Unknown version of HP MIE"
781
782 # FIXME: hack to assume a most-recent release if we're not
783 # running under Ubuntu.
784 if self.lsb_release['Distributor ID'] not in ["Ubuntu","Linaro"]:
785 self.lsb_release['Release'] = 10000
786 # Adjust Linaro release to pretend to be Ubuntu
787 if self.lsb_release['Distributor ID'] in ["Linaro"]:
788 self.lsb_release['Distributor ID'] = "Ubuntu"
789 self.lsb_release['Release'] -= 0.01
790
791 # Load arch
792 if not os.path.exists('/usr/bin/dpkg'):
793 machine = cmd(['uname','-m'])[1].strip()
794 if machine.endswith('86'):
795 self.dpkg_arch = 'i386'
796 elif machine.endswith('_64'):
797 self.dpkg_arch = 'amd64'
798 elif machine.startswith('arm'):
799 self.dpkg_arch = 'armel'
800 else:
801 raise ValueError, "Unknown machine type '%s'" % (machine)
802 else:
803 self.dpkg_arch = cmd(['dpkg','--print-architecture'])[1].strip()
804
805 # Find kernel version
806 self.kernel_is_ubuntu = False
807 self.kernel_version_signature = None
808 self.kernel_version = cmd(["uname","-r"])[1].strip()
809 versig = '/proc/version_signature'
810 if os.path.exists(versig):
811 self.kernel_is_ubuntu = True
812 self.kernel_version_signature = file(versig).read().strip()
813 self.kernel_version_ubuntu = self.kernel_version
814 elif os.path.exists('/usr/bin/dpkg'):
815 # this can easily be inaccurate but is only an issue for Dapper
816 rc, out = cmd(['dpkg','-l','linux-image-%s' % (self.kernel_version)])
817 if rc == 0:
818 self.kernel_version_signature = out.strip().split('\n').pop().split()[2]
819 self.kernel_version_ubuntu = self.kernel_version_signature
820 if self.kernel_version_signature == None:
821 # Attempt to fall back to something for non-Debian-based
822 self.kernel_version_signature = self.kernel_version
823 self.kernel_version_ubuntu = self.kernel_version
824 # Build ubuntu version without hardware suffix
825 try:
826 self.kernel_version_ubuntu = "-".join([x for x in self.kernel_version_signature.split(' ')[1].split('-') if re.search('^[0-9]', x)])
827 except:
828 pass
829
830 # Find gcc version
831 self.gcc_version = get_gcc_version('gcc')
832
833 # Find libc
834 self.path_libc = [x.split()[2] for x in cmd(['ldd','/bin/ls'])[1].splitlines() if x.startswith('\tlibc.so.')][0]
835
836 # Report self
837 if self.verbosity:
838 kernel = self.kernel_version_ubuntu
839 if kernel != self.kernel_version_signature:
840 kernel += " (%s)" % (self.kernel_version_signature)
841 print >>sys.stdout, "Running test: '%s' distro: '%s %.2f' kernel: '%s' arch: '%s' uid: %d/%d SUDO_USER: '%s')" % ( \
842 sys.argv[0],
843 self.lsb_release['Distributor ID'],
844 self.lsb_release['Release'],
845 kernel,
846 self.dpkg_arch,
847 os.geteuid(), os.getuid(),
848 os.environ.get('SUDO_USER', ''))
849 sys.stdout.flush()
850
851 # Additional heuristics
852 #if os.environ.get('SUDO_USER', os.environ.get('USER', '')) in ['mdeslaur']:
853 # sys.stdout.write("Replying to Marc Deslauriers in http://launchpad.net/bugs/%d: " % random.randint(600000, 980000))
854 # sys.stdout.flush()
855 # time.sleep(0.5)
856 # sys.stdout.write("destroyed\n")
857 # time.sleep(0.5)
858
859 def hello(self, msg):
860 print >>sys.stderr, "Hello from %s" % (msg)
861# The central instance
862manager = TestlibManager()
863
864class TestlibCase(unittest.TestCase):
865 def __init__(self, *args):
866 '''This is called for each TestCase test instance, which isn't much better
867 than SetUp.'''
868
869 unittest.TestCase.__init__(self, *args)
870
871 # Attach to and duplicate dicts from manager singleton
872 self.manager = manager
873 #self.manager.hello(repr(self) + repr(*args))
874 self.my_verbosity = self.manager.verbosity
875 self.lsb_release = self.manager.lsb_release
876 self.dpkg_arch = self.manager.dpkg_arch
877 self.kernel_version = self.manager.kernel_version
878 self.kernel_version_signature = self.manager.kernel_version_signature
879 self.kernel_version_ubuntu = self.manager.kernel_version_ubuntu
880 self.kernel_is_ubuntu = self.manager.kernel_is_ubuntu
881 self.gcc_version = self.manager.gcc_version
882 self.path_libc = self.manager.path_libc
883
884 def version_compare(self, one, two):
885 return apt_pkg.VersionCompare(one,two)
886
887 def assertFileType(self, filename, filetype):
888 '''Checks the file type of the file specified'''
889
890 (rc, report, out) = self._testlib_shell_cmd(["/usr/bin/file", "-b", filename])
891 out = out.strip()
892 expected = 0
893 # Absolutely no idea why this happens on Hardy
894 if self.lsb_release['Release'] == 8.04 and rc == 255 and len(out) > 0:
895 rc = 0
896 result = 'Got exit code %d, expected %d:\n%s\n' % (rc, expected, report)
897 self.assertEquals(expected, rc, result)
898
899 filetype = '^%s$' % (filetype)
900 result = 'File type reported by file: [%s], expected regex: [%s]\n' % (out, filetype)
901 self.assertNotEquals(None, re.search(filetype, out), result)
902
903 def yank_commonname_from_cert(self, certfile):
904 '''Extract the commonName from a given PEM'''
905 rc, out = cmd(['openssl','asn1parse','-in',certfile])
906 if rc == 0:
907 ready = False
908 for line in out.splitlines():
909 if ready:
910 return line.split(':')[-1]
911 if ':commonName' in line:
912 ready = True
913 return socket.getfqdn()
914
915 def announce(self, text):
916 if self.my_verbosity:
917 print >>sys.stdout, "(%s) " % (text),
918 sys.stdout.flush()
919
920 def make_clean(self):
921 rc, output = self.shell_cmd(['make','clean'])
922 self.assertEquals(rc, 0, output)
923
924 def get_makefile_compiler(self):
925 # Find potential compiler name
926 compiler = 'gcc'
927 if os.path.exists('Makefile'):
928 for line in open('Makefile'):
929 if line.startswith('CC') and '=' in line:
930 items = [x.strip() for x in line.split('=')]
931 if items[0] == 'CC':
932 compiler = items[1]
933 break
934 return compiler
935
936 def make_target(self, target, expected=0):
937 '''Compile a target and report output'''
938
939 compiler = self.get_makefile_compiler()
940 rc, output = self.shell_cmd(['make',target])
941 self.assertEquals(rc, expected, 'rc(%d)!=%d:\n' % (rc, expected) + output)
942 self.assertTrue('%s ' % (compiler) in output, 'Expected "%s":' % (compiler) + output)
943 return output
944
945 # call as return testlib.skipped()
946 def _skipped(self, reason=""):
947 '''Provide a visible way to indicate that a test was skipped'''
948 if reason != "":
949 reason = ': %s' % (reason)
950 self.announce("skipped%s" % (reason))
951 return False
952
953 def _testlib_shell_cmd(self,args,stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT):
954 argstr = "'" + "', '".join(args).strip() + "'"
955 rc, out = cmd(args,stdin=stdin,stdout=stdout,stderr=stderr)
956 report = 'Command: ' + argstr + '\nOutput:\n' + out
957 return rc, report, out
958
959 def shell_cmd(self, args, stdin=None):
960 return cmd(args,stdin=stdin)
961
962 def assertShellExitEquals(self, expected, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg=""):
963 '''Test a shell command matches a specific exit code'''
964 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
965 result = 'Got exit code %d, expected %d\n' % (rc, expected)
966 self.assertEquals(expected, rc, msg + result + report)
967
968 def assertShellExitNotEquals(self, unwanted, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg=""):
969 '''Test a shell command doesn't match a specific exit code'''
970 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
971 result = 'Got (unwanted) exit code %d\n' % rc
972 self.assertNotEquals(unwanted, rc, msg + result + report)
973
974 def assertShellOutputContains(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False):
975 '''Test a shell command contains a specific output'''
976 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
977 result = 'Got exit code %d. Looking for text "%s"\n' % (rc, text)
978 if not invert:
979 self.assertTrue(text in out, msg + result + report)
980 else:
981 self.assertFalse(text in out, msg + result + report)
982
983 def assertShellOutputEquals(self, text, args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, msg="", invert=False, expected=None):
984 '''Test a shell command matches a specific output'''
985 rc, report, out = self._testlib_shell_cmd(args, stdin=stdin, stdout=stdout, stderr=stderr)
986 result = 'Got exit code %d. Looking for exact text "%s" (%s)\n' % (rc, text, " ".join(args))
987 if not invert:
988 self.assertEquals(text, out, msg + result + report)
989 else:
990 self.assertNotEquals(text, out, msg + result + report)
991 if expected != None:
992 result = 'Got exit code %d. Expected %d (%s)\n' % (rc, expected, " ".join(args))
993 self.assertEquals(rc, expected, msg + result + report)
994
995 def _word_find(self, report, content, invert=False):
996 '''Check for a specific string'''
997 if invert:
998 warning = 'Found "%s"\n' % content
999 self.assertTrue(content not in report, warning + report)
1000 else:
1001 warning = 'Could not find "%s"\n' % content
1002 self.assertTrue(content in report, warning + report)
1003
1004 def _test_sysctl_value(self, path, expected, msg=None, exists=True):
1005 sysctl = '/proc/sys/%s' % (path)
1006 self.assertEquals(exists, os.path.exists(sysctl), sysctl)
1007 value = None
1008 if exists:
1009 value = int(file(sysctl).read())
1010 report = "%s is not %d: %d" % (sysctl, expected, value)
1011 if msg:
1012 report += " (%s)" % (msg)
1013 self.assertEquals(value, expected, report)
1014 return value
1015
1016 def set_sysctl_value(self, path, desired):
1017 sysctl = '/proc/sys/%s' % (path)
1018 self.assertTrue(os.path.exists(sysctl),"%s does not exist" % (sysctl))
1019 file(sysctl,'w').write(str(desired))
1020 self._test_sysctl_value(path, desired)
1021
1022 def kernel_at_least(self, introduced):
1023 return self.version_compare(self.kernel_version_ubuntu,
1024 introduced) >= 0
1025
1026 def kernel_claims_cve_fixed(self, cve):
1027 changelog = "/usr/share/doc/linux-image-%s/changelog.Debian.gz" % (self.kernel_version)
1028 if os.path.exists(changelog):
1029 for line in gzip.open(changelog):
1030 if cve in line and not "revert" in line and not "Revert" in line:
1031 return True
1032 return False
1033
1034class TestGroup:
1035 '''Create a temporary test group and remove it again in the dtor.'''
1036
1037 def __init__(self, group=None, lower=False):
1038 '''Create a new group'''
1039
1040 self.group = None
1041 if group:
1042 if group_exists(group):
1043 raise ValueError, 'group name already exists'
1044 else:
1045 while(True):
1046 group = random_string(7,lower=lower)
1047 if not group_exists(group):
1048 break
1049
1050 assert subprocess.call(['groupadd',group]) == 0
1051 self.group = group
1052 g = grp.getgrnam(self.group)
1053 self.gid = g[2]
1054
1055 def __del__(self):
1056 '''Remove the created group.'''
1057
1058 if self.group:
1059 rc, report = cmd(['groupdel', self.group])
1060 assert rc == 0
1061
1062class TestUser:
1063 '''Create a temporary test user and remove it again in the dtor.'''
1064
1065 def __init__(self, login=None, home=True, group=None, uidmin=None, lower=False, shell=None):
1066 '''Create a new user account with a random password.
1067
1068 By default, the login name is random, too, but can be explicitly
1069 specified with 'login'. By default, a home directory is created, this
1070 can be suppressed with 'home=False'.'''
1071
1072 self.login = None
1073
1074 if os.geteuid() != 0:
1075 raise ValueError, "You must be root to run this test"
1076
1077 if login:
1078 if login_exists(login):
1079 raise ValueError, 'login name already exists'
1080 else:
1081 while(True):
1082 login = 't' + random_string(7,lower=lower)
1083 if not login_exists(login):
1084 break
1085
1086 self.salt = random_string(2)
1087 self.password = random_string(8,lower=lower)
1088 self.crypted = crypt.crypt(self.password, self.salt)
1089
1090 creation = ['useradd', '-p', self.crypted]
1091 if home:
1092 creation += ['-m']
1093 if group:
1094 creation += ['-G',group]
1095 if uidmin:
1096 creation += ['-K','UID_MIN=%d'%uidmin]
1097 if shell:
1098 creation += ['-s',shell]
1099 creation += [login]
1100 assert subprocess.call(creation) == 0
1101 # Set GECOS
1102 assert subprocess.call(['usermod','-c','Buddy %s' % (login),login]) == 0
1103
1104 self.login = login
1105 p = pwd.getpwnam(self.login)
1106 self.uid = p[2]
1107 self.gid = p[3]
1108 self.gecos = p[4]
1109 self.home = p[5]
1110 self.shell = p[6]
1111
1112 def __del__(self):
1113 '''Remove the created user account.'''
1114
1115 if self.login:
1116 # sanity check the login name so we don't accidentally wipe too much
1117 if len(self.login)>3 and not '/' in self.login:
1118 subprocess.call(['rm','-rf', '/home/'+self.login, '/var/mail/'+self.login])
1119 rc, report = cmd(['userdel', '-f', self.login])
1120 assert rc == 0
1121
1122 def add_to_group(self, group):
1123 '''Add user to the specified group name'''
1124 rc, report = cmd(['usermod', '-G', group, self.login])
1125 if rc != 0:
1126 print report
1127 assert rc == 0
1128
1129# Timeout handler using alarm() from John P. Speno's Pythonic Avocado
1130class TimeoutFunctionException(Exception):
1131 """Exception to raise on a timeout"""
1132 pass
1133class TimeoutFunction:
1134 def __init__(self, function, timeout):
1135 self.timeout = timeout
1136 self.function = function
1137
1138 def handle_timeout(self, signum, frame):
1139 raise TimeoutFunctionException()
1140
1141 def __call__(self, *args, **kwargs):
1142 old = signal.signal(signal.SIGALRM, self.handle_timeout)
1143 signal.alarm(self.timeout)
1144 try:
1145 result = self.function(*args, **kwargs)
1146 finally:
1147 signal.signal(signal.SIGALRM, old)
1148 signal.alarm(0)
1149 return result
1150
1151def main():
1152 print "hi"
1153 unittest.main()
diff --git a/debian/tests/testsuite b/debian/tests/testsuite
0new file mode 1006441154new file mode 100644
index 0000000..47c7a70
--- /dev/null
+++ b/debian/tests/testsuite
@@ -0,0 +1,7 @@
1#!/bin/bash
2#-------------------
3# Testing open-iscsi
4#-------------------
5set -e
6python2 `dirname $0`/test-open-iscsi.py 2>&1
7
diff --git a/debian/tests/tgt-boot-test b/debian/tests/tgt-boot-test
0new file mode 1007558new file mode 100755
index 0000000..af5ec50
--- /dev/null
+++ b/debian/tests/tgt-boot-test
@@ -0,0 +1,534 @@
1#!/bin/bash
2
3VERBOSITY=0
4TEMP_D=""
5DEF_WPORT=32600
6IPV4_NET="10.0.12"
7DEF_NETDEV="user,net=${IPV4_NET}.0/24,host=${IPV4_NET}.2"
8
9ISCSI_PORT=3260
10TGT_CONF=""
11HTTP_PID=""
12TGT_NAME=""
13
14_DEF_CMDLINE_TMPL=(
15 nomodeset {icmdline_parms} {cmdline_ip} ro
16 net.ifnames=0 BOOTIF_DEFAULT=eth0
17 root={root} {overlay_drive}
18 console=ttyS0 {cmdline_ds}
19 # LP: #1796137
20 systemd.mask=snapd.seeded.service systemd.mask=snapd.service
21)
22DEF_CMDLINE_TMPL="${_DEF_CMDLINE_TMPL[*]}"
23
24error() { echo "$@" 1>&2; }
25fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
26
27cleanup() {
28 [ ! -d "$TEMP_D" ] || rm -Rf "$TEMP_D"
29 if [ -f "$TGT_CONF" ]; then
30 error "cleaning up tgt mount ${TGT_NAME}"
31 sudo tgt-admin --force --delete="$TGT_NAME"
32 sudo rm -f "$TGT_CONF"
33 fi
34 if [ -n "$HTTP_PID" ]; then
35 kill $HTTP_PID
36 fi
37}
38
39Usage() {
40 cat <<EOF
41Usage: ${0##*/} [ options ] image kernel initrd
42
43 put 'image' into tgt, boot 'kernel' and 'initrd' in a kvm
44 guest pointing to that iscsi target.
45
46 options:
47 -p | --webserv-port PORT serve cloud-init seed on port PORT
48 default: ${DEF_WPORT}
49 -O | --overlay-disk DISK attach DISK to guest and use it for the overlayroot
50 target. Use 'temp' to use a temp file.
51 use an existing file to use that. Use a
52 non-existing file to create.
53 -n | --netdev DEV passed through to xkvm.
54 if none passed, default is:
55 $DEF_NETDEV
56 -a | --host-addr ADDR will be used for iscsi host address and
57 cloud-init seed address. Default is read
58 from 'host=' in --netdev arg.
59 -l | --serial-log FILE write serial log to FILE default is to let output
60 go to console.
61 --cmdline TMPL template for kernel command line.
62 default: ${DEF_CMDLINE_TMPL}
63 --cmdline-add ARGS add the args to the kernel command line. default: ""
64 --user-data FILE user-data to provide to instance.
65 default: builtin
66 --user-data-add FILE append FILE to default user-data.
67EOF
68}
69
70bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
71
72debug() {
73 local level=${1}; shift;
74 [ "${level}" -gt "${VERBOSITY}" ] && return
75 error "${@}"
76}
77
78write_userdata() {
79 ## set up a user-data and meta-data for cloud-init
80 ## and we'll seed that through the kernel command line
81 ##
82 ## The user data we provide will allow us to log in
83 ## as the 'ubuntu' user with 'passw0rd'.
84 local out="$1" keys="${2:-[]}"
85 cat > "$out" <<"EOF"
86#cloud-config
87chpasswd:
88 expire: False
89 list: |
90 ubuntu:passw0rd
91 root:root
92ssh_pwauth: True
93EOF
94}
95
96get_ssh_pubkeys() {
97 # get users ssh pubkeys in a yaml list format
98 local keys="" d=""
99 keys=$( (ssh-add -L 2>/dev/null ;
100 [ -f ~/.ssh/id_rsa.pub ] && cat ~/.ssh/id_rsa.pub ) | sort -u )
101 if [ -n "$keys" ]; then
102 d=$(IFS=$'\n'; for i in ${keys}; do echo "'$i',"; done)
103 keys="[${d%,}]"
104 else
105 keys="[]"
106 fi
107 _RET="$keys"
108}
109
110write_metadata() {
111 local iid="" out="$1" pubkeys="$2"
112 iid=$(uuidgen 2>/dev/null || echo i-abcdefg)
113 {
114 echo "instance-id: $iid"
115 if [ -n "$pubkeys" ]; then
116 echo "public-keys: $pubkeys"
117 fi
118 } > "$out"
119}
120
121register_image() {
122 local conf="$1" name="$2" image="$3"
123 sudo tee "$conf" >/dev/null <<EOF
124<target ${name}>
125 readonly 1
126 backing-store "$image"
127 allow-in-use yes
128</target>
129EOF
130 [ $? -eq 0 ] || { error "failed to write '$conf'"; return 1; }
131
132 sudo tgt-admin "--update=$name" ||
133 { error "failed tgt-admin update=$name"; return 1; }
134}
135
136address_on_dev() {
137 local dev="$1" atype="${2:-inet}" out="" addr=""
138 out=$(ip address show dev "$dev" 2>/dev/null) ||
139 { error "could not get address on $1"; return 1; }
140 addr=$(echo "$out" |
141 awk '$1 == atype && $4 == "global" {
142 sub(/\/.*/, "", $2); print $2; exit(0); }' "atype=$atype" )
143 [ -n "$addr" ] || return
144 _RET="$addr"
145}
146
147find_host_addr() {
148 # run through --netdev args and fine 'host=' or make one up base
149 # on there being a net= and assume .2 for host.
150 # example: type=user,id=net00,net=10.0.12.0/24,host=10.0.12.2
151 # ipv6-net=fec0::/64,ipv6-host=fec0::2
152 # lxcbr0
153 local nd="" atype="" bridge=""
154 local oifs="$IFS"
155 for nd in "$@"; do
156 local host="" netaddr="" cur="" ipv4="x" ipv6="x" ntype=""
157 bridge=${nd%%,*}
158 if [ "$bridge" != "user" -a -e "/sys/class/net/$bridge" ]; then
159 for atype in inet inet6; do
160 address_on_dev "$bridge" "$atype" || continue
161 debug 2 "took $atype address on bridge '$bridge': $_RET";
162 return 0;
163 done
164 fi
165 cur=${nd}
166 while :; do
167 first=${cur%%,*}
168 rest=${cur#*,}
169 case "$first" in
170 user) ntype=user;;
171 ipv4=on|ipv4) ipv4=on;;
172 ipv4=off) ipv4=off;;
173 ipv6=on|ipv6) ipv6=on;;
174 ipv6=off) ipv6=off;;
175 ipv6-net=*) tmp=${first#*=};
176 tmp=${tmp%/*}
177 netaddr="${tmp%.*}:2"
178 ;;
179 net=*) tmp=${first#*=};
180 tmp=${tmp%/*}
181 netaddr="${tmp%.*}.2"
182 ;;
183 host=*|ipv6-host=) host=${first#*=};;
184 esac
185 if [ "$first" = "$rest" ]; then
186 # there was no ','
187 break
188 fi
189 cur=$rest
190 done
191 local found="" msg=""
192 if [ -n "$host" ]; then
193 found="$host"
194 msg="host= in '$nd'"
195 elif [ -n "$netaddr" ]; then
196 found="$netaddr"
197 msg="second address on net= in '$nd'";
198 elif [ "$ntype" = "user" ]; then
199 case "$ipv4/$ipv6" in
200 */on)
201 msg="known user net default host in ipv6 in '$nd'"
202 found="fec0::2";;
203 x/x|on/*)
204 msg="known user net default host in ipv4 in '$nd'"
205 found="10.0.2.2";;
206 esac
207 fi
208 if [ -n "$found" ]; then
209 debug 2 "found host address '$found' via $msg"
210 _RET="$found"
211 return 0
212 fi
213 done
214 return 1
215}
216
217
218get_rfc4173() {
219 # protocol would normally be '6' (tcp but empty is fine)
220 # https://tools.ietf.org/html/rfc4173
221 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=804162
222 local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6" proto="$7"
223 local rfc="" auth="${user:+${user}${pass:+:${pass}}}"
224 rfc="iscsi:"
225 if [ -n "${user}" ]; then
226 rfc="$rfc:${user}${pass:+:${pass}}"
227 fi
228 case "$server" in
229 \[*\]) :;;
230 *:*) server="[$server]";;
231 esac
232 rfc="${server}:$proto:${port}:${lun}:${name}"
233 _RET="$rfc"
234}
235
236get_root_parm() {
237 local server="$1" name="$2" port="${3:-$ISCSI_PORT}"
238 local lun="$4" user="$5" pass="$6" proto="$7" part="$8"
239 local ret=""
240 # for ipv6 addresses, path just contains : for the server
241 _RET="/dev/disk/by-path/ip-$server:$port-iscsi-${name}-lun-${lun}${part:+-part$part}"
242}
243
244get_cmdline_params() {
245 local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6"
246 local proto="$7" initiator="$8" ret=""
247 ret="${initiator:+iscsi_initiator=${initiator} }"
248 ret="${ret}iscsi_target_name=$name "
249 ret="${ret}iscsi_target_ip=$server "
250 ret="${ret}${port:+iscsi_target_port=$port }"
251 ret="${ret}${initiator:+iscsi_initiator=$initiator }"
252 _RET=${ret% }
253}
254
255get_iscsi_cmd() {
256 local server="$1" name="$2" port="$3" lun="$4" user="$5" pass="$6"
257 local proto="$7" initiator="$8" ret="" group=${9:-1}
258 _RET=( iscsistart -i "$initiator"
259 -t "$name" -g "$group" -a "$server" -p "$port"
260 ${user:+-u "$user"} ${pass:+-w "${pass}"} )
261}
262
263serv_http() {
264 local dir="$1" port="$2" check="$3"
265 local python="" kid=""
266 command -v python3 >/dev/null 2>&1 && python=python3 || python=python2
267 cat > "$TEMP_D/webserv" <<EOF
268import os, socket, sys
269try:
270 from BaseHTTPServer import HTTPServer
271 from SimpleHTTPServer import SimpleHTTPRequestHandler
272except ImportError:
273 from http.server import HTTPServer, SimpleHTTPRequestHandler
274
275class HTTPServerV6(HTTPServer):
276 address_family = socket.AF_INET6
277
278if __name__ == "__main__":
279 dir = sys.argv[1]
280 port = int(sys.argv[2])
281 os.chdir(dir)
282 server = HTTPServerV6(("::", port), SimpleHTTPRequestHandler)
283 server.serve_forever()
284EOF
285 $python "$TEMP_D/webserv" "$dir" "$port" &
286 HTTP_PID=$!
287 local i=0 site="127.0.0.1"
288 local url="http://$site:$port/$check"
289 while [ -d /proc/$HTTP_PID -a "$i" -lt 10 ] && i=$(($i+1)); do
290 no_proxy=$site wget -q -O /dev/null "$url" && return 0
291 sleep .5
292 done
293 return 1
294}
295
296render_templ() {
297 local tmpl="$1"
298 shift
299 local key val i="" cur="$tmpl"
300 for i in "$@"; do
301 key=${i%%=*}
302 val=${i#*=}
303 cur=${cur//\{${key}\}/${val}}
304 done
305 _RET="$cur"
306}
307
308get_partition() {
309 # return in _RET the 'auto' partition for a image.
310 # return partition number for a partitioned image
311 # return 0 for unpartitioned
312 # return 0 if image is partitioned, 1 if not
313 local img="$1"
314 out=$(LANG=C sfdisk --list -uS "$img" 2>&1) || {
315 error "failed determining if partitioned: $out";
316 return 1;
317 }
318 if echo "$out" | grep -q 'Device.*Start.*End'; then
319 _RET=1
320 else
321 _RET=0
322 fi
323}
324
325main() {
326 local short_opts="a:hn:O:p:l:v"
327 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:"
328 local getopt_out=""
329
330 getopt_out=$(getopt --name "${0##*/}" \
331 --options "${short_opts}" --long "${long_opts}" -- "$@") &&
332 eval set -- "${getopt_out}" ||
333 { bad_Usage; return; }
334
335 local cur="" next=""
336 local overlay_disk="" webserv_port="${DEF_WPORT}" netdevs="" host_addr=""
337 local serial_log="" cmdline_tmpl="${DEF_CMDLINE_TMPL}" user_data_file=""
338 local cmdline_add="" user_data_add="" pt=""
339 # The string 'BOOTIF' is replaced at runtime with the interface
340 # name by cloud-initramfs-dyn-netconf.
341 local cmdline_ip="ip=::::{iinitiator}:BOOTIF"
342 netdevs=( )
343 pt=( )
344
345 while [ $# -ne 0 ]; do
346 cur="$1"; next="$2";
347 case "$cur" in
348 -h|--help) Usage ; exit 0;;
349 --cmdline) cmdline_tmpl=$next; shift;;
350 --cmdline-add) cmdline_add=$next; shift;;
351 --cmdline-ip) cmdline_ip=$next; shift;;
352 --disk) pt[${#pt[@]}]="$1=$2"; shift;;
353 -a|--host-addr) host_addr=$next; shift;;
354 -O|--overlay-disk) overlay_disk=$next; shift;;
355 -n|--netdev) netdevs[${#netdevs[@]}]="$next"; shift;;
356 -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
357 -l|--serial-log) serial_log="$next"; shift;;
358 --user-data-file) user_data_file="$next"; shift;;
359 --user-data-add) user_data_add="$next"; shift;;
360 -p|--webserv-port) webserv_port=$port; shift;;
361 --) shift; break;;
362 esac
363 shift;
364 done
365
366 [ $# -eq 3 ] || { bad_Usage "expected 3 args, got $# ($*)"; return 1; }
367 local image_in=$1 kernel_in=$2 initrd_in=$3
368 for f in "$image_in" "$kernel_in" "$initrd_in"; do
369 [ -f "$f" ] || fail "$f: not a file"
370 done
371
372 local image="" kernel="" initrd=""
373 image=$(readlink -f "$image_in") ||
374 fail "cannot get full path to $image_in"
375 kernel=$(readlink -f "$kernel_in") ||
376 fail "cannot get full path to $kernel_in"
377 initrd=$(readlink -f "$initrd_in") ||
378 fail "cannot get full path to $initrd_in"
379
380 TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
381 fail "failed to make tempdir"
382 TEMP_D=$(cd "$TEMP_D" && pwd)
383 trap cleanup EXIT
384
385 local t_image t_kernel t_initrd
386 t_image="${TEMP_D}/image"
387 t_kernel="${TEMP_D}/kernel"
388 t_initrd="${TEMP_D}/initrd"
389
390 if [ "${#netdevs[@]}" -eq 0 ]; then
391 netdevs=( "$DEF_NETDEV" )
392 fi
393
394 local keys=""
395 mkdir -p "$TEMP_D/ci-seed"
396 if [ -n "${user_data_file}" ]; then
397 cat "${user_data_file}" > "$TEMP_D/ci-seed/user-data" ||
398 fail "failed to copy '$user_data_file' to ci-seed/user-data"
399 else
400 write_userdata "$TEMP_D/ci-seed/user-data" ||
401 fail "failed to write user-data"
402 fi
403 if [ -n "$user_data_add" ]; then
404 cat "$user_data_add" >> "$TEMP_D/ci-seed/user-data" ||
405 fail "failed to write additional user-data"
406 fi
407
408 get_ssh_pubkeys || fail "failed getting pubkeys"
409 keys="$_RET"
410 write_metadata "$TEMP_D/ci-seed/meta-data" "$keys" ||
411 fail "failed writing metadata"
412
413 if [ -z "$host_addr" ]; then
414 find_host_addr "${netdevs[@]}" ||
415 fail "failed to find host address. try --host-addr."
416 host_addr="$_RET"
417 fi
418 debug 1 "using host address: '${host_addr}'"
419
420 ## run a python web server to seed this
421 serv_http "$TEMP_D/ci-seed" "$webserv_port" "user-data" ||
422 fail "failed to web serv $TEMP_D/ci-seed on $webserv_port"
423 debug 1 "web server in pid $HTTP_PID serving ${TEMP_D}/ci-seed/ on port $webserv_port"
424 local seed_url="http://$host_addr:$webserv_port/"
425 if [ "${host_addr#*:}" != "$host_addr" ]; then
426 seed_url="http://[$host_addr]:$webserv_port/"
427 fi
428 debug 1 " ${seed_url}meta-data"
429
430 if [ "${image%.gz}" != "$image" ]; then
431 error "uncompressing $image_in -> temp-dir"
432 gzcat "$image" > "${TEMP_D}/image" ||
433 fail "failed uncompress of $image_in"
434 else
435 ln -s "$image" "$t_image" || fail "symlink to $image failed"
436 fi
437
438 ln -s "$kernel" "$t_kernel" &&
439 ln -s "$initrd" "$t_initrd" ||
440 fail "failed link to kernel or initrd"
441
442 local partition=""
443 get_partition "$t_image" ||
444 fail "failed to read partition from $image"
445 partition=${_RET}
446 [ "$part" = "0" ] && partition=""
447
448 TGT_NAME=${TEMP_D##*/}
449 TGT_NAME=${TGT_NAME//./-}
450 TGT_CONF="/etc/tgt/conf.d/$TGT_NAME.conf"
451 register_image "$TGT_CONF" "$TGT_NAME" "$t_image" ||
452 fail "failed to register image $t_image in tgt"
453
454 overlay_drive_kernel="overlayroot=tmpfs"
455 overlay_drive_xkvm=""
456 if [ -n "${overlay_disk}" ]; then
457 if [ "${overlay_disk}" = "temp" ]; then
458 overlay_disk="${TEMP_D}/overlay.img"
459 fi
460 if [ ! -f "$overlay_disk" ]; then
461 qemu-img create -f raw "$overlay_disk" 1G
462 mkfs.ext2 -L "delta" -F "$overlay_disk" >/dev/null 2>&1 ||
463 fail "failed mkfs on $overlay_disk"
464 overlay_drive_kernel="overlayroot=device:dev=LABEL=delta"
465 overlay_drive_xkvm="--disk=${overlay_disk},format=raw"
466 fi
467 fi
468
469 local iserver="${host_addr}" iname="$TGT_NAME" iport="$ISCSI_PORT"
470 local ilun="1" iuser="" ipass="" iproto="" iinitiator="maas-enlist"
471 local rfc="" root="" iscsi_cmdline_parms="" iscsi_start_cmd=""
472 local cmdline=""
473 get_rfc4173 "${iserver}" "$iname" "$iport" "$ilun" \
474 "$iuser" "$ipass" "$iproto"
475 rfc="$_RET"
476
477 get_cmdline_params "${iserver}" "$iname" "$iport" "$ilun" \
478 "$iuser" "$ipass" "$iproto" "$iinitiator"
479 iscsi_cmdline_parms="$_RET"
480
481 get_root_parm "$iserver" "$iname" "$iport" "$ilun" \
482 "$iuser" "$ipass" "$iproto" "$partition"
483 root="$_RET"
484
485 get_iscsi_cmd "$iserver" "$iname" "$iport" "$ilun" \
486 "$iuser" "$ipass" "$iproto" "$iinitiator"
487 iscsi_start_cmd=( "${_RET[@]}" )
488
489 render_templ "${cmdline_ip}" iinitiator="$iinitiator" ||
490 { error "failed rendering cmdline ip: ${cmdline_ip}"; return 1; }
491 cmdline_ip="$_RET"
492
493 render_templ "$cmdline_tmpl${cmdline_add:+ ${cmdline_add}}" \
494 iserver="$host_addr" iname="$TGT_NAME" iport="$ISCSI_PORT" \
495 ilun="$ilun" iuser="$iuser" ipass="$ipass" iproto="$iproto" \
496 iinitiator="$iinitiator" "rfc4173=$rfc" "root=$root" \
497 "seed_url=$seed_url" icmdline_parms="$iscsi_cmdline_parms" \
498 "overlay_drive=${overlay_drive_kernel}" \
499 "cmdline_ds=ds=nocloud-net;seedfrom=${seed_url}" \
500 "cmdline_ip=${cmdline_ip}" ||
501 { error "failed rendering cmdline"; return 1; }
502 cmdline="$_RET"
503
504 debug 1 "rfc4173: $rfc"
505 debug 1 "iscsi_cmdline_parms: $iscsi_cmdline_parms"
506 debug 1 "root: $root"
507 debug 1 "iscsi_start_cmd: ${iscsi_start_cmd[*]}"
508 debug 1 "cmdline=$cmdline"
509
510 local netdev_args=""
511 netdev_args=( )
512 for i in "${netdevs[@]}"; do
513 netdev_args[${#netdev_args[@]}]="--netdev=$i"
514 done
515
516 local mem="512" start="$SECONDS" ret=""
517 local cmd=""
518 cmd=(
519 ${BOOT_TIMEOUT:+timeout --kill-after=1m --signal=TERM $BOOT_TIMEOUT}
520 xkvm -v -v "${netdev_args[@]}" ${overlay_drive_xkvm} "${pt[@]}" --
521 -echr 0x5
522 -m $mem ${serial_log:+-serial "file:$serial_log"} -nographic
523 -kernel "${t_kernel}" -initrd "${t_initrd}"
524 -append "${cmdline}"
525 )
526 debug 1 "executing: ${cmd[*]}"
527 "${cmd[@]}"
528 ret=$?
529 debug 1 "xkvm returned $ret in $((SECONDS-start))s"
530 return $ret
531}
532
533main "$@"
534# vi: ts=4 expandtab
diff --git a/debian/tests/xkvm b/debian/tests/xkvm
0new file mode 100755535new file mode 100755
index 0000000..9513723
--- /dev/null
+++ b/debian/tests/xkvm
@@ -0,0 +1,704 @@
1#!/bin/bash
2
3set -f
4
5VERBOSITY=0
6KVM_PID=""
7DRY_RUN=false
8TEMP_D=""
9DEF_BRIDGE="virbr0"
10TAPDEVS=( )
11# OVS_CLEANUP gets populated with bridge:devname pairs used with ovs
12OVS_CLEANUP=( )
13MAC_PREFIX="52:54:00:12:34"
14KVM="kvm"
15declare -A KVM_DEVOPTS
16
17error() { echo "$@" 1>&2; }
18fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
19
20bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
21randmac() {
22 # return random mac addr within final 3 tokens
23 local random=""
24 random=$(printf "%02x:%02x:%02x" \
25 "$((${RANDOM}%256))" "$((${RANDOM}%256))" "$((${RANDOM}%256))")
26 padmac "$random"
27}
28
29cleanup() {
30 [ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
31 if [ -n "${KVM_PID}" ]; then
32 debug 1 "${0##*/} cleanup killing kvm pid '$KVM_PID'"
33 kill "$KVM_PID"
34 fi
35 if [ ${#TAPDEVS[@]} -ne 0 ]; then
36 local name item
37 for item in "${TAPDEVS[@]}"; do
38 [ "${item}" = "skip" ] && continue
39 debug 1 "removing" "$item"
40 name="${item%:*}"
41 if $DRY_RUN; then
42 error ip tuntap del mode tap "$name"
43 else
44 ip tuntap del mode tap "$name"
45 fi
46 [ $? -eq 0 ] || error "failed removal of $name"
47 done
48 if [ ${#OVS_CLEANUP[@]} -ne 0 ]; then
49 # with linux bridges, there seems to be no harm in just deleting
50 # the device (not detaching from the bridge). However, with
51 # ovs, you have to remove them from the bridge, or later it
52 # will refuse to add the same name.
53 error "cleaning up ovs ports: ${OVS_CLEANUP[@]}"
54 if ${DRY_RUN}; then
55 error sudo "$0" tap-control ovs-cleanup "${OVS_CLEANUP[@]}"
56 else
57 sudo "$0" tap-control ovs-cleanup "${OVS_CLEANUP[@]}"
58 fi
59 fi
60 fi
61}
62
63debug() {
64 local level=${1}; shift;
65 [ "${level}" -gt "${VERBOSITY}" ] && return
66 error "${@}"
67}
68
69Usage() {
70 cat <<EOF
71Usage: ${0##*/} [ options ] -- kvm-args [ ... ]
72
73 run kvm with a tap interface.
74
75 options:
76 -n | --netdev NETDEV netdev can be 'user' or a bridge.
77 default is to bridge to $DEF_BRIDGE
78 -d | --disk DISK.img attach DISK.img as a disk (via virtio)
79 --dry-run only report what would be done
80
81 --uefi boot with efi
82 --uefi-nvram=FILE boot with efi, using nvram settings in FILE
83 if FILE not present, copy from defaults.
84
85 NETDEV:
86 Above, 'NETDEV' is a comma delimited string
87 The first field must be
88 * bridge name: (br0 or virbr0): attach a device to this bridge
89 * literal 'user': use qemu user networking
90
91 Additional fields are optional, and can be anything that is acceptable
92 to kvm either as:
93 * '-device virtio-net-pci' option (see 'kvm -device virtio-net-pci,?')
94 * '-net [user|tap]' option
95
96 Example:
97 * xkvm --netdev br0,macaddr=:05 -- -drive file=disk.img,if=virtio -curses
98 attach a tap device to bridge 'br0' with mac address
99 '${MAC_PREFIX}:05'
100
101 * xkvm --netdev user,mac=random --netdev br1,model=e1000,mac=auto -- -curses
102 attach virtio user networking nic with random mac address
103 attach tap device to br1 bridge as e1000 with unspecified mac
104
105 * xkvm --disk disk1.img
106EOF
107}
108
109isdevopt() {
110 local model="$1" input="${2%%=*}"
111 local out="" opt="" opts=()
112 if [ -z "${KVM_DEVOPTS[$model]}" ]; then
113 out=$($KVM -device "$model,?" 2>&1) &&
114 out=$(echo "$out" | sed -e "s,[^.]*[.],," -e 's,=.*,,') &&
115 KVM_DEVOPTS[$model]="$out" ||
116 { error "bad device model $model?"; exit 1; }
117 fi
118 opts=( ${KVM_DEVOPTS[$model]} )
119 for opt in "${opts[@]}"; do
120 [ "$input" = "$opt" ] && return 0
121 done
122 return 1
123}
124
125padmac() {
126 # return a full mac, given a subset.
127 # assume whatever is input is the last portion to be
128 # returned, and fill it out with entries from MAC_PREFIX
129 local mac="$1" num="$2" prefix="${3:-$MAC_PREFIX}" itoks="" ptoks=""
130 # if input is empty set to :$num
131 [ -n "$mac" ] || mac=$(printf "%02x" "$num") || return
132 itoks=( ${mac//:/ } )
133 ptoks=( ${prefix//:/ } )
134 rtoks=( )
135 for r in ${ptoks[@]:0:6-${#itoks[@]}} ${itoks[@]}; do
136 rtoks[${#rtoks[@]}]="0x$r"
137 done
138 _RET=$(printf "%02x:%02x:%02x:%02x:%02x:%02x" "${rtoks[@]}")
139}
140
141make_nics_Usage() {
142 cat <<EOF
143Usage: ${0##*/} tap-control make-nics [options] bridge [bridge [..]]
144
145 make a tap device on each of bridges requested
146 outputs: 'tapname:type' for each input, or 'skip' if nothing needed.
147
148 type is one of 'brctl' or 'ovs'
149EOF
150}
151
152make_nics() {
153 # takes input of list of bridges to create a tap device on
154 # and echos either 'skip' or
155 # <tapname>:<type> for each tap created
156 # type is one of "ovs" or "brctl"
157 local short_opts="v"
158 local long_opts="--verbose"
159 local getopt_out=""
160 getopt_out=$(getopt --name "${0##*/} make-nics" \
161 --options "${short_opts}" --long "${long_opts}" -- "$@") &&
162 eval set -- "${getopt_out}" || { make_nics_Usage 1>&2; return 1; }
163
164 local cur="" next=""
165 while [ $# -ne 0 ]; do
166 cur=${1}; next=${2};
167 case "$cur" in
168 -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
169 --) shift; break;;
170 esac
171 shift;
172 done
173
174 [ $# -ne 0 ] || {
175 make_nics_Usage 1>&2; error "must give bridge";
176 return 1;
177 }
178
179 local owner="" ovsbrs="" tap="" tapnum="0" brtype="" bridge=""
180 [ "$(id -u)" = "0" ] || { error "must be root for make-nics"; return 1; }
181 owner="${SUDO_USER:-root}"
182 ovsbrs=""
183 if command -v ovs-vsctl >/dev/null 2>&1; then
184 out=$(ovs-vsctl list-br)
185 out=$(echo "$out" | sed "s/\n/,/")
186 ovsbrs=",$out,"
187 fi
188 for bridge in "$@"; do
189 [ "$bridge" = "user" ] && echo skip && continue
190 [ "${ovsbrs#*,${bridge},}" != "$ovsbrs" ] &&
191 btype="ovs" || btype="brctl"
192 tapnum=0;
193 while [ -e /sys/class/net/tapvm$tapnum ]; do tapnum=$(($tapnum+1)); done
194 tap="tapvm$tapnum"
195 debug 1 "creating $tap:$btype on $bridge" 1>&2
196 ip tuntap add mode tap user "$owner" "$tap" ||
197 { error "failed to create tap '$tap' for '$owner'"; return 1; }
198 ip link set "$tap" up 1>&2 || {
199 error "failed to bring up $tap";
200 ip tuntap del mode tap "$tap";
201 return 1;
202 }
203 if [ "$btype" = "ovs" ]; then
204 ovs-vsctl add-port "$bridge" "$tap" 1>&2 || {
205 error "failed: ovs-vsctl add-port $bridge $tap";
206 ovs-vsctl del-port "$bridge" "$tap"
207 return 1;
208 }
209 else
210 ip link set "$tap" master "$bridge" 1>&2 || {
211 error "failed to add tap '$tap' to '$bridge'"
212 ip tuntap del mode tap "$tap";
213 return 1
214 }
215 fi
216 echo "$tap:$btype"
217 done
218}
219
220ovs_cleanup() {
221 [ "$(id -u)" = "0" ] ||
222 { error "must be root for ovs-cleanup"; return 1; }
223 local item="" errors=0
224 # TODO: if get owner (SUDO_USERNAME) and if that isn't
225 # the owner, then do not delete.
226 for item in "$@"; do
227 name=${item#*:}
228 bridge=${item%:*}
229 ovs-vsctl del-port "$bridge" "$name" || errors=$((errors+1))
230 done
231 return $errors
232}
233
234quote_cmd() {
235 local quote='"' x="" vline=""
236 for x in "$@"; do
237 if [ "${x#* }" != "${x}" ]; then
238 if [ "${x#*$quote}" = "${x}" ]; then
239 x="\"$x\""
240 else
241 x="'$x'"
242 fi
243 fi
244 vline="${vline} $x"
245 done
246 echo "$vline"
247}
248
249get_bios_opts() {
250 # get_bios_opts(bios, uefi, nvram)
251 # bios is a explicit bios to boot.
252 # uefi is boolean indicating uefi
253 # nvram is optional and indicates that ovmf vars should be copied
254 # to that file if it does not exist. if it exists, use it.
255 local bios="$1" uefi="${2:-false}" nvram="$3"
256 local ovmf_dir="/usr/share/OVMF"
257 local bios_opts="" pflash_common="if=pflash,format=raw"
258 unset _RET
259 _RET=( )
260 if [ -n "$bios" ]; then
261 _RET=( -drive "${pflash_common},file=$bios" )
262 return 0
263 elif ! $uefi; then
264 return 0
265 fi
266
267 # ovmf in older releases (14.04) shipped only a single file
268 # /usr/share/ovmf/OVMF.fd
269 # newer ovmf ships split files
270 # /usr/share/OVMF/OVMF_CODE.fd
271 # /usr/share/OVMF/OVMF_VARS.fd
272 # with single file, pass only one file and read-write
273 # with split, pass code as readonly and vars as read-write
274 local joined="/usr/share/ovmf/OVMF.fd"
275 local code="/usr/share/OVMF/OVMF_CODE.fd"
276 local vars="/usr/share/OVMF/OVMF_VARS.fd"
277 local split="" nvram_src=""
278 if [ -e "$code" -o -e "$vars" ]; then
279 split=true
280 nvram_src="$vars"
281 elif [ -e "$joined" ]; then
282 split=false
283 nvram_src="$joined"
284 elif [ -n "$nvram" -a -e "$nvram" ]; then
285 error "WARN: nvram given, but did not find expected ovmf files."
286 error " assuming this is code and vars (OVMF.fd)"
287 split=false
288 else
289 error "uefi support requires ovmf bios: apt-get install -qy ovmf"
290 return 1
291 fi
292
293 if [ -n "$nvram" ]; then
294 if [ ! -f "$nvram" ]; then
295 cp "$nvram_src" "$nvram" ||
296 { error "failed copy $nvram_src to $nvram"; return 1; }
297 debug 1 "copied $nvram_src to $nvram"
298 fi
299 else
300 debug 1 "uefi without --uefi-nvram storage." \
301 "nvram settings likely will not persist."
302 nvram="${nvram_src}"
303 fi
304
305 if [ ! -w "$nvram" ]; then
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches