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