linecook-gem 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/linecook/bake.rb +9 -37
- data/lib/linecook/build.rb +1 -1
- data/lib/linecook/builder.rb +14 -2
- data/lib/linecook/chef.rb +107 -0
- data/lib/linecook/lxc.rb +11 -5
- data/lib/linecook/ssh.rb +7 -4
- data/lib/linecook/version.rb +1 -1
- data/man/LINECOOK.1 +8 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45514052292ba7f0031994394b15c5dab5447226
|
4
|
+
data.tar.gz: 94fdd52fe12e1c6720313ba221c3d9233a346c2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 131abec9715038d78fcd107060b77d13e62fef657f60d0471d045cd023aac2fa230e5a84c5bee4c0df68fecb02f080e7521a45e01a4cb9299aeb4a7439bc5d6c
|
7
|
+
data.tar.gz: 12ea95edd61ea70c354aca1ed08d272da115a146d354ee4ccbb897dfe2469c8b86b58d2da39c050cf535ad15ec5c3886d7874e48bde4db22d2807dd258c67cd7
|
data/lib/linecook/bake.rb
CHANGED
@@ -1,49 +1,21 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
|
3
|
-
require 'chef-provisioner'
|
4
|
-
require 'chefdepartie'
|
5
|
-
|
6
3
|
require 'linecook/build'
|
4
|
+
require 'linecook/chef'
|
7
5
|
|
8
6
|
module Linecook
|
9
7
|
module Baker
|
10
8
|
extend self
|
11
9
|
|
12
10
|
def bake
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
puts "Establishing connection to build..."
|
23
|
-
build = Linecook::Build.new('test', 'ubuntu-base.squashfs')
|
24
|
-
build.start
|
25
|
-
build.ssh.forward(chef_port)
|
26
|
-
build.ssh.upload(script, '/tmp/chef_bootstrap')
|
27
|
-
build.ssh.run('sudo bash /tmp/chef_bootstrap')
|
28
|
-
build.ssh.stop_forwarding
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def setup
|
34
|
-
ChefProvisioner::Config.setup(client: 'linecook', listen: 'localhost')
|
35
|
-
config = Linecook::Config.load_config
|
36
|
-
|
37
|
-
chef_config = config[:chef]
|
38
|
-
chef_config.merge!(node_name: "linecook-#{SecureRandom.uuid}",
|
39
|
-
chef_server_url: ChefProvisioner::Config.server)
|
40
|
-
# FIXME: sort out cache copying here for concurrent builds of different refs
|
41
|
-
Chefdepartie.run(background: true, config: chef_config, cache: '/tmp/linecook-cache')
|
42
|
-
chef_config
|
43
|
-
end
|
44
|
-
|
45
|
-
def chef_port
|
46
|
-
ChefProvisioner::Config.server.split(':')[-1].to_i
|
11
|
+
provisioner = 'chef' # FIXME HACK - read from config instead
|
12
|
+
build = Linecook::Build.new('test', 'ubuntu-base.squashfs') # FIXME - HACK, read from config
|
13
|
+
case provisioner
|
14
|
+
when 'chef'
|
15
|
+
Linecook::Chef.provision(build)
|
16
|
+
else
|
17
|
+
fail "Unsupported provisioner #{provisioner}"
|
18
|
+
end
|
47
19
|
end
|
48
20
|
end
|
49
21
|
end
|
data/lib/linecook/build.rb
CHANGED
@@ -15,7 +15,7 @@ module Linecook
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def ssh
|
18
|
-
@ssh ||= Linecook::SSH.new(@container.ip, username: 'ubuntu', password: 'ubuntu', proxy: Linecook::Builder.ssh)
|
18
|
+
@ssh ||= Linecook::SSH.new(@container.ip, username: 'ubuntu', password: 'ubuntu', proxy: Linecook::Builder.ssh, keyfile: Linecook::Builder.pemfile)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/linecook/builder.rb
CHANGED
@@ -29,6 +29,7 @@ module Linecook
|
|
29
29
|
extend Forwardable
|
30
30
|
BUILD_HOME = '/u/lxc'
|
31
31
|
|
32
|
+
attr_reader :pemfile
|
32
33
|
def_instance_delegators :backend, :stop, :ip, :info, :running?
|
33
34
|
|
34
35
|
def backend
|
@@ -43,7 +44,17 @@ module Linecook
|
|
43
44
|
|
44
45
|
def ssh
|
45
46
|
config = Linecook::Config.load_config[:builder]
|
46
|
-
@ssh ||=
|
47
|
+
@ssh ||= begin
|
48
|
+
userkey = File.expand_path("~/.ssh/id_rsa")
|
49
|
+
dedicated_key = File.join(Linecook::Config::LINECOOK_HOME, 'linecook_ssh.pem')
|
50
|
+
unless File.exists?(dedicated_key)
|
51
|
+
File.write(dedicated_key, SSHKey.generate.private_key)
|
52
|
+
FileUtils.chmod(0600, dedicated_key)
|
53
|
+
end
|
54
|
+
@pemfile = File.exists?(userkey) ? userkey : dedicated_key
|
55
|
+
puts @pemfile
|
56
|
+
SSH.new(ip, username: config[:username], password: config[:password], keyfile: @pemfile)
|
57
|
+
end
|
47
58
|
end
|
48
59
|
|
49
60
|
def builds
|
@@ -61,7 +72,8 @@ module Linecook
|
|
61
72
|
private
|
62
73
|
|
63
74
|
def setup_ssh
|
64
|
-
|
75
|
+
ssh
|
76
|
+
pubkey = SSHKey.new(File.read(@pemfile)).ssh_public_key
|
65
77
|
config = Linecook::Config.load_config[:builder]
|
66
78
|
ssh.run("mkdir -p /home/#{config[:username]}/.ssh")
|
67
79
|
ssh.upload(pubkey, "/home/#{config[:username]}/.ssh/authorized_keys")
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require 'chef-provisioner'
|
5
|
+
require 'chefdepartie'
|
6
|
+
|
7
|
+
module Linecook
|
8
|
+
module Chef
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def provision(build)
|
12
|
+
chef_config = setup
|
13
|
+
script = ChefProvisioner::Bootstrap.generate(
|
14
|
+
node_name: chef_config[:node_name],
|
15
|
+
chef_version: chef_config[:version] || nil,
|
16
|
+
first_boot: {
|
17
|
+
run_list: chef_config[:run_list]
|
18
|
+
}
|
19
|
+
)
|
20
|
+
|
21
|
+
puts "Establishing connection to build..."
|
22
|
+
build.start
|
23
|
+
build.ssh.forward(chef_port)
|
24
|
+
build.ssh.upload(script, '/tmp/chef_bootstrap')
|
25
|
+
build.ssh.run('sudo bash /tmp/chef_bootstrap')
|
26
|
+
build.ssh.stop_forwarding
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def setup
|
32
|
+
ChefProvisioner::Config.setup(client: 'linecook', listen: 'localhost')
|
33
|
+
config = Linecook::Config.load_config
|
34
|
+
|
35
|
+
chef_config = config[:chef]
|
36
|
+
chef_config.merge!(node_name: "linecook-#{SecureRandom.uuid}",
|
37
|
+
chef_server_url: ChefProvisioner::Config.server)
|
38
|
+
# FIXME: sort out cache copying here for concurrent builds of different refs
|
39
|
+
Chefdepartie.run(background: true, config: chef_config, cache: Cache.path)
|
40
|
+
chef_config
|
41
|
+
end
|
42
|
+
|
43
|
+
def chef_port
|
44
|
+
ChefProvisioner::Config.server.split(':')[-1].to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
# Required in order to have multiple builds run on different refs
|
48
|
+
module Cache
|
49
|
+
CACHE_PATH = File.join(Linecook::Config::LINECOOK_HOME, 'chefcache').freeze
|
50
|
+
PIDFILE = File.join(CACHE_PATH, 'pid')
|
51
|
+
STAMPFILE = File.join(CACHE_PATH, 'stamp')
|
52
|
+
STALE_THRESHOLD = 86400 # one day in seconds
|
53
|
+
|
54
|
+
extend self
|
55
|
+
|
56
|
+
def path
|
57
|
+
cache_path = Dir.mktmpdir
|
58
|
+
build
|
59
|
+
copy(cache_path)
|
60
|
+
cache_path
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def copy(cache_path)
|
66
|
+
FileUtils.copy_entry(CACHE_PATH, cache_path, preserve: true)
|
67
|
+
end
|
68
|
+
|
69
|
+
def build
|
70
|
+
if stale
|
71
|
+
puts 'Regenerating cookbook cache'
|
72
|
+
Chefdepartie.run(background: true, config: Linecook::Config.load_config[:chef], cache: CACHE_PATH)
|
73
|
+
Chefdepartie.stop
|
74
|
+
write_stamp
|
75
|
+
unlock
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def stale
|
80
|
+
return false if locked?
|
81
|
+
lock
|
82
|
+
old?
|
83
|
+
end
|
84
|
+
|
85
|
+
def locked?
|
86
|
+
File.exists?(PIDFILE) && (true if Process.kill(0, File.read(PIDFILE)) rescue false)
|
87
|
+
end
|
88
|
+
|
89
|
+
def lock
|
90
|
+
File.write(PIDFILE, Process.pid)
|
91
|
+
end
|
92
|
+
|
93
|
+
def unlock
|
94
|
+
FileUtils.rm_f(PIDFILE)
|
95
|
+
end
|
96
|
+
|
97
|
+
def old?
|
98
|
+
return true unless File.exists?(STAMPFILE)
|
99
|
+
(Time.now.to_i - File.read(STAMPFILE).to_i) > STALE_THRESHOLD
|
100
|
+
end
|
101
|
+
|
102
|
+
def write_stamp
|
103
|
+
File.write(STAMPFILE, Time.now.to_i)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/linecook/lxc.rb
CHANGED
@@ -7,6 +7,7 @@ require 'ipaddress'
|
|
7
7
|
module Linecook
|
8
8
|
module Lxc
|
9
9
|
class Container
|
10
|
+
MAX_WAIT = 60
|
10
11
|
attr_reader :config
|
11
12
|
def initialize(name: 'linecook', home: '/u/lxc', image: nil, remote: :local)
|
12
13
|
@remote = remote == :local ? false : remote
|
@@ -24,7 +25,7 @@ module Linecook
|
|
24
25
|
mount_all
|
25
26
|
write_config
|
26
27
|
execute("lxc-start #{container_str} -d")
|
27
|
-
|
28
|
+
wait_running
|
28
29
|
# Don't start a cgmanager if we're already in a container
|
29
30
|
execute('[ -f /etc/init/cgmanager.conf ] && sudo status cgmanager | grep -q running && sudo stop cgmanager || true') if lxc?
|
30
31
|
setup_bridge unless @remote
|
@@ -68,12 +69,17 @@ module Linecook
|
|
68
69
|
|
69
70
|
private
|
70
71
|
|
72
|
+
def wait_running
|
73
|
+
wait_for { running? }
|
74
|
+
end
|
71
75
|
def wait_ssh
|
72
|
-
running
|
73
|
-
|
76
|
+
wait_for { capture("lxc-attach -n #{@name} -P #{@home} status ssh || true") =~ /running/ }
|
77
|
+
end
|
78
|
+
|
79
|
+
def wait_for
|
74
80
|
attempts = 0
|
75
|
-
until
|
76
|
-
break if
|
81
|
+
until attempts > MAX_WAIT
|
82
|
+
break if yield
|
77
83
|
attempts += 1
|
78
84
|
sleep(1)
|
79
85
|
end
|
data/lib/linecook/ssh.rb
CHANGED
@@ -50,10 +50,11 @@ module Linecook
|
|
50
50
|
class SSH
|
51
51
|
|
52
52
|
attr_reader :username, :hostname
|
53
|
-
def initialize(hostname, username: 'ubuntu', password: nil, proxy: nil)
|
53
|
+
def initialize(hostname, username: 'ubuntu', password: nil, keyfile: nil, proxy: nil)
|
54
54
|
@username = username
|
55
55
|
@password = password
|
56
56
|
@hostname = hostname
|
57
|
+
@keyfile = keyfile
|
57
58
|
@proxy = proxy_command(proxy) if proxy
|
58
59
|
end
|
59
60
|
|
@@ -110,16 +111,18 @@ module Linecook
|
|
110
111
|
|
111
112
|
def linecook_host
|
112
113
|
@host ||= begin
|
113
|
-
|
114
114
|
host = SSHKit::Host.new(user: @username, hostname: @hostname)
|
115
115
|
host.password = @password if @password
|
116
|
-
|
116
|
+
opts = {}
|
117
|
+
opts.merge!({ proxy: @proxy }) if @proxy
|
118
|
+
opts.merge!({ keys: [@keyfile], auth_methods: %w(publickey password) }) if @keyfile
|
119
|
+
host.ssh_options = opts
|
117
120
|
host
|
118
121
|
end
|
119
122
|
end
|
120
123
|
|
121
124
|
def proxy_command(proxy)
|
122
|
-
ssh_command = "ssh #{proxy.username}@#{proxy.hostname} nc %h %p"
|
125
|
+
ssh_command = "ssh #{"-i #{@keyfile}" if @keyfile} #{proxy.username}@#{proxy.hostname} nc %h %p"
|
123
126
|
Net::SSH::Proxy::Command.new(ssh_command)
|
124
127
|
end
|
125
128
|
end
|
data/lib/linecook/version.rb
CHANGED
data/man/LINECOOK.1
CHANGED
@@ -7,7 +7,7 @@ linecook \- system image builder
|
|
7
7
|
linecook help [\fB\fCCOMMAND\fR]\- for specific command help
|
8
8
|
.SH DESCRIPTION
|
9
9
|
.PP
|
10
|
-
Linecook
|
10
|
+
Linecook builds system images utilizing overlayfs, squashfs, and linux containers via LXC. Currently, linecook only natively supports chef for provisioning, but using packer with a null resource, any of the mechanisms supported by packer are also supported by linecook.
|
11
11
|
.SH CONFIGURATION
|
12
12
|
.PP
|
13
13
|
Describe config file here once it's been determined
|
@@ -44,6 +44,13 @@ Linux 3.19 or greater with support for cgroups, and netfilter as described by lx
|
|
44
44
|
OS X 10.10 or later (Hypervisor.framework required for Xhyve)
|
45
45
|
.RE
|
46
46
|
.SH QUIRKS
|
47
|
+
.SS Xhyve
|
48
|
+
.RS
|
49
|
+
.IP \(bu 2
|
50
|
+
Xhyve requires root privileges until
|
51
|
+
\[la]https://github.com/mist64/xhyve/issues/60\[ra] is resolved. Linecook will setuid on the xhyve binary.
|
52
|
+
.RE
|
53
|
+
.SS Overlayfs
|
47
54
|
.RS
|
48
55
|
.IP \(bu 2
|
49
56
|
Overlayfs doesn't support unix domain sockets (yet), so anything using a unix domain socket outside of the /run tree should do manually symlink to /run.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linecook-gem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Hamel
|
@@ -205,6 +205,7 @@ files:
|
|
205
205
|
- lib/linecook/bake.rb
|
206
206
|
- lib/linecook/build.rb
|
207
207
|
- lib/linecook/builder.rb
|
208
|
+
- lib/linecook/chef.rb
|
208
209
|
- lib/linecook/cli.rb
|
209
210
|
- lib/linecook/config.rb
|
210
211
|
- lib/linecook/darwin_backend.rb
|
@@ -239,4 +240,3 @@ signing_key:
|
|
239
240
|
specification_version: 4
|
240
241
|
summary: Build system images using chef zero, LXC, and packer
|
241
242
|
test_files: []
|
242
|
-
has_rdoc:
|