kitchen-lxd_cli 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a65b448e80451e4143b9f1ef2eaf7bb0f5dab4f
4
- data.tar.gz: 7fffe1a9ddd489f45fcbe28b8dbf4a6afa49e9e9
3
+ metadata.gz: cd56e6cb62ec4b0bf4f099521e195d42bacb3a90
4
+ data.tar.gz: ee398952d35afd1145877c0e587a82b01f63195c
5
5
  SHA512:
6
- metadata.gz: e8817e841aa26dafd5e7c4bf4381875c10f9983a348d5a703a141cd62a98dcc41a9705f96fa37320065c0e9bf5def81f0bc7fff07fcb4337dcc993bf09f65e2c
7
- data.tar.gz: 76f04d46e7e53b667e9d846e1c27f5d86af5df6e83ef023f4a99adb6b2228a92f29caaf826607f6e63185a35051e329f127df0219bd7ef073d3d462b567032b7
6
+ metadata.gz: f842f5c0031c0dbaa23dc839f57905981bfbae95f436da9c55f5903b452e19cb342f455273adfd737c84e1980b081fe331b4150d90727bc4f7544933bc9893b4
7
+ data.tar.gz: 1f6180cb8e220ee0e86ea6da7b884ce083f1cd3d297b9eb6d816f2fa0936691924ae76f8917c780721a1134be0586de7ed8590d2781a3a7eb4d9a7bfb02076fe
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  *.swp
19
+ .kitchen/*
data/README.md CHANGED
@@ -1,18 +1,16 @@
1
1
  # <a name="title"></a> Kitchen::LxdCli
2
2
 
3
- A Test Kitchen Driver for LxdCli.
4
-
5
- At this point would NOT recommend using in Production.
3
+ A Test Kitchen Driver for LXD / LXC
6
4
 
7
5
  ## <a name="overview"></a> Overview
8
6
 
9
- This is a test-kitchen driver for lxd, which controls lxc. I named it LxdCli because this is my first plugin and I wanted to leave LXD driver name in case a more extensive project is put together.
7
+ This is a test-kitchen driver for lxd, which controls lxc. I named it LxdCli because this is my first plugin and I wanted to leave LXD driver name in case a more extensive project is put together. Although I've since added a lot more features than I originally planned.
10
8
 
11
- Basics are working. I'm running lxd --version 0.20 on ubuntu 15.10.
9
+ I'm running lxd --version 0.20 on ubuntu 15.10. NOTE: Networking options will not work LXD 0.21, 0.22 [Github Issue](https://github.com/lxc/lxd/issues/1259)
12
10
 
13
- I started the project because I really like the idea of developing containers, but kitchen-lxc wouldn't work with my version. I also tried docker but preferred how lxd is closer to a hypervisor virtual machine. For instance kitchen-docker my recipes that had worked on virtual machies for mongodb, the service would not start when using docker. Ultimately I was interested in LXD and there wasn't anything out there. I was quickly able to get my mongodb recipe working. I figured I'd clean things up, and some features and publish it. At least if someone like me wants to play with lxd, chef, test-kitchen they can test some basics without having to recreate the wheel.
11
+ I started the project because I really like the idea of developing containers, but kitchen-lxc wouldn't work with my version. I also tried docker but preferred how lxd is closer to a hypervisor virtual machine. For instance kitchen-docker my recipes that had worked on virtual machies for mongodb, the service would not start when using docker. I was able to get the service to start but liked the concept of system containers more than application containers. Ultimately I was interested in LXD and there wasn't anything out there. I was quickly able to get my mongodb recipe working. I figured I'd clean things up, and some features and publish it. Since then I've added numerous features, mainly with a focus on speeding up development of cookbooks, and exploring LXD.
14
12
 
15
- I AM VERY OPEN TO SUGGESTIONS/HELP. As I mentioned I haven't written a kitchen driver or published any ruby gems before so I was hesitant to even release it.
13
+ I AM VERY OPEN TO SUGGESTIONS / HELP. As I mentioned this is my first kitchen driver / published ruby gem.
16
14
 
17
15
  Minimal .kitchen.yml
18
16
  ```yaml
@@ -32,6 +30,17 @@ suites:
32
30
  attributes:
33
31
  ```
34
32
 
33
+ Recommended for Faster Development
34
+ ```yaml
35
+ ---
36
+ driver:
37
+ name: lxd_cli
38
+ image_name: my-ubuntu-image #Publish your own image, with base install. Including Chef.
39
+ verifier_path: "/opt/verifier"
40
+ lxd_proxy_install: true
41
+
42
+ ```
43
+
35
44
  All Options Shown .kitchen.yml
36
45
  ```yaml
37
46
  ---
@@ -56,12 +65,24 @@ driver:
56
65
  # lxd_proxy_update: true
57
66
  # lxd_proxy_path: "~/.lxd_proxy"
58
67
  # lxd_proxy_github_url: "-b development --single-branch https://github.com/bradenwright/cookbook-lxd_polipo
59
-
68
+ # enable_wait_for_ssh_login: true
69
+ mount:
70
+ rails_mongodb_app:
71
+ local_path: "/mylocalpath"
72
+ container_path: "/mnt/rails_mongodb_app"
60
73
  domain_name: localdomain
61
74
  dns_servers: ["8.8.8.8","8.8.4.4"]
62
75
  ipv4: 10.0.3.99/24
63
76
  ip_gateway: 10.0.3.1
77
+ verifier_path: "/opt/verifier"
64
78
  stop_instead_of_destroy: true
79
+ publish_image_name: "kitchen-base-ubuntu-1404"
80
+ use_publish_image: true
81
+ publish_image_before_destroy: true
82
+ publish_image_overwrite: true
83
+ enable_wait_for_ssh_login: false
84
+
85
+
65
86
 
66
87
  provisioner:
67
88
  name: chef_zero
@@ -128,6 +149,11 @@ Current config options:
128
149
  * ipv4
129
150
  * ip_gateway
130
151
  * never_destroy
152
+ * verifier_path
153
+ * publish_image_before_destroy
154
+ * publish_image_name
155
+ * publish_image_overwrite
156
+ * use_publish_image
131
157
  * lxd_proxy_install
132
158
  * lxd_proxy_destroy
133
159
  * lxd_proxy_verify
@@ -135,7 +161,7 @@ Current config options:
135
161
  * lxd_proxy_path
136
162
  * lxd_proxy_github_url
137
163
 
138
- public_key_path:
164
+ ### public_key_path
139
165
 
140
166
  can be manual set otherwise is derived by default based
141
167
  ~/.ssh/ directory, specifically the setting is derived by searching for:
@@ -146,54 +172,148 @@ can be manual set otherwise is derived by default based
146
172
 
147
173
  The public key at this location is copied to /root/.ssh in the lxc container to allow password less login.
148
174
 
149
- image_name:
175
+ `public_key_path: "/path/to/my/public/key"`
176
+
177
+ ### image_name
150
178
 
151
179
  Defaults to platform.name. Also note that if the image exists it will be used and will not be created. This allows a container to be published (image manually created).
152
180
 
153
- image_os:
181
+ `image_name: "my-container-image"`
182
+
183
+ ### image_os
154
184
 
155
185
  By default platform.name is split on "-" and the first element is used. E.G. platform.name = ubuntu-14.04 then image_os = ubuntu
156
186
 
157
- image_release:
187
+ `image_os: "ubuntu"`
188
+
189
+ ### image_release
158
190
 
159
191
  By default platform.name is split on "-" and the second element is used. E.G. platform.name = ubuntu-14.04 the image_release = 14.04 For ubuntu 14.04 is changed to release name, E.G. trusty, when image is being downloaded. For Ubuntu trusty, 14.04, 1404 will all result in the same image being used, it will just be named different depending. It may work for OS's other than ubuntu but have not tested
160
192
 
161
- profile:
193
+ `image_release: "trusty"`
194
+
195
+ ### profile
196
+
197
+ Default is Nil. See LXC documentation but a lxc profile can be specified. Which will be passed to "lxc init" command. A String or an Array are accepted.
162
198
 
163
- Default is Nil. See LXC documentation but a lxc profile can be specified. Which will be passed to "lxc init" command
199
+ `profile: "migratable"`
164
200
 
201
+ `profile: [ "default", "migratable" ]`
202
+
203
+
204
+ ### config
205
+
206
+ Default is Nil. See LXC documentation but a lxc config container key/value can be specified. [LXC Container Config Options](https://github.com/lxc/lxd/blob/master/specs/configuration.md#keyvalue-configuration-1). Config options are passed to "lxc init" command. A String or a Hash of key/value pairs is accepted.
207
+
208
+ `config: "limits.memory=2G"`
209
+
210
+ ```yaml
165
211
  config:
212
+ limits.memory: 1G
213
+ limits.cpus: 2
214
+ boot.autostart: true
215
+ ```
166
216
 
167
- Default is Nil. See LXC documentation but a lxc config container key/value can be specified. [LXC Container Config Options](https://github.com/lxc/lxd/blob/master/specs/configuration.md#keyvalue-configuration-1). Hash of config options is looped over and "lxc config set" command is run for each key/value pair.
217
+ ### mount
218
+ Default is Nil. Mount allows for local directories to be mounted inside the container. Must have the following format:
168
219
 
169
- domain_name:
220
+ ```yaml
221
+ mount:
222
+ myhome:
223
+ local_path: "<%= ENV['HOME'] %>"
224
+ container_path: "/mnt/myhome"
225
+ mymount2:
226
+ local_path: "/my/local/path"
227
+ container_path: "/my/container/path"
228
+ ```
170
229
 
171
- Default is nil.
230
+ You can mount however many directories you like. The kitchen-lxd_cli driver will run `lxc config device add <container> <name> disk <local_path>=<container_path>`
172
231
 
173
- dns_server:
232
+ ### domain_name
233
+
234
+ Default is nil. String can be provided
235
+
236
+ `domain_name: "mydomain.com"`
237
+
238
+ ### dns_server
174
239
 
175
240
  Default is nil. Which is used for dhcp, if a static ip is setup then dns servers need to be configured for chef to work. If a static ip is supplied and no dns_server is specified it will try to use the default gateway, google dns (e.g. 10.0.3.1, 8.8.8.8, 8.8.4.4). If a default gateway is not specified or can't be located then only google dns (8.8.8.8, 8.8.4.4) will be used. A hash of dns_servers may be specified instead.
176
241
 
177
- LXC NETWORKING OPTIONS: LXC by default uses 10.0.3.2/24 with a gateway of 10.0.3.1. You may use any ip space you wish, but LXD/LXC install sets up an ethernet bridge on 10.0.3.0/24 so make sure whatever network you choose to use is configured and accessible. In Ubuntu 15.10, LXD/LXC 0.20 configuration for networking is located at /etc/default/lxc-net, another option other than static ips is to setup dhcp host/ip mappings to reserve ips (described in /etc/default/lxc-net file comments) but it didn't seem to be working for me. You can also configure DHCP scope, etc. I've been using static ips from 10.0.3.0/24 and those ips have worked without needing to make changes to LXD/LXC configuration, although I did change the DHCP scope to allow space for static ip addresses (just to make sure there wasn't accidentally overlap)
242
+ `dns_servers: ["10.0.3.1", "8.8.8.8", "8.8.4.4"]`
243
+
244
+ ##### LXC NETWORKING OPTIONS
178
245
 
179
- ipv4:
246
+ LXC by default uses 10.0.3.2/24 with a gateway of 10.0.3.1. You may use any ip space you wish, but LXD/LXC install sets up an ethernet bridge on 10.0.3.0/24 so make sure whatever network you choose to use is configured and accessible. In Ubuntu 15.10, LXD/LXC 0.20 configuration for networking is located at /etc/default/lxc-net, another option other than static ips is to setup dhcp host/ip mappings to reserve ips (described in /etc/default/lxc-net file comments) but it didn't seem to be working for me. You can also configure DHCP scope, etc. I've been using static ips from 10.0.3.0/24 and those ips have worked without needing to make changes to LXD/LXC configuration, although I did change the DHCP scope to allow space for static ip addresses (just to make sure there wasn't accidentally overlap)
247
+
248
+ **NOTE: Networking options will not work LXD 0.21, 0.22 [Github Issue](https://github.com/lxc/lxd/issues/1259)**
249
+
250
+ ### ipv4
180
251
 
181
252
  Allows for Static IP/CIDR to be set, currently netmask is not supported. E.g. 10.0.3.100/24
182
253
 
183
- ip_gateway:
254
+ `ipv4: "10.0.3.99/24"`
255
+
256
+ ### ip_gateway
184
257
 
185
258
  Allows for a default gateway to be set. If ipv4 is used ip_gateway default value is 10.0.3.1, if dhcp is used then default gateway is given via dhcp. Default gateway is also used as a dns_server if static ips are used and no dns server is specified.
186
259
 
260
+ `ip_gateway: "10.0.3.1"`
187
261
 
188
- never_destroy:
262
+ ### never_destroy
189
263
 
190
264
  Default is false. Can be useful sometimes to keep machines intact. It allows kitchen destroy to stop container, kitchen create can be issued to start boxes if they are not running.
191
265
 
192
- lxd_proxy_install:
266
+ `never_destroy: true`
267
+
268
+ ### verifier_path
193
269
 
194
- Default is false. If true it installs polipo proxy by cloning into .lxd_proxy and running test kitchen in that directory. It only runs the first time unless you tell it to update. Also if the proxy already exists from another project, the existing container (named proxy-ubuntu-1404) will be used, started if necessary. Recommended use for testing would be to set this value to true and leave all others as defaults. It will significantly increase your test kitchen runs. But be sure to setup nodes in .kitchen.yml with normal proxy settings, e.g.
270
+ Default is nil. If nil, then normal setting are used, i.e. /tmp/verifier is the path. Since its in /tmp, it gets deleted on restart. I tried other options that I've found (BUT DIDN'T WORK), like:
195
271
 
196
272
  ```
273
+ # DID NOT WORK!!!
274
+ busser:
275
+ root_path: /opt/verifier
276
+ ```
277
+
278
+ Since that option isn't working set verifier_path will create a directory if its missing and create a symbolic link from /tmp/verifier to the directroy specified. This is particular usefuly when publishing an image. E.g.
279
+
280
+ `verifier_path: "/opt/verifier"`
281
+
282
+ This will save verifier gems to a permanent location, I publish a base install with verifier gems install in /opt/verifier. By publishing and using this image, everytime the container is created it doesn't have to go through the process of installing multiple gems (which can be a little slow, especially if you have to recreate boxes often).
283
+
284
+ ### publish_image_before_destroy
285
+
286
+ Default is false. If true, then after the container is stopped but before it is destroyed the container will be published as a local image.
287
+
288
+ `publish_image_before_destroy: true`
289
+
290
+ ### publish_image_name
291
+
292
+ Default is "kitchen-#{instance.name}", sets the name/alias for the lxc image
293
+
294
+ `publish_image_name: "my-published-image"`
295
+
296
+ ### publish_image_overwrite
297
+
298
+ Default is false. If true if an image of the same name exists, it will be deleted so the new image of the same name can be published.
299
+
300
+ `publish_image_overwrite: true`
301
+
302
+ ### use_publish_image
303
+
304
+ Default is false. If true then if the published_image_name exists as an lxc image it will be used to instead of using image name, or the image_name which is generated based on the instance.name
305
+
306
+ `use_publish_image: true`
307
+
308
+ ### lxd_proxy_install
309
+
310
+ Default is false. If true it installs polipo proxy by cloning into .lxd_proxy and running test kitchen in that directory. It only runs the first time unless you tell it to update. Also if the proxy already exists from another project, the existing container (named proxy-ubuntu-1404) will be used, started if necessary. Recommended use for testing would be to set this value to true and leave all others as defaults. It will significantly increase your test kitchen runs.
311
+
312
+ `lxd_proxy_install: true`
313
+
314
+ But be sure to setup nodes in .kitchen.yml with normal proxy settings, so the proxy is used
315
+
316
+ ```yaml
197
317
  provisioner:
198
318
  name: chef_zero
199
319
  http_proxy: http://10.0.3.5:8123
@@ -201,26 +321,48 @@ provisioner:
201
321
  chef_omnibus_url: http://www.chef.io/chef/install.sh
202
322
  ```
203
323
 
204
- lxd_proxy_destroy:
324
+ chef_omnibus_url of http is provided b/c it allows proxy to be utilized for chef install, with https (aka default) chef install is not utlizing proxy.
325
+
326
+ ### lxd_proxy_destroy
205
327
 
206
328
  Default is false. By default proxy is not destroyed and it is set to auto boot. This way after proxy is installed once, it should just be there and usable for all your cookbooks.
207
329
 
208
- lxd_proxy_verify:
330
+ `lxd_proxy_destroy: true`
331
+
332
+ ### lxd_proxy_verify
209
333
 
210
334
  Default is false. If false then kitchen converge command is used, which speeds up the process. If you want to run serverspec tests to ensure polipo is up set this value to true.
211
335
 
212
- lxd_proxy_update:
336
+ `lxd_proxy_verify: true`
337
+
338
+ ### lxd_proxy_update
213
339
 
214
340
  Default is false. Very little has been tested, and could be errors that one would manually have to deal with. But it attempts to pull from git, update berkshelf, re-run kitchen converge. Takes extra time but may come in useful. At this point I would recommend just destroying and recreating the lxd_proxy if there are any issues.
215
341
 
216
- lxd_proxy_path:
342
+ `lxd_proxy_update: true`
343
+
344
+ ### lxd_proxy_path
217
345
 
218
346
  Default is `~/.lxd_proxy` Path of where github gets cloned can be changed. That location is used so only 1 copy needs to exist on disk for all cookbook. But most of the disk space is the lxc container thats running the polipo proxy, container is named proxy-ubuntu-1404 by default.
219
347
 
220
- lxd_proxy_github_url:
348
+ `lxd_proxy_path: "/my/proxy/path"`
349
+
350
+ ### lxd_proxy_github_url
221
351
 
222
352
  Default is https://github.com/bradenwright/cookbook-lxd_polipo basically if can be overridden so that whatever repo is used. Idea being that someone can customize the polipo install I have setup. Or try to use a completely different type of proxy (not polipo) as long as the git-repo would create a proxy by running `bundle install` and `bundle exec kitchen converge`. Also if you don't want to use github if you setup a container named proxy-ubuntu-1404, ie `lxc info proxy-ubuntu-1404` returns a box it will be used.
223
353
 
354
+ ```yaml
355
+ lxd_proxy_github_url: "-b development --single-branch https://github.com/bradenwright/cookbook-lxd_polipo"
356
+ ```
357
+
358
+ ### enable_wait_for_ssh_login
359
+
360
+ Default is false. If set to true container will loop until it can login to ssh, this ensures that ssh is ready before kitchen moves on to converging. It's false by default b/c it slows things down, and I only seemed to need it after using publishing option. Specifically if I didn't remove /root/.ssh, if I did remove /root/.ssh before publishing, then the sleep/time to setup ssh_public_key seemed to wait long enough that kitchen converge was not timing out.
361
+
362
+ `enable_wait_for_ssh_login: true`
363
+
364
+ NOTE: Hope is that I can resolve the issues of needing to wait by writing a transport that uses lxc commands and not ssh, also will improve sped since ssh login is slow.
365
+
224
366
  ### <a name="config-require-chef-omnibus"></a> require\_chef\_omnibus
225
367
 
226
368
  Determines whether or not a Chef [Omnibus package][chef_omnibus_dl] will be
@@ -241,13 +383,16 @@ The default value is unset, or `nil`.
241
383
  * Update/Clean README
242
384
  * Config option for remote host, remote user, etc. So lxc can be launched on a remote server, not just locally
243
385
  * Config option to add remote for lxc, so images can be downloaded from other locations. Currently would have to manually be done in LXD/LXC
244
- * Config option to publish container on verify
245
- * Config option to install upstart (not used by default in containers)
246
386
  * Example chef cookbook which uses this driver to setup a multi-node web application
247
387
  * Allow specifying name of container
248
- * More thorough check to see if proxy exists, right now looking for directory
249
- * Ability to configure ip, maybe ram, etc too, for lxd_proxy_install (currently would need to be done manually, either via lxc or via .lxd_proxy/.kitchen.yml)
388
+ * Fix issue with installing proxy on first run and running multiple nodes with `kitchen converge -p`. Need a more thorough check to see if proxy exists, right now looking for directory. LXC shows box as running, also may want to run a check to make sure lxc shows same ip that is setup in .kitchen.yml file.
389
+ * Ability to configure options for lxd_proxy_install, such as: ip, maybe ram, etc (currently would need to be done manually, either via lxc or via .lxd_proxy/.kitchen.yml)
390
+ * Option for dhcp proxy, find ip proxy is running on in Kitchen driver and use it, by default instead of using 10.0.3.5.
250
391
  * Write a transport for lxd_cli, using ssh is a lot slower than using lxc commands
392
+ * Write ServerSpec tests. [kitchen-openstack]() and [kitchen-ec2]() have good examples.
393
+ * Update all licensing to Apache 2.0, or something else that free, some stuff may have defaulted differently. Also check [cookbook-lxd_polipo](https://github.com/bradenwright/cookbook-lxd_polipo)
394
+ * Ability to use snapshots, along with test-kitchen to speed up testing. Idea being if config option is set, then on destroy a snapshot will be taken. When kitchen create is run snapshot would be reverted. options: snapshot_name, snapshot_before_destroy, snapshot_revert_on_create
395
+ * Copy / Migrate on Destroy
251
396
 
252
397
  ## <a name="development"></a> Development
253
398
 
@@ -47,9 +47,10 @@ module Kitchen
47
47
 
48
48
  unless exists?
49
49
  image_name = create_image_if_missing
50
- profile = "-p #{config[:profile]}" if config[:profile]
50
+ profile_args = setup_profile_args if config[:profile]
51
+ config_args = setup_config_args if config[:config]
51
52
  info("Initializing container #{instance.name}")
52
- run_lxc_command("init #{image_name} #{instance.name} #{profile}")
53
+ run_lxc_command("init #{image_name} #{instance.name} #{profile_args} #{config_args}")
53
54
  end
54
55
 
55
56
  config_and_start_container unless running?
@@ -57,6 +58,11 @@ module Kitchen
57
58
  lxc_ip = wait_for_ip_address
58
59
  state[:hostname] = lxc_ip
59
60
  setup_ssh_access
61
+ wait_for_ssh_login(lxc_ip) if config[:enable_wait_for_ssh_login] == "true"
62
+ IO.popen("lxc exec #{instance.name} bash", "r+") do |p|
63
+ p.puts("if [ ! -d '#{config[:verifier_path]}' ]; then mkdir -p #{config[:verifier_path]}; fi")
64
+ p.puts("if [ ! -L '/tmp/verifier' ]; then ln -s #{config[:verifier_path]} /tmp/verifier; fi")
65
+ end if config[:verifier_path] && config[:verifier_path].length > 0
60
66
  end
61
67
 
62
68
  def destroy(state)
@@ -65,6 +71,9 @@ module Kitchen
65
71
  info("Stopping container #{instance.name}")
66
72
  run_lxc_command("stop #{instance.name}")
67
73
  end
74
+
75
+ publish_image if config[:publish_image_before_destroy]
76
+
68
77
  unless config[:never_destroy]
69
78
  info("Deleting container #{instance.name}")
70
79
  run_lxc_command("delete #{instance.name}") unless config[:never_destroy] && config[:never_destroy] == true
@@ -98,18 +107,19 @@ module Kitchen
98
107
  end
99
108
 
100
109
  def create_image_if_missing
101
- image_name = config[:image_name] ||= instance.platform.name
102
- `lxc image show #{image_name} > /dev/null 2>&1`
103
- if $?.to_i == 0
104
- debug("Image #{image_name} exists")
105
- else
106
- info("Image #{image_name} doesn't exist, creating now.")
110
+ image_name = get_image_name
111
+
112
+ unless image_exists?(image_name)
113
+ info("Creating image #{image_name} now.")
107
114
  image = get_image_info
108
- image_os = config[:image_os] ||= image[:os]
109
- image_release = config[:image_release] ||= image[:release]
115
+ image_os = config[:image_os]
116
+ image_os ||= image[:os]
117
+ image_release = config[:image_release]
118
+ image_release ||= image[:release]
110
119
  debug("Ran command: lxd-images import #{image_os} #{image_release} --alias #{image_name}")
111
120
  IO.popen("lxd-images import #{image_os} #{image_release} --alias #{image_name}", "w") { |pipe| puts pipe.gets rescue nil }
112
121
  end
122
+
113
123
  return image_name
114
124
  end
115
125
 
@@ -136,9 +146,54 @@ module Kitchen
136
146
  return image
137
147
  end
138
148
 
149
+ def publish_image
150
+ publish_image_name = get_publish_image_name
151
+ if image_exists?(publish_image_name)
152
+ if config[:publish_image_overwrite] == true
153
+ info("Deleting existing image #{publish_image_name}, so image of same name can be published")
154
+ run_lxc_command("image delete #{publish_image_name}")
155
+ else
156
+ raise "Image #{publish_image_name} already exists! If you wish to overwrite it set publish_image_overwrite: true in kitchen.yml"
157
+ end
158
+ end
159
+ info("Publishing image #{publish_image_name}")
160
+ run_lxc_command("publish #{instance.name} --alias #{publish_image_name}")
161
+ end
162
+
163
+ def get_image_name
164
+ image_name = get_publish_image_name
165
+ unless config[:use_publish_image] == true && image_exists?(image_name)
166
+ image_name = config[:image_name]
167
+ image_name ||= instance.platform.name
168
+ end
169
+
170
+ debug("Image Name is #{image_name}")
171
+ return image_name
172
+ end
173
+
174
+ def get_publish_image_name
175
+ publish_image_name = config[:publish_image_name]
176
+ publish_image_name ||= "kitchen-#{instance.name}"
177
+
178
+ debug("Publish Image Name is #{publish_image_name}")
179
+ return publish_image_name
180
+ end
181
+
182
+ def image_exists?(image_name)
183
+ `lxc image show #{image_name} > /dev/null 2>&1`
184
+ if $?.to_i == 0
185
+ debug("Image #{image_name} exists")
186
+ return true
187
+ else
188
+ debug("Image #{image_name} does not exist")
189
+ return false
190
+ end
191
+ end
192
+
139
193
  def config_and_start_container
140
194
  config[:ip_gateway] ||= "auto"
141
195
  arg_disable_dhcp = ""
196
+
142
197
  if config[:ipv4]
143
198
  IO.popen("bash", "r+") do |p|
144
199
  p.puts("echo -e \"lxc.network.type = veth\nlxc.network.name = eth0\nlxc.network.link = lxcbr0\nlxc.network.ipv4 = #{config[:ipv4]}\nlxc.network.ipv4.gateway = #{config[:ip_gateway]}\nlxc.network.flags = up\" | lxc config set #{instance.name} raw.lxc -")
@@ -146,14 +201,48 @@ module Kitchen
146
201
  end
147
202
  arg_disable_dhcp = "&& lxc exec #{instance.name} -- sed -i 's/dhcp/manual/g' /etc/network/interfaces.d/eth0.cfg"
148
203
  end
149
- # TODO: loop over/run all lxc config settings passed in or figure out how to use multiple with lxc init
150
- IO.popen("bash", "r+") do |p|
151
- config[:config].each do |key, value|
152
- p.puts("lxc config set #{instance.name} #{key} #{value}")
153
- end if config[:config]
154
- end
204
+
155
205
  info("Starting container #{instance.name}")
156
206
  run_lxc_command("start #{instance.name} #{arg_disable_dhcp}")
207
+ setup_mount_bindings if config[:mount].class == Hash
208
+ end
209
+
210
+ def setup_config_args
211
+ config_args = ""
212
+ if config[:config].class == String
213
+ config_args += " -c #{config[:config]}"
214
+ else
215
+ config[:config].each do |key, value|
216
+ config_args += " -c #{key}=#{value}"
217
+ end
218
+ end
219
+ if config[:mount].class == Hash
220
+ debug("security.privileged=true is added to Config Args, b/c its needed for mount binding")
221
+ config_args += " -c security.privileged=true"
222
+ end
223
+ debug("Config Args: #{config_args}")
224
+ return config_args
225
+ end
226
+
227
+ def setup_profile_args
228
+ profile_args = ""
229
+ if config[:profile].class == String
230
+ profile_args += " -p #{config[:profile]}"
231
+ else
232
+ config[:profile].each do |profile|
233
+ profile_args += " -p #{profile}"
234
+ end
235
+ end
236
+ debug("Profile Args: #{profile_args}")
237
+ return profile_args
238
+ end
239
+
240
+ def setup_mount_bindings
241
+ config[:mount].each do |mount_name, mount_binding|
242
+ if mount_name && mount_binding[:local_path] && mount_binding[:container_path]
243
+ run_lxc_command("config device add #{instance.name} #{mount_name} disk source=#{mount_binding[:local_path]} path=#{mount_binding[:container_path]}")
244
+ end
245
+ end if config[:mount].class == Hash
157
246
  end
158
247
 
159
248
  def configure_dns
@@ -194,41 +283,6 @@ module Kitchen
194
283
  p.puts("exit")
195
284
  end
196
285
  end
197
- =begin
198
- def configure_ip_via_lxc_restart
199
- debug("Configuring new ip address on eth0")
200
-
201
- IO.popen("lxc exec #{instance.name} bash", "r+") do |p|
202
- p.puts('echo -e "#############################################" > /etc/network/interfaces.d/eth0.cfg')
203
- p.puts('echo -e "# DO NOT EDIT CONTROLLED BY KITCHEN-LXC_CLI #" >> /etc/network/interfaces.d/eth0.cfg')
204
- p.puts('echo -e "#############################################" >> /etc/network/interfaces.d/eth0.cfg')
205
- p.puts('echo -e "auto eth0" >> /etc/network/interfaces.d/eth0.cfg')
206
- if config[:ipv4]
207
- config[:ip_gateway] ||= "10.0.3.1"
208
- config[:dns_servers] ||= [ "8.8.8.8", "8.8.4.4" ]
209
- p.puts('echo -e " iface eth0 inet static" >> /etc/network/interfaces.d/eth0.cfg')
210
- p.puts("echo -e \" address #{config[:ipv4]}\" >> /etc/network/interfaces.d/eth0.cfg")
211
- else
212
- p.puts('echo -e " iface eth0 inet dhcp" >> /etc/network/interfaces.d/eth0.cfg')
213
- end
214
- p.puts("echo -e \" gateway #{config[:ip_gateway]}\" >> /etc/network/interfaces.d/eth0.cfg") if config[:ip_gateway]
215
- config[:dns_servers].each do |dns_server|
216
- p.puts("echo -e \" dns-nameserver #{dns_server}\" >> /etc/network/interfaces.d/eth0.cfg")
217
- end if config[:dns_servers]
218
- if config[:domain_name]
219
- p.puts("echo -e \" dns-search #{config[:domain_name]}\" >> /etc/network/interfaces.d/eth0.cfg")
220
- end
221
- p.puts("exit")
222
- end
223
- debug("Finished configuring new ip address, restarting #{instance.name} for settings to take effect")
224
- debug_note_about_configuring_ip
225
- wait_for_ip_address
226
- sleep 3 # Was hanging more often than not whenever I lowered the sleep
227
- debug("Restarting #{instance.name}")
228
- run_lxc_command("restart #{instance.name}")
229
- debug("Finished restarting #{instance.name} ip address should be configured")
230
- end
231
- =end
232
286
 
233
287
  def setup_ssh_access
234
288
  info("Setting up public key #{config[:public_key_path]} on #{instance.name}")
@@ -307,6 +361,16 @@ module Kitchen
307
361
  debug("Found #{path}")
308
362
  end
309
363
 
364
+ def wait_for_ssh_login(ip)
365
+ begin
366
+ debug("Trying to login into #{ip} via SSH...")
367
+ `ssh root@#{ip} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no 'true' > /dev/null 2>&1`
368
+ break if $?.to_i == 0
369
+ sleep 0.3
370
+ end while true
371
+ debug("SSH is up, able to login at root@#{ip}")
372
+ end
373
+
310
374
  def run_lxc_command(cmd)
311
375
  run_local_command("lxc #{cmd}") if cmd
312
376
  end
@@ -320,6 +384,44 @@ module Kitchen
320
384
  def debug_note_about_configuring_ip
321
385
  debug("NOTE: Restarting seemed to be the only way I could get things to work. Tried lxc profiles, config options. Tried restart networking service but it didn't work, also tried passing command like ifconfig 10.0.3.x/24 eth0 up. Which set the ip but after container ran for a while, it would reset to dhcp address that had been assigned. Restarting container seems to be working, and is really fast. Open to better alternatives.")
322
386
  end
387
+
388
+
389
+ =begin
390
+ def configure_ip_via_lxc_restart
391
+ debug("Configuring new ip address on eth0")
392
+
393
+ IO.popen("lxc exec #{instance.name} bash", "r+") do |p|
394
+ p.puts('echo -e "#############################################" > /etc/network/interfaces.d/eth0.cfg')
395
+ p.puts('echo -e "# DO NOT EDIT CONTROLLED BY KITCHEN-LXC_CLI #" >> /etc/network/interfaces.d/eth0.cfg')
396
+ p.puts('echo -e "#############################################" >> /etc/network/interfaces.d/eth0.cfg')
397
+ p.puts('echo -e "auto eth0" >> /etc/network/interfaces.d/eth0.cfg')
398
+ if config[:ipv4]
399
+ config[:ip_gateway] ||= "10.0.3.1"
400
+ config[:dns_servers] ||= [ "8.8.8.8", "8.8.4.4" ]
401
+ p.puts('echo -e " iface eth0 inet static" >> /etc/network/interfaces.d/eth0.cfg')
402
+ p.puts("echo -e \" address #{config[:ipv4]}\" >> /etc/network/interfaces.d/eth0.cfg")
403
+ else
404
+ p.puts('echo -e " iface eth0 inet dhcp" >> /etc/network/interfaces.d/eth0.cfg')
405
+ end
406
+ p.puts("echo -e \" gateway #{config[:ip_gateway]}\" >> /etc/network/interfaces.d/eth0.cfg") if config[:ip_gateway]
407
+ config[:dns_servers].each do |dns_server|
408
+ p.puts("echo -e \" dns-nameserver #{dns_server}\" >> /etc/network/interfaces.d/eth0.cfg")
409
+ end if config[:dns_servers]
410
+ if config[:domain_name]
411
+ p.puts("echo -e \" dns-search #{config[:domain_name]}\" >> /etc/network/interfaces.d/eth0.cfg")
412
+ end
413
+ p.puts("exit")
414
+ end
415
+ debug("Finished configuring new ip address, restarting #{instance.name} for settings to take effect")
416
+ debug_note_about_configuring_ip
417
+ wait_for_ip_address
418
+ sleep 3 # Was hanging more often than not whenever I lowered the sleep
419
+ debug("Restarting #{instance.name}")
420
+ run_lxc_command("restart #{instance.name}")
421
+ debug("Finished restarting #{instance.name} ip address should be configured")
422
+ end
423
+ =end
424
+
323
425
  end
324
426
  end
325
427
  end
@@ -21,6 +21,6 @@ module Kitchen
21
21
  module Driver
22
22
 
23
23
  # Version string for LxdCli Kitchen driver
24
- LXD_CLI_VERSION = "0.1.3"
24
+ LXD_CLI_VERSION = "0.1.5"
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-lxd_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braden Wright
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-07 00:00:00.000000000 Z
11
+ date: 2015-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen
@@ -103,7 +103,6 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - ".cane"
105
105
  - ".gitignore"
106
- - ".kitchen/logs/kitchen.log"
107
106
  - ".tailor"
108
107
  - ".travis.yml"
109
108
  - CHANGELOG.md
@@ -1,26 +0,0 @@
1
- E, [2015-11-06T17:54:18.362107 #26784] ERROR -- Kitchen: ------Exception-------
2
- E, [2015-11-06T17:54:18.362275 #26784] ERROR -- Kitchen: Class: Kitchen::UserError
3
- E, [2015-11-06T17:54:18.362315 #26784] ERROR -- Kitchen: Message: Kitchen YAML file /home/braden/kitchen-lxd_cli/.kitchen.yml does not exist.
4
- E, [2015-11-06T17:54:18.362337 #26784] ERROR -- Kitchen: ------Backtrace-------
5
- E, [2015-11-06T17:54:18.362355 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/loader/yaml.rb:74:in `read'
6
- E, [2015-11-06T17:54:18.362373 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/config.rb:145:in `data'
7
- E, [2015-11-06T17:54:18.362391 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/config.rb:124:in `suites'
8
- E, [2015-11-06T17:54:18.362408 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/config.rb:175:in `filter_instances'
9
- E, [2015-11-06T17:54:18.362426 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/config.rb:134:in `build_instances'
10
- E, [2015-11-06T17:54:18.362443 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/config.rb:110:in `instances'
11
- E, [2015-11-06T17:54:18.362461 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/command.rb:115:in `filtered_instances'
12
- E, [2015-11-06T17:54:18.362478 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/command.rb:145:in `parse_subcommand'
13
- E, [2015-11-06T17:54:18.362495 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/command/list.rb:32:in `call'
14
- E, [2015-11-06T17:54:18.362512 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/cli.rb:56:in `perform'
15
- E, [2015-11-06T17:54:18.362552 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/cli.rb:108:in `list'
16
- E, [2015-11-06T17:54:18.362570 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
17
- E, [2015-11-06T17:54:18.362587 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
18
- E, [2015-11-06T17:54:18.362604 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/cli.rb:308:in `invoke_task'
19
- E, [2015-11-06T17:54:18.362621 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
20
- E, [2015-11-06T17:54:18.362638 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
21
- E, [2015-11-06T17:54:18.362655 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/bin/kitchen:13:in `block in <top (required)>'
22
- E, [2015-11-06T17:54:18.362672 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/lib/kitchen/errors.rb:154:in `with_friendly_errors'
23
- E, [2015-11-06T17:54:18.362689 #26784] ERROR -- Kitchen: /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/test-kitchen-1.4.2/bin/kitchen:13:in `<top (required)>'
24
- E, [2015-11-06T17:54:18.362706 #26784] ERROR -- Kitchen: /opt/chefdk/bin/kitchen:14:in `load'
25
- E, [2015-11-06T17:54:18.362723 #26784] ERROR -- Kitchen: /opt/chefdk/bin/kitchen:14:in `<main>'
26
- E, [2015-11-06T17:54:18.362739 #26784] ERROR -- Kitchen: ----------------------