linecook-gem 0.2.0 → 0.2.1

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: 3c2ebac88ea5856749e3c19115a06aee40f9c258
4
- data.tar.gz: 21c9e7a2166694a3793813c82d0131963e3f7b78
3
+ metadata.gz: ad86918c27d3bed05ac3aaad743e427877835f97
4
+ data.tar.gz: 93df415c037673ac86283e8ae03f81e49c9b0dfa
5
5
  SHA512:
6
- metadata.gz: 73f4b086e94dcea9fe1bb9106becf8dcb6bee7293c16b07ed467301335dd3409996808e86fe2bd8abf0cbadfc0e0aa9330bd24e1abba274ea0e4da00c3429631
7
- data.tar.gz: 88b2c87c88f17445e74da4ad4c57ea6bd92b2ae3f41cd2e9989ffacebaee9f45172fa121f43ca72ca98d87ba49fc987139068675cb5784f176a984070658a621
6
+ metadata.gz: 7bf26a041fdf59d7380f5532e22eeaeb3d0b89aeb8f1e7f08cd57a6d4482e592868526f5e83c41a31b628a6004dc192849eb948703c16b1d32f1e45da5671293
7
+ data.tar.gz: 8a65d3ffa6bbe955e9280d11a0218326717b40a218d009c278cf4d729b4e144948791ca821b0520f4dbf7b94658a6e35938f9384d27be2e361b41d841eb2831c
@@ -4,8 +4,9 @@ require 'linecook/builder/manager'
4
4
  module Linecook
5
5
  class Build
6
6
  extend Forwardable
7
+ USERNAME = 'linecook'
7
8
 
8
- def_instance_delegators :@container, :stop, :start, :ip, :info
9
+ def_instance_delegators :@container, :start, :stop, :ip, :info
9
10
  attr_reader :type
10
11
 
11
12
  def initialize(name, tag: nil, image: nil, id: nil)
@@ -17,7 +18,7 @@ module Linecook
17
18
  end
18
19
 
19
20
  def ssh
20
- @ssh ||= Linecook::SSH.new(@container.ip, username: 'ubuntu', password: 'ubuntu', proxy: Linecook::Builder.ssh, keyfile: Linecook::SSH.private_key)
21
+ @ssh ||= Linecook::SSH.new(@container.ip, username: USERNAME, proxy: Linecook::Builder.ssh, keyfile: Linecook::SSH.private_key, setup: false)
21
22
  end
22
23
 
23
24
  def snapshot(save: false)
@@ -44,10 +44,11 @@ module Linecook
44
44
  execute("lxc-start #{container_str} -d") unless running?
45
45
  end
46
46
 
47
- def stop
47
+ def stop(clean: false)
48
48
  setup_dirs
49
+ cexec("sudo userdel -r -f #{Linecook::Build::USERNAME}") if @remote
49
50
  execute("lxc-stop #{container_str} -k") if running?
50
- unmount
51
+ unmount(clean: clean)
51
52
  end
52
53
 
53
54
  def ip
@@ -80,10 +81,23 @@ module Linecook
80
81
 
81
82
  private
82
83
 
84
+ def cexec(command)
85
+ execute("lxc-attach #{container_str} -- #{command}")
86
+ end
87
+
83
88
  def wait_running
84
89
  wait_for { running? }
85
90
  end
91
+
86
92
  def wait_ssh
93
+ if @remote
94
+ user = Linecook::Build::USERNAME
95
+ cexec("useradd -m -G sudo #{user}")
96
+ cexec("mkdir -p /home/#{user}/.ssh")
97
+ Linecook::Builder.ssh.upload(Linecook::SSH.public_key, "/tmp/#{@name}-pubkey")
98
+ Linecook::Builder.ssh.run("sudo mv /tmp/#{@name}-pubkey #{@root}/home/#{user}/.ssh/authorized_keys")
99
+ cexec("chown -R #{user} /home/#{user}/.ssh")
100
+ end
87
101
  wait_for { capture("lxc-attach -n #{@name} -P #{@home} status ssh || true") =~ /running/ }
88
102
  end
89
103
 
@@ -144,13 +158,15 @@ module Linecook
144
158
  execute("grep -q #{dest} /etc/mtab || sudo mount #{type} #{options} #{source} #{dest}")
145
159
  end
146
160
 
147
- def unmount
161
+ def unmount(clean: false)
148
162
  @socket_dirs.each { |sock| execute("umount #{sock}") }
163
+ source = capture("mount | grep #{@lower_dir} | awk '{print $1}'") if clean
149
164
  execute("umount #{@root}")
150
165
  execute("umount #{@upper_base}")
151
166
  execute("umount #{@lower_dir}")
152
167
  execute("rmdir #{@lower_dir}")
153
168
  execute("rmdir #{@upper_base}")
169
+ FileUtils.rm_f(source) if clean
154
170
  end
155
171
 
156
172
  def bridge_network
@@ -179,7 +195,6 @@ eos
179
195
  execute("lxc-attach -n #{@name} -P #{@home} ifup lxcbr0")
180
196
  end
181
197
 
182
-
183
198
  def setup_image
184
199
  @source_path = Linecook::ImageManager.fetch(@source_image, profile: :public)
185
200
  if @remote
@@ -36,6 +36,8 @@ module Linecook
36
36
  def decrypt_file(source, dest: nil, keypath: nil)
37
37
  dest ||= "/tmp/#{File.basename(source)}-decrypted"
38
38
  Tempfile.open('key') do |key|
39
+ key.write(@secret_key)
40
+ key.flush
39
41
  @remote.upload(@secret_key, key.path) if @remote
40
42
  capture("openssl enc -#{CIPHER} -out #{dest} -in #{source} -kfile #{key.path} -d", sudo: false)
41
43
  @remote.run("rm #{key.path}") if @remote
@@ -10,11 +10,20 @@ module Linecook
10
10
  IMAGE_PATH = File.join(Config::LINECOOK_HOME, 'images').freeze
11
11
  extend self
12
12
 
13
- def fetch(name, upgrade:false, profile: :private)
14
- image_name = Linecook.config[:image][:images][name][:name]
15
- path = File.join(IMAGE_PATH, image_name)
16
- url = provider(profile).url(name) unless File.exist?(path) || upgrade# FIXME
17
- Linecook::Downloader.download(url, path) unless File.exist?(path) || upgrade
13
+ def fetch(image, upgrade:false, profile: :private, type: nil, encrypted: false)
14
+ url_path = if image.is_a?(Symbol)
15
+ image_name = Linecook.config[:image][:images][image][:name]
16
+ path = File.join(IMAGE_PATH, image_name)
17
+ provider(profile).url(name) unless File.exist?(path) || upgrade
18
+ elsif image.is_a?(Hash)
19
+ profile = :private
20
+ encrypted = true
21
+ name = image[:name] == :latest ? File.basename(latest(image[:type])) : image[:name]
22
+ path = File.join([IMAGE_PATH, image[:type], name].compact)
23
+ provider(profile).url(name, type: image[:type])
24
+ end
25
+
26
+ Linecook::Downloader.download(url_path, path, encrypted: encrypted) unless File.exist?(path) || upgrade
18
27
  path
19
28
  end
20
29
 
@@ -16,7 +16,8 @@ module Linecook
16
16
  chef_version: chef_config[:version] || nil,
17
17
  first_boot: {
18
18
  run_list: role_config[:run_list]
19
- }
19
+ },
20
+ audit: Linecook.config[:provisioner][:chefzero][:audit]
20
21
  )
21
22
 
22
23
  puts "Establishing connection to build..."
@@ -10,18 +10,22 @@ module Linecook
10
10
  extend self
11
11
 
12
12
  def bake(name: nil, tag: nil, id: nil, snapshot: nil, upload: nil, package: nil, build: nil, keep: nil, clean: nil)
13
- build_agent = Linecook::Build.new(name, tag: tag, id: id)
13
+ build_agent = Linecook::Build.new(name, tag: tag, id: id, image: image(name))
14
14
  provider(name).provision(build_agent, name) if build
15
15
  snapshot = build_agent.snapshot(save: true) if snapshot || upload || package
16
16
  Linecook::ImageManager.upload(snapshot, type: build_agent.type) if upload || package
17
17
  Linecook::Packager.package(snapshot, type: build_agent.type) if package
18
18
  ensure
19
- build_agent.stop unless keep
19
+ build_agent.stop(clean: clean) unless keep
20
20
  FileUtils.rm_f(snapshot) if clean
21
21
  end
22
22
 
23
23
  private
24
24
 
25
+ def image(name)
26
+ Linecook.config[:roles][name.to_sym][:image]
27
+ end
28
+
25
29
  def provider(name)
26
30
  provisioner = Linecook.config[:roles][name.to_sym][:provisioner] || Linecook.config[:provisioner][:default_provider]
27
31
  case provisioner
@@ -29,6 +29,9 @@ module Linecook
29
29
  provisioner: {
30
30
  default_provider: :chefzero,
31
31
  default_image: :base_image,
32
+ chefzero: {
33
+ audit: true
34
+ }
32
35
  },
33
36
  image: {
34
37
  provider: {
@@ -77,7 +80,9 @@ module Linecook
77
80
 
78
81
  def setup
79
82
  FileUtils.mkdir_p(LINECOOK_HOME)
80
- File.write(DEFAULT_CONFIG_PATH, YAML.dump(DEFAULT_CONFIG)) unless File.exist?(DEFAULT_CONFIG_PATH)
83
+ config = {}
84
+ config.merge!(YAML.load(File.read(DEFAULT_CONFIG_PATH))) if File.exist?(DEFAULT_CONFIG_PATH)
85
+ File.write(DEFAULT_CONFIG_PATH, YAML.dump(DEFAULT_CONFIG.deep_merge(config)))
81
86
  check_perms if platform == 'darwin'
82
87
  end
83
88
 
@@ -4,11 +4,18 @@ require 'fileutils'
4
4
  require 'zip'
5
5
  require 'ruby-progressbar'
6
6
 
7
+ require 'linecook/image/crypt'
8
+
7
9
  module Linecook
8
10
  module Downloader
9
- def self.download(url, path)
11
+ LOCK_WAIT_TIMEOUT = 120
12
+
13
+ def self.download(url, path, encrypted: false)
14
+ acquire_lock(path)
10
15
  FileUtils.mkdir_p(File.dirname(path))
11
- File.open(path, 'w') do |f|
16
+ cryptfile = "#{File.basename(path)}-encrypted"
17
+ destination = encrypted ? File.join('/tmp', cryptfile) : path
18
+ File.open(destination, 'w') do |f|
12
19
  pbar = ProgressBar.create(title: File.basename(path), total: nil)
13
20
  IO.copy_stream(open(url,
14
21
  content_length_proc: lambda do|t|
@@ -18,8 +25,16 @@ module Linecook
18
25
  pbar.progress = s
19
26
  end), f)
20
27
  end
28
+
29
+ if encrypted
30
+ Linecook::Crypto.new.decrypt_file(destination, dest: path)
31
+ FileUtils.rm_f(destination)
32
+ end
33
+ ensure
34
+ unlock(path)
21
35
  end
22
36
 
37
+
23
38
  def self.unzip(source, dest: nil)
24
39
  puts "Extracting #{source}..."
25
40
  dest ||= File.dirname(source)
@@ -31,5 +46,32 @@ module Linecook
31
46
  end
32
47
  end
33
48
  end
49
+
50
+ private
51
+
52
+ def self.acquire_lock(path)
53
+ attempts = 0
54
+ while attempts < LOCK_WAIT_TIMEOUT
55
+ return lock(path) unless locked?(path)
56
+ attempts += 1
57
+ sleep(1)
58
+ end
59
+ end
60
+
61
+ def self.locked?(path)
62
+ File.exists?(lockfile(path)) && (true if Process.kill(0, File.read(lockfile(path))) rescue false)
63
+ end
64
+
65
+ def self.lock(path)
66
+ File.write(lockfile(path), Process.pid.to_s)
67
+ end
68
+
69
+ def self.unlock(path)
70
+ FileUtils.rm_f(lockfile(path))
71
+ end
72
+
73
+ def self.lockfile(path)
74
+ "/tmp/#{File.basename(path)}-flock"
75
+ end
34
76
  end
35
77
  end
@@ -76,14 +76,14 @@ module Linecook
76
76
  OpenSSL::Digest.new('md5',k.to_der).hexdigest.scan(/../).join(":")
77
77
  end
78
78
 
79
- def initialize(hostname, username: 'ubuntu', password: nil, keyfile: nil, proxy: nil)
79
+ def initialize(hostname, username: 'ubuntu', password: nil, keyfile: nil, proxy: nil, setup: true)
80
80
  @username = username
81
81
  @password = password
82
82
  @hostname = hostname
83
83
  @keyfile = keyfile
84
84
  @proxy = proxy_command(proxy) if proxy
85
85
  wait_for_connection
86
- setup_ssh_key if @keyfile
86
+ setup_ssh_key if @keyfile && setup
87
87
  end
88
88
 
89
89
  def forward(local, remote:nil)
@@ -1,3 +1,3 @@
1
1
  module Linecook
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
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.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dale Hamel
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.1.2
89
+ version: 0.1.4
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.1.2
96
+ version: 0.1.4
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: activesupport
99
99
  requirement: !ruby/object:Gem::Requirement