docker-template 0.8.0 → 0.10.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/Gemfile +1 -1
- data/Rakefile +18 -20
- data/bin/docker-template +7 -10
- data/comp/list +7 -10
- data/comp/list.pak +0 -0
- data/lib/docker/template.rb +33 -30
- data/lib/docker/template/auth.rb +72 -0
- data/lib/docker/template/builder.rb +169 -81
- data/lib/docker/template/builder/normal.rb +58 -0
- data/lib/docker/template/builder/rootfs.rb +111 -0
- data/lib/docker/template/builder/scratch.rb +165 -0
- data/lib/docker/template/cache.rb +15 -20
- data/lib/docker/template/cli.rb +77 -20
- data/lib/docker/template/cli/build.rb +23 -8
- data/lib/docker/template/cli/list.rb +10 -10
- data/lib/docker/template/error.rb +12 -43
- data/lib/docker/template/logger.rb +99 -38
- data/lib/docker/template/{metadata.rb → meta.rb} +209 -114
- data/lib/docker/template/notify.rb +55 -12
- data/lib/docker/template/parser.rb +44 -35
- data/lib/docker/template/repo.rb +85 -81
- data/lib/docker/template/version.rb +1 -3
- data/lib/erb/context.rb +5 -8
- data/templates/rootfs/alpine.erb +65 -66
- data/templates/rootfs/ubuntu.erb +71 -42
- metadata +32 -12
- data/lib/docker/template/normal.rb +0 -46
- data/lib/docker/template/rootfs.rb +0 -85
- data/lib/docker/template/scratch.rb +0 -166
- data/shas.yml +0 -11
@@ -0,0 +1,58 @@
|
|
1
|
+
# Frozen-string-literal: true
|
2
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Encoding: utf-8
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Template
|
7
|
+
class Builder
|
8
|
+
class Normal < Builder
|
9
|
+
projects_allowed!
|
10
|
+
|
11
|
+
def teardown(img: false)
|
12
|
+
@img.delete "force" => true if @img && img
|
13
|
+
@context.rmtree if @context && \
|
14
|
+
@context.directory?
|
15
|
+
end
|
16
|
+
|
17
|
+
# --
|
18
|
+
|
19
|
+
def setup_context
|
20
|
+
@context = @repo.tmpdir
|
21
|
+
@copy = @context.join("copy")
|
22
|
+
copy_dockerfile
|
23
|
+
@copy.mkdir
|
24
|
+
end
|
25
|
+
|
26
|
+
# --
|
27
|
+
|
28
|
+
private
|
29
|
+
def copy_dockerfile
|
30
|
+
dockerfile = Template.project?? Template.root : @repo.root
|
31
|
+
dockerfile = dockerfile.join("Dockerfile").read
|
32
|
+
|
33
|
+
data = ERB::Context.new(:meta => @repo.meta)
|
34
|
+
data = ERB.new(dockerfile).result(data._binding)
|
35
|
+
context = @context.join("Dockerfile")
|
36
|
+
context.write(data)
|
37
|
+
end
|
38
|
+
|
39
|
+
# --
|
40
|
+
|
41
|
+
private
|
42
|
+
def cache_context
|
43
|
+
return unless @repo.cacheable?
|
44
|
+
return Cache.aliased_context(self) if alias?
|
45
|
+
Cache.context(self, @context)
|
46
|
+
end
|
47
|
+
|
48
|
+
class << self
|
49
|
+
def files
|
50
|
+
%w(
|
51
|
+
Dockerfile
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# Frozen-string-literal: true
|
2
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Encoding: utf-8
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Template
|
7
|
+
class Builder
|
8
|
+
class Rootfs < Builder
|
9
|
+
extend Forwardable::Extended
|
10
|
+
|
11
|
+
# --
|
12
|
+
|
13
|
+
def data
|
14
|
+
Template.get(:rootfs, {
|
15
|
+
:rootfs_base_img => @repo.meta["rootfs_base_img"]
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
# --
|
20
|
+
|
21
|
+
def discover
|
22
|
+
self.class.files.map do |file|
|
23
|
+
file = @repo.root.join(
|
24
|
+
file
|
25
|
+
)
|
26
|
+
|
27
|
+
if file.file?
|
28
|
+
then return file
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
"rootfs/#{
|
33
|
+
@repo.meta.rootfs_template
|
34
|
+
}"
|
35
|
+
end
|
36
|
+
|
37
|
+
# --
|
38
|
+
|
39
|
+
def builder_data
|
40
|
+
Template.get(discover, {
|
41
|
+
:meta => @repo.meta
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
# --
|
46
|
+
# During a simple copy you store all the data (including rootfs) data
|
47
|
+
# as a project unit, this helps us clean up data that is known to be for
|
48
|
+
# just the rootfs image and remove it so it doesn't impact.
|
49
|
+
# --
|
50
|
+
def simple_cleanup(dir)
|
51
|
+
file = dir.join("usr/local/bin/mkimg")
|
52
|
+
|
53
|
+
if file.exist?
|
54
|
+
then file.delete
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# --
|
59
|
+
|
60
|
+
def teardown(img: true)
|
61
|
+
@context.rmtree if @context && @context.directory?
|
62
|
+
@img.delete "force" => true if @img && img \
|
63
|
+
rescue nil
|
64
|
+
end
|
65
|
+
|
66
|
+
# --
|
67
|
+
|
68
|
+
private
|
69
|
+
def setup_context
|
70
|
+
@context = @repo.tmpdir("rootfs")
|
71
|
+
@copy = @context.join(@repo.meta["copy_dir"])
|
72
|
+
@context.join("Dockerfile").write(data)
|
73
|
+
|
74
|
+
@copy.join("usr/local/bin").mkdir_p
|
75
|
+
@copy.join("usr/local/bin/mkimg").write(builder_data)
|
76
|
+
@copy.join("usr/local/bin/mkimg").chmod(0755)
|
77
|
+
copy_rootfs
|
78
|
+
end
|
79
|
+
|
80
|
+
# --
|
81
|
+
|
82
|
+
private
|
83
|
+
def copy_rootfs
|
84
|
+
dir = @repo.copy_dir(
|
85
|
+
"rootfs"
|
86
|
+
)
|
87
|
+
|
88
|
+
if dir.exist?
|
89
|
+
@repo.copy_dir("rootfs").safe_copy(@copy, {
|
90
|
+
:root => Template.root
|
91
|
+
})
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def sub?
|
97
|
+
return true
|
98
|
+
end
|
99
|
+
|
100
|
+
# --
|
101
|
+
|
102
|
+
def files
|
103
|
+
%w(
|
104
|
+
Rootfs.erb Rootfs rootfs.erb rootfs
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# Frozen-string-literal: true
|
2
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Encoding: utf-8
|
4
|
+
|
5
|
+
module Docker
|
6
|
+
module Template
|
7
|
+
class Builder
|
8
|
+
class Scratch < Builder
|
9
|
+
attr_reader :rootfs
|
10
|
+
|
11
|
+
# --
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
super; @rootfs = Rootfs.new(
|
15
|
+
repo
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
# --
|
20
|
+
|
21
|
+
def data
|
22
|
+
Template.get(:scratch, {
|
23
|
+
:entrypoint => @repo.meta.entry,
|
24
|
+
:maintainer => @repo.meta.maintainer,
|
25
|
+
:tar_gz => @tar_gz.basename
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
# --
|
30
|
+
|
31
|
+
def teardown(img: false)
|
32
|
+
@copy.rm_rf if @copy
|
33
|
+
@context.rm_rf if @context
|
34
|
+
@tar_gz.rm_rf if @tar_gz
|
35
|
+
|
36
|
+
if @img && img
|
37
|
+
then @img.delete({
|
38
|
+
"force" => true
|
39
|
+
})
|
40
|
+
end
|
41
|
+
rescue Docker::Error::NotFoundError
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# --
|
46
|
+
|
47
|
+
private
|
48
|
+
def setup_context
|
49
|
+
@context = @repo.tmpdir
|
50
|
+
@tar_gz = @repo.tmpfile "archive", ".tar.gz", root: @context
|
51
|
+
@copy = @repo.tmpdir "copy"
|
52
|
+
copy_dockerfile
|
53
|
+
end
|
54
|
+
|
55
|
+
# --
|
56
|
+
|
57
|
+
private
|
58
|
+
def copy_dockerfile
|
59
|
+
data = self.data % @tar_gz.basename
|
60
|
+
dockerfile = @context.join("Dockerfile")
|
61
|
+
dockerfile.write(data)
|
62
|
+
end
|
63
|
+
|
64
|
+
# --
|
65
|
+
|
66
|
+
def copy_cleanup
|
67
|
+
@rootfs.simple_cleanup(
|
68
|
+
@copy
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
# --
|
73
|
+
|
74
|
+
def verify_context
|
75
|
+
if @repo.buildable? && @tar_gz.zero?
|
76
|
+
raise Error::InvalidTargzFile, @tar_gz
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# --
|
81
|
+
|
82
|
+
private
|
83
|
+
def build_context
|
84
|
+
return unless @repo.buildable?
|
85
|
+
@rootfs.build
|
86
|
+
|
87
|
+
logger = Logger.new
|
88
|
+
img = Container.create(create_args)
|
89
|
+
img.start.attach(logger_opts, &logger.method(logger_type))
|
90
|
+
status = img.json["State"]["ExitCode"]
|
91
|
+
|
92
|
+
if status != 0
|
93
|
+
logger.simple(:stderr, img.logs(:stderr => true)) unless logger.output?
|
94
|
+
logger.simple(:stdout, img.logs(:stdout => true)) unless logger.output?
|
95
|
+
raise Error::BadExitStatus, status
|
96
|
+
end
|
97
|
+
ensure
|
98
|
+
if img
|
99
|
+
then img.tap(&:stop).delete({
|
100
|
+
"force" => true
|
101
|
+
})
|
102
|
+
end
|
103
|
+
|
104
|
+
@rootfs.teardown
|
105
|
+
end
|
106
|
+
|
107
|
+
# --
|
108
|
+
|
109
|
+
private
|
110
|
+
def logger_type
|
111
|
+
@repo.meta["tty"] ? :tty : :simple
|
112
|
+
end
|
113
|
+
|
114
|
+
# --
|
115
|
+
|
116
|
+
private
|
117
|
+
def logger_opts
|
118
|
+
return {
|
119
|
+
:tty => @repo.meta["tty"], :stdout => true, :stderr => true
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
# --
|
124
|
+
|
125
|
+
private
|
126
|
+
def create_args
|
127
|
+
name = ["rootfs", @repo.name, @repo.tag, "image"].join("-")
|
128
|
+
env = @repo.to_env(:tar_gz => @tar_gz, :copy_dir => @copy)
|
129
|
+
|
130
|
+
return {
|
131
|
+
"Env" => env.to_a,
|
132
|
+
"Tty" => @repo.meta["tty"],
|
133
|
+
"Image" => @rootfs.img.id,
|
134
|
+
"Name" => name,
|
135
|
+
|
136
|
+
"HostConfig" => {
|
137
|
+
"Binds" => [
|
138
|
+
"#{@copy}:#{@copy}", "#{@tar_gz}:#{@tar_gz}"
|
139
|
+
]
|
140
|
+
},
|
141
|
+
|
142
|
+
"Volumes" => {
|
143
|
+
@copy.to_s => {
|
144
|
+
"source" => @copy.to_s,
|
145
|
+
"destination" => @copy.to_s
|
146
|
+
},
|
147
|
+
|
148
|
+
@tar_gz.to_s => {
|
149
|
+
"source" => @tar_gz.to_s,
|
150
|
+
"destination" => @tar_gz.to_s
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
class << self
|
157
|
+
def files
|
158
|
+
return Rootfs \
|
159
|
+
.files
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -1,17 +1,15 @@
|
|
1
|
-
# ----------------------------------------------------------------------------
|
2
1
|
# Frozen-string-literal: true
|
3
2
|
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
4
3
|
# Encoding: utf-8
|
5
|
-
# ----------------------------------------------------------------------------
|
6
4
|
|
7
5
|
module Docker
|
8
6
|
module Template
|
9
7
|
module Cache
|
10
8
|
module_function
|
11
9
|
|
12
|
-
#
|
10
|
+
# --
|
13
11
|
# Cache the context into the cache directory.
|
14
|
-
#
|
12
|
+
# --
|
15
13
|
|
16
14
|
def context(builder, context)
|
17
15
|
builder.repo.cache_dir.rm_rf
|
@@ -19,15 +17,16 @@ module Docker
|
|
19
17
|
cache_dir = builder.repo.cache_dir
|
20
18
|
cache_dir.parent.mkdir_p
|
21
19
|
|
22
|
-
readme(builder)
|
23
20
|
context.cp_r(cache_dir.tap(
|
24
21
|
&:rm_rf
|
25
22
|
))
|
23
|
+
|
24
|
+
readme(builder)
|
26
25
|
end
|
27
26
|
|
28
|
-
#
|
27
|
+
# --
|
29
28
|
# rubocop:disable Metrics/LineLength
|
30
|
-
#
|
29
|
+
# --
|
31
30
|
|
32
31
|
def aliased_context(builder)
|
33
32
|
if builder.aliased_repo.cache_dir.exist?
|
@@ -38,18 +37,18 @@ module Docker
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
#
|
40
|
+
# --
|
42
41
|
# Cleanup the context caches, removing the caches we no longer need.
|
43
|
-
# ----------------------------------------------------------------------
|
44
42
|
# rubocop:enable Metrics/LineLength
|
45
|
-
#
|
43
|
+
# --
|
46
44
|
|
47
45
|
def cleanup(repo)
|
46
|
+
return unless repo.clean_cache?
|
48
47
|
cache_dir = repo.cache_dir.parent
|
49
48
|
|
50
|
-
if
|
51
|
-
|
52
|
-
next unless repo.
|
49
|
+
if cache_dir.exist?
|
50
|
+
cache_dir.children.each do |file|
|
51
|
+
next unless repo.meta.tags.include?(file.basename)
|
53
52
|
$stdout.puts Simple::Ansi.yellow(format("Removing %s.",
|
54
53
|
file.relative_path_from(Template.root)
|
55
54
|
))
|
@@ -59,17 +58,13 @@ module Docker
|
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
|
-
#
|
61
|
+
# --
|
63
62
|
# Note: We normally expect but do not require you to have a README.
|
64
63
|
# Search for and copy the readme if available.
|
65
|
-
#
|
64
|
+
# --
|
66
65
|
|
67
66
|
def readme(builder)
|
68
|
-
file = builder.repo.root.children.find
|
69
|
-
val =~ /readme/i
|
70
|
-
end
|
71
|
-
|
72
|
-
return unless file
|
67
|
+
return unless file = builder.repo.root.children.find { |val| val =~ /readme/i }
|
73
68
|
file.safe_copy(builder.repo.cache_dir, {
|
74
69
|
:root => file.parent
|
75
70
|
})
|
data/lib/docker/template/cli.rb
CHANGED
@@ -1,46 +1,98 @@
|
|
1
|
-
# ----------------------------------------------------------------------------
|
2
1
|
# Frozen-string-literal: true
|
3
2
|
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
4
3
|
# Encoding: utf-8
|
5
|
-
# ----------------------------------------------------------------------------
|
6
4
|
|
5
|
+
require "docker/template"
|
7
6
|
require "thor"
|
8
7
|
|
9
8
|
module Docker
|
10
9
|
module Template
|
11
10
|
class CLI < Thor
|
12
|
-
autoload :Build, "docker/template/cli/build"
|
13
|
-
autoload :List, "docker/template/cli/list"
|
14
11
|
|
15
|
-
#
|
12
|
+
# --
|
13
|
+
|
14
|
+
option :force, :type => :boolean, :desc => "Force caching."
|
15
|
+
desc "cache [REPOS [OPTS]]", "Cache all (or some) of your repositories."
|
16
|
+
option :clean, :type => :boolean, :desc => "Cleanup your caches."
|
17
|
+
option :help, :type => :boolean, :desc => "Output this."
|
18
|
+
|
19
|
+
# --
|
20
|
+
|
21
|
+
def cache(*args)
|
22
|
+
return help(__method__) if options.help?
|
23
|
+
self.options = options.merge(:cache => true) if options.force?
|
24
|
+
self.options = options.merge(:cache_only => true)
|
25
|
+
return build(
|
26
|
+
*args
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
# --
|
31
|
+
|
32
|
+
option :force, :type => :boolean, :desc => "Force cleaning."
|
33
|
+
desc "clean [REPOS [OPTS]]", "Clean all (or some) of your repositories caches."
|
34
|
+
option :help, :type => :boolean, :desc => "Output this."
|
35
|
+
|
36
|
+
# --
|
37
|
+
|
38
|
+
def clean(*args)
|
39
|
+
return help(__method__) if options.help?
|
40
|
+
self.options = options.merge(:clean => true) if options.force?
|
41
|
+
self.options = options.merge(:clean_only => true)
|
42
|
+
return build(
|
43
|
+
*args
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
# --
|
48
|
+
|
49
|
+
option :force, :type => :boolean, :desc => "Force cleaning."
|
50
|
+
desc "push [REPOS [OPTS]]", "Push all (or some) of your repositories."
|
51
|
+
option :help, :type => :boolean, :desc => "Output this."
|
52
|
+
|
53
|
+
# --
|
54
|
+
|
55
|
+
def push(*args)
|
56
|
+
return help(__method__) if options.help?
|
57
|
+
self.options = options.merge(:push => true) if options.force?
|
58
|
+
self.options = options.merge(:push_only => true)
|
59
|
+
return build(
|
60
|
+
*args
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# --
|
16
65
|
# docker-template build [repos [opts]]
|
17
|
-
#
|
66
|
+
# --
|
18
67
|
|
19
|
-
desc "build [REPOS [OPTS]]", "Build all (or some) of your repositories"
|
20
|
-
option :diff, :type => :boolean, :desc => "Build only modified repositories."
|
21
|
-
option :cache_only, :type => :boolean, :desc => "Only cache your repositories, don't build."
|
22
|
-
option :clean_only, :type => :boolean, :desc => "Only clean your repositories, don't build."
|
23
|
-
option :push_only, :type => :boolean, :desc => "Only push your repositories, don't build."
|
68
|
+
desc "build [REPOS [OPTS]]", "Build all (or some) of your repositories."
|
24
69
|
option :profile, :type => :boolean, :desc => "Profile Memory."
|
25
70
|
option :tty, :type => :boolean, :desc => "Enable TTY Output."
|
26
|
-
option :push, :type => :boolean, :desc => "Push Repo After Building."
|
27
71
|
option :cache, :type => :boolean, :desc => "Cache your repositories to cache."
|
28
|
-
option :
|
72
|
+
option :exclude, :type => :array, :desc => "Build everything except for these images."
|
73
|
+
option :debug, :type => :boolean, :desc => "Send the DEBUG=true env var to your instance."
|
74
|
+
option :diff, :type => :boolean, :desc => "Build only modified repositories."
|
75
|
+
option :push, :type => :boolean, :desc => "Push Repo After Building."
|
29
76
|
option :clean, :type => :boolean, :desc => "Cleanup your caches."
|
77
|
+
option :force, :type => :boolean, :desc => "Force your build."
|
78
|
+
option :squash, :type => :boolean, :desc => "Squash the build."
|
79
|
+
option :help, :type => :boolean, :desc => "Output this."
|
30
80
|
|
31
|
-
#
|
81
|
+
# --
|
32
82
|
# rubocop:disable Lint/RescueException
|
33
|
-
#
|
83
|
+
# --
|
34
84
|
|
35
85
|
def build(*args)
|
36
|
-
|
86
|
+
return help(__method__) if options.help?
|
87
|
+
Build.new(args, options)
|
88
|
+
.start
|
37
89
|
|
38
90
|
rescue Docker::Template::Error::StandardError => e
|
39
91
|
$stderr.puts Simple::Ansi.red(e.message)
|
40
92
|
exit e.respond_to?(:status) ? \
|
41
93
|
e.status : 1
|
42
94
|
|
43
|
-
rescue Exception
|
95
|
+
rescue Exception => _e
|
44
96
|
raise unless $ERROR_POSITION
|
45
97
|
$ERROR_POSITION.delete_if do |source|
|
46
98
|
source =~ %r!#{Regexp.escape(
|
@@ -49,16 +101,18 @@ module Docker
|
|
49
101
|
end
|
50
102
|
end
|
51
103
|
|
52
|
-
#
|
104
|
+
# --
|
53
105
|
# rubocop:enable Lint/RescueException
|
54
106
|
# docker-template list [options]
|
55
|
-
#
|
107
|
+
# --
|
56
108
|
|
109
|
+
option :help, :type => :boolean, :desc => "Output this."
|
57
110
|
desc "list [OPTS]", "List all possible builds."
|
58
111
|
|
59
|
-
#
|
112
|
+
# --
|
60
113
|
|
61
114
|
def list
|
115
|
+
return help(__method__) if options.help?
|
62
116
|
return $stdout.puts(
|
63
117
|
List.build
|
64
118
|
)
|
@@ -66,3 +120,6 @@ module Docker
|
|
66
120
|
end
|
67
121
|
end
|
68
122
|
end
|
123
|
+
|
124
|
+
require "docker/template/cli/build"
|
125
|
+
require "docker/template/cli/list"
|