dock0 0.0.18 → 0.1.0
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/dock0.gemspec +5 -5
- data/lib/dock0.rb +2 -138
- data/lib/dock0/image.rb +120 -0
- data/spec/dock0_spec.rb +0 -11
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9afeb4b7bbfa1f902ce7bd38953bbb0525afa5ae
|
4
|
+
data.tar.gz: 99742d7ad4ab6957a0b4bafc2650883088fef914
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7ce4f31cf96516df77a9dd787f12ce96757730843c35429defbd8c33c125ff30d597a1b26ad00655b2d1fd6457d560ebd96cbe94a7bfe4a0543db4a2572cf87
|
7
|
+
data.tar.gz: 5c91c44a8b2e87622f210e75700837e99567cfac83fbf67efd8e4954dacd9e0abc04635e02e3295ab27366863fdfde37f27273c35ec1be9606d0208affa1dc16
|
data/dock0.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'dock0'
|
3
|
-
s.version = '0.0
|
3
|
+
s.version = '0.1.0'
|
4
4
|
s.date = Time.now.strftime("%Y-%m-%d")
|
5
5
|
|
6
6
|
s.summary = 'Builds a read-only Arch host for Docker'
|
@@ -14,9 +14,9 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.test_files = `git ls-files spec/*`.split
|
15
15
|
s.executables = ['dock0']
|
16
16
|
|
17
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
17
|
+
s.add_development_dependency 'rubocop', '~> 0.27.0'
|
18
18
|
s.add_development_dependency 'rake', '~> 10.3.2'
|
19
|
-
s.add_development_dependency 'coveralls', '~> 0.7.
|
20
|
-
s.add_development_dependency 'rspec', '~> 3.
|
21
|
-
s.add_development_dependency 'fuubar', '~> 2.0.0
|
19
|
+
s.add_development_dependency 'coveralls', '~> 0.7.1'
|
20
|
+
s.add_development_dependency 'rspec', '~> 3.1.0'
|
21
|
+
s.add_development_dependency 'fuubar', '~> 2.0.0'
|
22
22
|
end
|
data/lib/dock0.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'English'
|
4
|
-
|
5
1
|
##
|
6
2
|
# Dock0 provides an interface for building Arch images
|
7
3
|
module Dock0
|
@@ -13,138 +9,6 @@ module Dock0
|
|
13
9
|
Dock0::Image.new(*args)
|
14
10
|
end
|
15
11
|
end
|
16
|
-
|
17
|
-
##
|
18
|
-
# Default config for images
|
19
|
-
DEFAULT_CONFIG = {
|
20
|
-
'paths' => {
|
21
|
-
'device' => '/dev/xvdc',
|
22
|
-
'mount' => '/opt/target',
|
23
|
-
'build_file' => '/opt/build_file',
|
24
|
-
'build' => '/opt/build_file_mount',
|
25
|
-
'package_list' => './packages',
|
26
|
-
'overlay' => './overlay',
|
27
|
-
'scripts' => './scripts'
|
28
|
-
},
|
29
|
-
'root_size' => 512,
|
30
|
-
'fs' => {
|
31
|
-
'type' => 'ext4',
|
32
|
-
'flags' => '-F'
|
33
|
-
}
|
34
|
-
}
|
35
|
-
|
36
|
-
##
|
37
|
-
# An Image is an Arch system being built
|
38
|
-
class Image
|
39
|
-
attr_reader :device_path, :config, :stamp
|
40
|
-
|
41
|
-
##
|
42
|
-
# Make a new Image object with the given config
|
43
|
-
|
44
|
-
def initialize(*configs)
|
45
|
-
@config = configs.each_with_object(DEFAULT_CONFIG.dup) do |path, obj|
|
46
|
-
new = YAML.load(File.read(path))
|
47
|
-
next unless new
|
48
|
-
obj.merge! new
|
49
|
-
end
|
50
|
-
@stamp = Time.new.strftime '%F-%H%M'
|
51
|
-
end
|
52
|
-
|
53
|
-
def run(cmd)
|
54
|
-
results = `#{cmd} 2>&1`
|
55
|
-
return results if $CHILD_STATUS.success?
|
56
|
-
fail "Failed running #{cmd}:\n#{results}"
|
57
|
-
end
|
58
|
-
|
59
|
-
def run_chroot(cmd)
|
60
|
-
run "arch-chroot #{@config['paths']['build']} #{cmd}"
|
61
|
-
end
|
62
|
-
|
63
|
-
def prepare_device
|
64
|
-
puts "Making new filesystem on #{@config['paths']['device']}"
|
65
|
-
run "mkfs.ext4 -F #{@config['paths']['device']}"
|
66
|
-
puts "Mounting filesystem on #{@config['paths']['mount']}"
|
67
|
-
FileUtils.mkdir_p @config['paths']['mount']
|
68
|
-
run "mount #{@config['paths']['device']} #{@config['paths']['mount']}"
|
69
|
-
end
|
70
|
-
|
71
|
-
def prepare_root
|
72
|
-
puts "Making build FS at #{@config['paths']['build_file']}"
|
73
|
-
run "dd if=/dev/zero of=#{@config['paths']['build_file']} \
|
74
|
-
bs=1M count=#{@config['root_size']}"
|
75
|
-
mkfs = "mkfs.#{@config['fs']['type']} #{@config['fs']['flags']}"
|
76
|
-
run "#{mkfs} #{@config['paths']['build_file']}"
|
77
|
-
puts "Mounting FS at #{@config['paths']['build']}"
|
78
|
-
FileUtils.mkdir_p @config['paths']['build']
|
79
|
-
run "mount #{@config['paths']['build_file']} \
|
80
|
-
#{@config['paths']['build']}"
|
81
|
-
end
|
82
|
-
|
83
|
-
def install_packages
|
84
|
-
File.read(@config['paths']['package_list']).split("\n").each do |package|
|
85
|
-
puts "Installing #{package}"
|
86
|
-
run "pacstrap -G -M #{@config['paths']['build']} #{package}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def apply_overlay
|
91
|
-
puts "Applying overlay from #{@config['paths']['overlay']}"
|
92
|
-
overlay_path = @config['paths']['overlay'] + '/.'
|
93
|
-
FileUtils.cp_r overlay_path, @config['paths']['build']
|
94
|
-
File.open("#{@config['paths']['build']}/.stamp", 'w') do |fh|
|
95
|
-
fh.write @stamp
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def run_script(script)
|
100
|
-
Dir.chdir('.') { instance_eval File.read(script), script, 0 }
|
101
|
-
end
|
102
|
-
|
103
|
-
def run_scripts
|
104
|
-
Dir.glob(@config['paths']['scripts'] + '/*.rb').sort.each do |script|
|
105
|
-
puts "Running #{script}"
|
106
|
-
run_script script
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def run_commands
|
111
|
-
cmds = @config.fetch('commands', {})
|
112
|
-
cmds.fetch('chroot', []).each do |cmd|
|
113
|
-
puts "Running #{cmd} in chroot"
|
114
|
-
run_chroot cmd
|
115
|
-
end
|
116
|
-
cmds.fetch('host', []).each do |cmd|
|
117
|
-
puts "Running #{cmd} on host"
|
118
|
-
run cmd
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def finalize
|
123
|
-
puts 'Packing up root FS'
|
124
|
-
mount_path = @config['paths']['mount']
|
125
|
-
squash_path = "#{mount_path}/#{@stamp}.fs.sfs"
|
126
|
-
run "umount #{@config['paths']['build']}"
|
127
|
-
run "mksquashfs #{@config['paths']['build_file']} #{squash_path}"
|
128
|
-
File.symlink "#{@stamp}.fs.sfs", "#{mount_path}/root.fs.sfs"
|
129
|
-
end
|
130
|
-
|
131
|
-
def cleanup
|
132
|
-
puts 'Removing temporary build image'
|
133
|
-
File.unlink @config['paths']['build_file']
|
134
|
-
puts 'Unmounting target device'
|
135
|
-
run "umount #{@config['paths']['mount']}"
|
136
|
-
end
|
137
|
-
|
138
|
-
def easy_mode
|
139
|
-
prepare_device
|
140
|
-
prepare_root
|
141
|
-
install_packages
|
142
|
-
apply_overlay
|
143
|
-
run_scripts
|
144
|
-
run_commands
|
145
|
-
sleep 5
|
146
|
-
finalize
|
147
|
-
cleanup
|
148
|
-
end
|
149
|
-
end
|
150
12
|
end
|
13
|
+
|
14
|
+
require 'dock0/image'
|
data/lib/dock0/image.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'English'
|
4
|
+
|
5
|
+
##
|
6
|
+
# An Image is an Arch system being built
|
7
|
+
module Dock0
|
8
|
+
class Image
|
9
|
+
attr_reader :device_path, :config, :stamp
|
10
|
+
|
11
|
+
DEFAULT_CONFIG = {
|
12
|
+
'paths' => {
|
13
|
+
'build_file' => '/opt/build_file',
|
14
|
+
'build' => '/opt/build_file_mount',
|
15
|
+
'package_list' => './packages',
|
16
|
+
'overlay' => './overlay',
|
17
|
+
'scripts' => './scripts',
|
18
|
+
'output' => './root.fs.sfs'
|
19
|
+
},
|
20
|
+
'fs' => {
|
21
|
+
'size' => 512,
|
22
|
+
'type' => 'ext4',
|
23
|
+
'flags' => '-F'
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
##
|
28
|
+
# Make a new Image object with the given config
|
29
|
+
|
30
|
+
def initialize(*configs)
|
31
|
+
@config = configs.each_with_object(DEFAULT_CONFIG.dup) do |path, obj|
|
32
|
+
new = YAML.load(File.read(path))
|
33
|
+
next unless new
|
34
|
+
obj.merge! new
|
35
|
+
end
|
36
|
+
@paths = @config['paths']
|
37
|
+
end
|
38
|
+
|
39
|
+
def run(cmd)
|
40
|
+
results = `#{cmd} 2>&1`
|
41
|
+
return results if $CHILD_STATUS.success?
|
42
|
+
fail "Failed running #{cmd}:\n#{results}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_chroot(cmd)
|
46
|
+
run "arch-chroot #{@config['paths']['build']} #{cmd}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def prepare_root
|
50
|
+
build_file = @paths['build_file']
|
51
|
+
filesystem = @config['fs']
|
52
|
+
puts "Making build FS at #{build_file}"
|
53
|
+
run "dd if=/dev/zero of=#{build_file} bs=1M count=#{filesystem['size']}"
|
54
|
+
mkfs = "mkfs.#{filesystem['type']} #{filesystem['flags']}"
|
55
|
+
run "#{mkfs} #{build_file}"
|
56
|
+
puts "Mounting FS at #{@paths['build']}"
|
57
|
+
FileUtils.mkdir_p @paths['build']
|
58
|
+
run "mount #{build_file} #{@paths['build']}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def install_packages
|
62
|
+
File.read(@config['paths']['package_list']).split("\n").each do |package|
|
63
|
+
puts "Installing #{package}"
|
64
|
+
run "pacstrap -G -M #{@config['paths']['build']} #{package}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def apply_overlay
|
69
|
+
puts "Applying overlay from #{@config['paths']['overlay']}"
|
70
|
+
overlay_path = @config['paths']['overlay'] + '/.'
|
71
|
+
FileUtils.cp_r overlay_path, @config['paths']['build']
|
72
|
+
end
|
73
|
+
|
74
|
+
def run_script(script)
|
75
|
+
Dir.chdir('.') { instance_eval File.read(script), script, 0 }
|
76
|
+
end
|
77
|
+
|
78
|
+
def run_scripts
|
79
|
+
Dir.glob(@config['paths']['scripts'] + '/*.rb').sort.each do |script|
|
80
|
+
puts "Running #{script}"
|
81
|
+
run_script script
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_commands
|
86
|
+
cmds = @config.fetch('commands', {})
|
87
|
+
cmds.fetch('chroot', []).each do |cmd|
|
88
|
+
puts "Running #{cmd} in chroot"
|
89
|
+
run_chroot cmd
|
90
|
+
end
|
91
|
+
cmds.fetch('host', []).each do |cmd|
|
92
|
+
puts "Running #{cmd} on host"
|
93
|
+
run cmd
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def finalize
|
98
|
+
puts 'Packing up root FS'
|
99
|
+
squash_path = @config['paths']['output']
|
100
|
+
run "umount #{@config['paths']['build']}"
|
101
|
+
run "mksquashfs #{@config['paths']['build_file']} #{squash_path}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def cleanup
|
105
|
+
puts 'Removing temporary build image'
|
106
|
+
File.unlink @config['paths']['build_file']
|
107
|
+
end
|
108
|
+
|
109
|
+
def easy_mode
|
110
|
+
prepare_root
|
111
|
+
install_packages
|
112
|
+
apply_overlay
|
113
|
+
run_scripts
|
114
|
+
run_commands
|
115
|
+
sleep 5
|
116
|
+
finalize
|
117
|
+
cleanup
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/dock0_spec.rb
CHANGED
@@ -11,17 +11,6 @@ describe Dock0 do
|
|
11
11
|
describe Dock0::Image do
|
12
12
|
let(:image) { Dock0::Image.new 'spec/examples/image.yml' }
|
13
13
|
|
14
|
-
it 'loads stacked config files' do
|
15
|
-
config_image = Dock0::Image.new(
|
16
|
-
'spec/examples/alpha.yml', 'spec/examples/beta.yml'
|
17
|
-
)
|
18
|
-
result = { 'foo' => 'override', 'test' => 5, 'other' => 6 }
|
19
|
-
expect(config_image.config).to eql Dock0::DEFAULT_CONFIG.merge(result)
|
20
|
-
end
|
21
|
-
it 'has a timestamp' do
|
22
|
-
expect(Dock0::Image.new.stamp).to match(/\d{4}-\d{2}-\d{2}-\d{4}/)
|
23
|
-
end
|
24
|
-
|
25
14
|
describe '#run' do
|
26
15
|
it 'runs a command' do
|
27
16
|
expect(image.run('echo "hello"')).to eql "hello\n"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dock0
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Les Aker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.27.0
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.27.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,42 +44,42 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.7.
|
47
|
+
version: 0.7.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.7.
|
54
|
+
version: 0.7.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.
|
61
|
+
version: 3.1.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.
|
68
|
+
version: 3.1.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: fuubar
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.0.0
|
75
|
+
version: 2.0.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.0.0
|
82
|
+
version: 2.0.0
|
83
83
|
description: Generates a read-only Arch host for running Docker containers
|
84
84
|
email: me@lesaker.org
|
85
85
|
executables:
|
@@ -98,6 +98,7 @@ files:
|
|
98
98
|
- bin/dock0
|
99
99
|
- dock0.gemspec
|
100
100
|
- lib/dock0.rb
|
101
|
+
- lib/dock0/image.rb
|
101
102
|
- spec/dock0_spec.rb
|
102
103
|
- spec/examples/alpha.yml
|
103
104
|
- spec/examples/beta.yml
|