docker-template 0.2.0 → 0.3.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 +30 -4
- data/LICENSE +1 -1
- data/README.md +79 -14
- data/Rakefile +115 -38
- data/bin/docker-template +24 -10
- data/comp/bin +9 -0
- data/comp/list +83 -0
- data/comp/list.pak +0 -0
- data/lib/docker/template.rb +47 -61
- data/lib/docker/template/builder.rb +302 -0
- data/lib/docker/template/cache.rb +71 -0
- data/lib/docker/template/cli.rb +125 -0
- data/lib/docker/template/error.rb +120 -11
- data/lib/docker/template/logger.rb +128 -0
- data/lib/docker/template/metadata.rb +566 -103
- data/lib/docker/template/normal.rb +46 -0
- data/lib/docker/template/notify.rb +44 -0
- data/lib/docker/template/parser.rb +48 -38
- data/lib/docker/template/repo.rb +131 -97
- data/lib/docker/template/rootfs.rb +51 -41
- data/lib/docker/template/scratch.rb +96 -66
- data/lib/docker/template/version.rb +4 -2
- data/lib/erb/context.rb +29 -0
- data/shas.yml +11 -0
- data/templates/rootfs.erb +5 -0
- data/templates/rootfs/alpine.erb +71 -0
- data/templates/rootfs/ubuntu.erb +76 -0
- data/{lib/docker/template/templates → templates}/scratch.erb +0 -1
- metadata +64 -50
- data/lib/docker/template/alias.rb +0 -28
- data/lib/docker/template/ansi.rb +0 -85
- data/lib/docker/template/auth.rb +0 -25
- data/lib/docker/template/common.rb +0 -130
- data/lib/docker/template/config.rb +0 -80
- data/lib/docker/template/error/bad_exit_status.rb +0 -17
- data/lib/docker/template/error/bad_repo_name.rb +0 -15
- data/lib/docker/template/error/invalid_repo_type.rb +0 -16
- data/lib/docker/template/error/invalid_targz_file.rb +0 -15
- data/lib/docker/template/error/no_rootfs_copy_dir.rb +0 -15
- data/lib/docker/template/error/no_rootfs_mkimg.rb +0 -15
- data/lib/docker/template/error/no_setup_context_found.rb +0 -15
- data/lib/docker/template/error/not_implemented.rb +0 -15
- data/lib/docker/template/error/repo_not_found.rb +0 -16
- data/lib/docker/template/interface.rb +0 -118
- data/lib/docker/template/patches.rb +0 -9
- data/lib/docker/template/patches/array.rb +0 -11
- data/lib/docker/template/patches/hash.rb +0 -71
- data/lib/docker/template/patches/object.rb +0 -9
- data/lib/docker/template/patches/pathname.rb +0 -46
- data/lib/docker/template/patches/string.rb +0 -9
- data/lib/docker/template/routable.rb +0 -28
- data/lib/docker/template/simple.rb +0 -49
- data/lib/docker/template/stream.rb +0 -63
- data/lib/docker/template/templates/rootfs.erb +0 -8
- data/lib/docker/template/util.rb +0 -54
- data/lib/docker/template/util/copy.rb +0 -77
- data/lib/docker/template/util/data.rb +0 -26
@@ -0,0 +1,46 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
# Frozen-string-literal: true
|
3
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
4
|
+
# Encoding: utf-8
|
5
|
+
# ----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module Docker
|
8
|
+
module Template
|
9
|
+
class Normal < Builder
|
10
|
+
def teardown(img: false)
|
11
|
+
@img.delete "force" => true if @img && img
|
12
|
+
@context.rmtree if @context && \
|
13
|
+
@context.directory?
|
14
|
+
end
|
15
|
+
|
16
|
+
# ----------------------------------------------------------------------
|
17
|
+
|
18
|
+
def setup_context
|
19
|
+
@context = @repo.tmpdir
|
20
|
+
@copy = @context.join("copy")
|
21
|
+
copy_dockerfile
|
22
|
+
@copy.mkdir
|
23
|
+
end
|
24
|
+
|
25
|
+
# ----------------------------------------------------------------------
|
26
|
+
|
27
|
+
private
|
28
|
+
def copy_dockerfile
|
29
|
+
dockerfile = @repo.root.join("Dockerfile").read
|
30
|
+
data = ERB::Context.new(:metadata => @repo.metadata)
|
31
|
+
data = ERB.new(dockerfile).result(data._binding)
|
32
|
+
context = @context.join("Dockerfile")
|
33
|
+
context.write(data)
|
34
|
+
end
|
35
|
+
|
36
|
+
# ----------------------------------------------------------------------
|
37
|
+
|
38
|
+
private
|
39
|
+
def cache_context
|
40
|
+
if @repo.cacheable?
|
41
|
+
Cache.context self, @context
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
# Frozen-string-literal: true
|
3
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
4
|
+
# Encoding: utf-8
|
5
|
+
# ----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
module Docker
|
8
|
+
module Template
|
9
|
+
module Notify
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# ----------------------------------------------------------------------
|
13
|
+
# Notify the user of a push that is happening.
|
14
|
+
# ----------------------------------------------------------------------
|
15
|
+
|
16
|
+
def push(builder)
|
17
|
+
$stderr.puts Simple::Ansi.green(
|
18
|
+
"Pushing: #{builder.repo}"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
# ----------------------------------------------------------------------
|
23
|
+
# Notify the user that we are tag aliasing.
|
24
|
+
# ----------------------------------------------------------------------
|
25
|
+
|
26
|
+
def alias(builder)
|
27
|
+
repo = builder.repo
|
28
|
+
aliased_repo = builder.aliased_repo
|
29
|
+
msg = Simple::Ansi.green("Aliasing #{repo} -> #{aliased_repo}")
|
30
|
+
$stderr.puts msg
|
31
|
+
end
|
32
|
+
|
33
|
+
# ----------------------------------------------------------------------
|
34
|
+
# Notify the user that we are building their repository.
|
35
|
+
# ----------------------------------------------------------------------
|
36
|
+
|
37
|
+
def build(repo, **kwd)
|
38
|
+
img = repo.to_s(**kwd)
|
39
|
+
msg = Simple::Ansi.green("Building: #{img}")
|
40
|
+
$stderr.puts msg
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,66 +1,76 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
1
2
|
# Frozen-string-literal: true
|
2
|
-
# Copyright: 2015 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
4
|
# Encoding: utf-8
|
5
|
+
# ----------------------------------------------------------------------------
|
4
6
|
|
5
7
|
module Docker
|
6
8
|
module Template
|
7
9
|
class Parser
|
8
|
-
SLASH_REGEXP =
|
9
|
-
SPLIT_REGEXP =
|
10
|
-
COLON_REGEXP =
|
10
|
+
SLASH_REGEXP = /\//
|
11
|
+
SPLIT_REGEXP = /:|\//
|
12
|
+
COLON_REGEXP = /:/
|
11
13
|
|
12
|
-
def initialize(
|
13
|
-
@
|
14
|
+
def initialize(raw_repos = [], argv = {})
|
15
|
+
@raw_repos = raw_repos
|
16
|
+
@argv = argv
|
14
17
|
end
|
15
18
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
+
# ----------------------------------------------------------------------
|
20
|
+
# Return `raw_repos` if you send us a list of repos you wish to build,
|
21
|
+
# otherwise we get the children of the repo folder and ship that off so
|
22
|
+
# you can build *every* repo, I don't know if you want that.
|
23
|
+
# ----------------------------------------------------------------------
|
19
24
|
|
20
25
|
def all
|
21
|
-
return @
|
22
|
-
Template.
|
26
|
+
return @raw_repos unless @raw_repos.empty?
|
27
|
+
Template.root.join(Metadata.new({}).repos_dir).children.map do |path|
|
23
28
|
path.basename.to_s
|
24
29
|
end
|
30
|
+
|
25
31
|
rescue Errno::ENOENT
|
26
|
-
raise Error::RepoNotFound
|
32
|
+
then raise Error::RepoNotFound
|
27
33
|
end
|
28
34
|
|
29
|
-
#
|
35
|
+
# ----------------------------------------------------------------------
|
36
|
+
|
37
|
+
def parse
|
38
|
+
repos = {
|
39
|
+
:scratch => [],
|
40
|
+
:simple => [],
|
41
|
+
:aliases => []
|
42
|
+
}
|
30
43
|
|
31
|
-
|
32
|
-
|
33
|
-
hash
|
34
|
-
|
35
|
-
|
44
|
+
all.each do |v|
|
45
|
+
hash = to_repo_hash(v)
|
46
|
+
if hash.empty?
|
47
|
+
raise Docker::Template::Error::BadRepoName, v
|
48
|
+
|
49
|
+
else
|
50
|
+
Repo.new(hash, @argv).to_repos.each do |r|
|
51
|
+
r.alias?? repos[:aliases] << r : r.builder.scratch?? \
|
52
|
+
repos[:scratch] << r : repos[:simple] << r
|
53
|
+
end
|
54
|
+
end
|
36
55
|
end
|
37
|
-
|
56
|
+
|
57
|
+
repos.values.reduce(
|
58
|
+
:|
|
59
|
+
)
|
38
60
|
end
|
39
61
|
|
40
|
-
#
|
62
|
+
# ----------------------------------------------------------------------
|
41
63
|
|
42
64
|
private
|
43
|
-
def
|
65
|
+
def to_repo_hash(val)
|
44
66
|
data = val.split(SPLIT_REGEXP)
|
45
|
-
hsh = {}
|
46
67
|
|
47
|
-
if data.
|
48
|
-
|
68
|
+
return "name" => data[0] if data.one?
|
69
|
+
return "name" => data[0], "tag" => data[1] if val =~ COLON_REGEXP && data.size == 2
|
70
|
+
return "user" => data[0], "name" => data[1] if val =~ SLASH_REGEXP && data.size == 2
|
71
|
+
return "user" => data[0], "name" => data[1], "tag" => data[2] if data.size == 3
|
49
72
|
|
50
|
-
|
51
|
-
hsh["repo"] = data[0]
|
52
|
-
hsh[ "tag"] = data[1]
|
53
|
-
|
54
|
-
elsif val =~ SLASH_REGEXP && data.size == 2
|
55
|
-
hsh["user"] = data[0]
|
56
|
-
hsh["repo"] = data[1]
|
57
|
-
|
58
|
-
elsif data.size == 3
|
59
|
-
hsh["user"] = data[0]
|
60
|
-
hsh["repo"] = data[1]
|
61
|
-
hsh[ "tag"] = data[2]
|
62
|
-
end
|
63
|
-
hsh
|
73
|
+
{}
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|
data/lib/docker/template/repo.rb
CHANGED
@@ -1,85 +1,109 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
1
2
|
# Frozen-string-literal: true
|
2
|
-
# Copyright: 2015 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
4
|
# Encoding: utf-8
|
5
|
+
# ----------------------------------------------------------------------------
|
4
6
|
|
5
7
|
module Docker
|
6
8
|
module Template
|
7
|
-
|
8
|
-
# * A repo is not an image but a parent name w/ a tag.
|
9
|
-
# * An image is the final result of a build on a repo, and is associated.
|
10
|
-
# * Think of an image as the binary of the source in the repo.
|
11
|
-
|
12
9
|
class Repo
|
13
|
-
extend Forwardable
|
10
|
+
extend Forwardable::Extended
|
14
11
|
|
15
|
-
|
16
|
-
route_to_hash :name, :@base_metadata, :repo
|
17
|
-
route_to_hash [:tag, :type, :user], :metadata
|
18
|
-
def_delegator :@base_metadata, :to_h
|
19
|
-
def_delegator :metadata, :aliased
|
20
|
-
def_delegator :metadata, :tags
|
12
|
+
# ----------------------------------------------------------------------
|
21
13
|
|
22
|
-
def initialize(
|
23
|
-
|
24
|
-
|
25
|
-
@base_metadata = base_metadata.freeze
|
26
|
-
@sync_allowed = type == "simple" ? true : false
|
27
|
-
raise Error::InvalidRepoType, type unless Template.config.build_types.include?(type)
|
14
|
+
def initialize(*hashes)
|
15
|
+
@base_meta = hashes.compact.reduce(:deep_merge).freeze
|
28
16
|
raise Error::RepoNotFound, name unless root.exist?
|
29
17
|
end
|
30
18
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
#
|
19
|
+
# ----------------------------------------------------------------------
|
20
|
+
# Determines whether or not we should (or you should) push the repo.
|
21
|
+
# ----------------------------------------------------------------------
|
37
22
|
|
38
|
-
def
|
39
|
-
|
23
|
+
def pushable?
|
24
|
+
(metadata["push"] || metadata["push_only"]) && !metadata[
|
25
|
+
"cache_only"
|
26
|
+
]
|
40
27
|
end
|
41
28
|
|
42
|
-
#
|
29
|
+
# ----------------------------------------------------------------------
|
30
|
+
# Determines whether or not we should (or you should) cache the repo.
|
31
|
+
# ----------------------------------------------------------------------
|
43
32
|
|
44
|
-
def
|
45
|
-
metadata["
|
33
|
+
def cacheable?
|
34
|
+
(metadata["cache"] || metadata["cache_only"]) && !metadata[
|
35
|
+
"push_only"
|
36
|
+
]
|
46
37
|
end
|
47
38
|
|
48
|
-
#
|
39
|
+
# ----------------------------------------------------------------------
|
40
|
+
# Determines whether or not we should (or you should) build the repo.
|
41
|
+
# ----------------------------------------------------------------------
|
49
42
|
|
50
|
-
def
|
51
|
-
"
|
43
|
+
def buildable?
|
44
|
+
!metadata["push_only"] && !metadata["cache_only"] && !metadata[
|
45
|
+
"clean_only"
|
46
|
+
]
|
52
47
|
end
|
53
48
|
|
54
|
-
#
|
49
|
+
# ----------------------------------------------------------------------
|
50
|
+
# Pulls out the repo this repo is aliasing it, this happens when you
|
51
|
+
# when you set the tag in the "alias" section of your `opts.yml`.
|
52
|
+
# ----------------------------------------------------------------------
|
55
53
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
54
|
+
def aliased
|
55
|
+
if alias?
|
56
|
+
self.class.new(to_h.merge({
|
57
|
+
"tag" => metadata.aliased_tag
|
58
|
+
}))
|
59
|
+
end
|
59
60
|
end
|
60
61
|
|
61
|
-
#
|
62
|
+
# ----------------------------------------------------------------------
|
63
|
+
# Initializes and returns the builder so that you can build the repo.
|
64
|
+
# ----------------------------------------------------------------------
|
62
65
|
|
63
|
-
def
|
64
|
-
|
66
|
+
def builder
|
67
|
+
return @builder ||= begin
|
68
|
+
Template.const_get(type.capitalize).new(
|
69
|
+
self
|
70
|
+
)
|
71
|
+
end
|
65
72
|
end
|
66
73
|
|
67
|
-
#
|
74
|
+
# ----------------------------------------------------------------------
|
75
|
+
# Convert the repo into it's final image name, however if you tell, us
|
76
|
+
# this is a rootfs build we will convert it into the rootfs name.
|
77
|
+
# ----------------------------------------------------------------------
|
68
78
|
|
69
|
-
def
|
79
|
+
def to_s(rootfs: false)
|
70
80
|
prefix = metadata["local_prefix"]
|
81
|
+
return "#{user}/#{name}:#{tag}" unless rootfs
|
71
82
|
"#{prefix}/rootfs:#{name}"
|
72
83
|
end
|
73
84
|
|
74
|
-
#
|
85
|
+
# ----------------------------------------------------------------------
|
86
|
+
# The directory you wish to cache to (like `cache/`) or other.
|
87
|
+
# ----------------------------------------------------------------------
|
75
88
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
89
|
+
def cache_dir
|
90
|
+
return root.join(
|
91
|
+
metadata["cache_dir"], tag
|
92
|
+
)
|
80
93
|
end
|
81
94
|
|
82
|
-
#
|
95
|
+
# ----------------------------------------------------------------------
|
96
|
+
# The directory you store your image data in (by default `copy/`.)
|
97
|
+
# ----------------------------------------------------------------------
|
98
|
+
|
99
|
+
def copy_dir(*path)
|
100
|
+
dir = metadata["copy_dir"]
|
101
|
+
root.join(dir,
|
102
|
+
*path
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
# ----------------------------------------------------------------------
|
83
107
|
|
84
108
|
def to_tag_h
|
85
109
|
{
|
@@ -89,86 +113,96 @@ module Docker
|
|
89
113
|
}
|
90
114
|
end
|
91
115
|
|
92
|
-
#
|
116
|
+
# ----------------------------------------------------------------------
|
93
117
|
|
94
118
|
def to_rootfs_h
|
95
|
-
prefix = metadata["local_prefix"]
|
96
|
-
|
97
119
|
{
|
98
120
|
"tag" => name,
|
99
|
-
"repo" => "#{
|
121
|
+
"repo" => "#{metadata["local_prefix"]}/rootfs",
|
100
122
|
"force" => true
|
101
123
|
}
|
102
124
|
end
|
103
125
|
|
104
|
-
#
|
126
|
+
# ----------------------------------------------------------------------
|
105
127
|
|
106
|
-
def tmpdir(*
|
107
|
-
|
108
|
-
|
109
|
-
|
128
|
+
def tmpdir(*args, root: nil)
|
129
|
+
args.unshift(user, name, tag)
|
130
|
+
Pathutil.tmpdir(args,
|
131
|
+
nil, root
|
132
|
+
)
|
110
133
|
end
|
111
134
|
|
112
|
-
#
|
135
|
+
# ----------------------------------------------------------------------
|
113
136
|
|
114
|
-
def tmpfile(*
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
args = [prefixes, root].delete_if(&:nil?)
|
120
|
-
Pathname.new(Tempfile.new(*args))
|
137
|
+
def tmpfile(*args, root: nil)
|
138
|
+
args.unshift(user, name, tag)
|
139
|
+
Pathutil.tmpfile(args,
|
140
|
+
nil, root
|
141
|
+
)
|
121
142
|
end
|
122
143
|
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
144
|
+
# ----------------------------------------------------------------------
|
145
|
+
# If a tag was given then it returns [self] and if a tag was not sent
|
146
|
+
# it then goes on to detect the type and split itself accordingly
|
147
|
+
# returning multiple, AKA all repos that should be built.
|
148
|
+
# ----------------------------------------------------------------------
|
126
149
|
|
127
150
|
def to_repos
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
151
|
+
set = Set.new
|
152
|
+
if @base_meta.key?("tag")
|
153
|
+
set << self
|
154
|
+
else
|
132
155
|
tags.each do |tag|
|
133
|
-
|
134
|
-
set << self.class.new(
|
156
|
+
hash = to_h.merge("tag" => tag)
|
157
|
+
set << self.class.new(
|
158
|
+
hash, @cli_opts
|
159
|
+
)
|
135
160
|
end
|
136
|
-
|
137
|
-
set
|
138
|
-
else
|
139
|
-
Set.new([
|
140
|
-
self
|
141
|
-
])
|
142
161
|
end
|
162
|
+
set
|
143
163
|
end
|
144
164
|
|
145
|
-
#
|
165
|
+
# ----------------------------------------------------------------------
|
146
166
|
|
147
167
|
def metadata
|
148
|
-
@metadata ||= begin
|
149
|
-
|
150
|
-
|
151
|
-
|
168
|
+
return @metadata ||= begin
|
169
|
+
Metadata.new(
|
170
|
+
@base_meta
|
171
|
+
)
|
152
172
|
end
|
153
173
|
end
|
154
174
|
|
155
|
-
#
|
175
|
+
# ----------------------------------------------------------------------
|
156
176
|
|
157
|
-
def
|
158
|
-
metadata["env"]
|
177
|
+
def to_env(tar_gz: nil, copy_dir: nil)
|
178
|
+
hash = metadata["env"] || { "all" => {}}
|
179
|
+
Metadata.new(hash, :root => metadata).merge({
|
159
180
|
"REPO" => name,
|
160
|
-
"NAME" => name,
|
161
181
|
"TAR_GZ" => tar_gz,
|
162
|
-
"
|
163
|
-
"
|
164
|
-
"PKGS" => metadata["pkgs"].as_string_set,
|
165
|
-
"RELEASE" => metadata["release"].fallback,
|
182
|
+
"GROUP" => metadata.group,
|
183
|
+
"COPY_DIR" => copy_dir,
|
166
184
|
"BUILD_TYPE" => type,
|
167
|
-
"COPY" => copy_dir,
|
168
|
-
"TAR" => tar_gz,
|
169
185
|
"TAG" => tag
|
170
|
-
})
|
171
|
-
end
|
186
|
+
})
|
187
|
+
end
|
188
|
+
|
189
|
+
# ----------------------------------------------------------------------
|
190
|
+
|
191
|
+
rb_delegate :build, :to => :builder
|
192
|
+
rb_delegate :alias?, :to => :metadata
|
193
|
+
rb_delegate :complex_alias?, :to => :metadata
|
194
|
+
rb_delegate :type, :to => :metadata, :type => :hash
|
195
|
+
rb_delegate :user, :to => :metadata, :type => :hash
|
196
|
+
rb_delegate :name, :to => :metadata, :type => :hash
|
197
|
+
rb_delegate :tag, :to => :metadata, :type => :hash
|
198
|
+
rb_delegate :to_h, :to => :@base_meta
|
199
|
+
rb_delegate :root, :to => :metadata
|
200
|
+
rb_delegate :tags, :to => :metadata
|
201
|
+
rb_delegate :clean, {
|
202
|
+
:to => Cache, :alias_of => :cleanup, :args => %w(
|
203
|
+
self
|
204
|
+
)
|
205
|
+
}
|
172
206
|
end
|
173
207
|
end
|
174
208
|
end
|