docker-template 0.8.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,29 +1,44 @@
|
|
1
|
+
# Frozen-string-literal: true
|
2
|
+
# Copyright: 2015 - 2016 Jordon Bedwell - Apache v2.0 License
|
3
|
+
# Encoding: utf-8
|
4
|
+
|
1
5
|
module Docker
|
2
6
|
module Template
|
3
7
|
class CLI
|
4
8
|
class Build
|
5
9
|
def initialize(args, opts)
|
6
|
-
@opts =
|
10
|
+
@opts = Meta.new(opts || {})
|
7
11
|
@repos = Parser.new(args, opts || {}).parse
|
8
12
|
@args = args
|
9
13
|
end
|
10
14
|
|
11
|
-
#
|
15
|
+
# --
|
12
16
|
|
13
17
|
def start
|
14
18
|
_profile do
|
15
|
-
|
19
|
+
changed! if @opts.diff?
|
20
|
+
exclude! if @opts.exclude?
|
16
21
|
@repos.tap { |o| o.map(&:build) }.uniq(&:name).map(
|
17
22
|
&:clean
|
18
23
|
)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
22
|
-
#
|
27
|
+
# --
|
28
|
+
|
29
|
+
def exclude!
|
30
|
+
Parser.new(@opts[:exclude].map { |v| v.split(/,\s*/) }.flatten.compact).parse.each do |repo|
|
31
|
+
@repos.delete_if do |v|
|
32
|
+
v.name == repo.name && v.tag == repo.tag
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# --
|
23
38
|
# rubocop:disable Metrics/AbcSize
|
24
|
-
#
|
39
|
+
# --
|
25
40
|
|
26
|
-
def
|
41
|
+
def changed!
|
27
42
|
Template._require "rugged" do
|
28
43
|
git = Rugged::Repository.new(Template.root.to_s)
|
29
44
|
dir = Template.root.join(@opts.repos_dir)
|
@@ -43,9 +58,9 @@ module Docker
|
|
43
58
|
end
|
44
59
|
end
|
45
60
|
|
46
|
-
#
|
61
|
+
# --
|
47
62
|
# rubocop:enable Metrics/AbcSize
|
48
|
-
#
|
63
|
+
# --
|
49
64
|
|
50
65
|
private
|
51
66
|
def _profile
|
@@ -6,13 +6,13 @@ module Docker
|
|
6
6
|
return new.build
|
7
7
|
end
|
8
8
|
|
9
|
-
#
|
9
|
+
# --
|
10
10
|
|
11
11
|
def initialize(images = Parser.new([], {}).parse)
|
12
12
|
@images = images
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
15
|
+
# --
|
16
16
|
|
17
17
|
def build
|
18
18
|
out = ""
|
@@ -26,7 +26,7 @@ module Docker
|
|
26
26
|
out
|
27
27
|
end
|
28
28
|
|
29
|
-
#
|
29
|
+
# --
|
30
30
|
|
31
31
|
def repos(user, images)
|
32
32
|
out = ""
|
@@ -42,7 +42,7 @@ module Docker
|
|
42
42
|
out
|
43
43
|
end
|
44
44
|
|
45
|
-
#
|
45
|
+
# --
|
46
46
|
|
47
47
|
def tags(user, name, images)
|
48
48
|
out = ""
|
@@ -57,13 +57,13 @@ module Docker
|
|
57
57
|
out
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
60
|
+
# --
|
61
61
|
|
62
62
|
def remote_aliases(*args)
|
63
63
|
out = ""
|
64
64
|
|
65
65
|
remotes = _remote_aliases(*args).group_by do |image|
|
66
|
-
image.
|
66
|
+
image.meta[:aliases][
|
67
67
|
image.tag
|
68
68
|
]
|
69
69
|
end
|
@@ -86,7 +86,7 @@ module Docker
|
|
86
86
|
out
|
87
87
|
end
|
88
88
|
|
89
|
-
#
|
89
|
+
# --
|
90
90
|
|
91
91
|
def _remote_aliases(user, name, images)
|
92
92
|
images.select do |image|
|
@@ -96,7 +96,7 @@ module Docker
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
#
|
99
|
+
# --
|
100
100
|
|
101
101
|
def aliases(user, name, tag, images, depth: 0)
|
102
102
|
out = ""
|
@@ -123,14 +123,14 @@ module Docker
|
|
123
123
|
out
|
124
124
|
end
|
125
125
|
|
126
|
-
#
|
126
|
+
# --
|
127
127
|
|
128
128
|
private
|
129
129
|
def aliased_remote?(image)
|
130
130
|
return image.alias? && !image.aliased
|
131
131
|
end
|
132
132
|
|
133
|
-
#
|
133
|
+
# --
|
134
134
|
|
135
135
|
private
|
136
136
|
def _aliases(user, name, tag, images)
|
@@ -1,8 +1,6 @@
|
|
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
|
@@ -11,17 +9,15 @@ module Docker
|
|
11
9
|
StandardError
|
12
10
|
)
|
13
11
|
|
14
|
-
#
|
12
|
+
# --
|
15
13
|
|
16
|
-
class
|
17
|
-
def initialize
|
18
|
-
super
|
19
|
-
"PLACEHOLDER ERROR: %s", error
|
20
|
-
)
|
14
|
+
class UnsuccessfulAuth < StandardError
|
15
|
+
def initialize
|
16
|
+
super "Unable to authorize you to Dockerhub, something is wrong."
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
24
|
-
#
|
20
|
+
# --
|
25
21
|
|
26
22
|
class BadExitStatus < StandardError
|
27
23
|
attr_reader :status
|
@@ -33,7 +29,7 @@ module Docker
|
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
36
|
-
#
|
32
|
+
# --
|
37
33
|
|
38
34
|
class BadRepoName < StandardError
|
39
35
|
def initialize(name)
|
@@ -43,18 +39,7 @@ module Docker
|
|
43
39
|
end
|
44
40
|
end
|
45
41
|
|
46
|
-
#
|
47
|
-
|
48
|
-
class InvalidRepoType < StandardError
|
49
|
-
def initialize(type)
|
50
|
-
build_types = Template.config.build_types.join(", ")
|
51
|
-
super "Uknown repo type given '#{type}' not in '#{
|
52
|
-
build_types
|
53
|
-
}'"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# ----------------------------------------------------------------------
|
42
|
+
# --
|
58
43
|
|
59
44
|
class InvalidTargzFile < StandardError
|
60
45
|
def initialize(tar_gz)
|
@@ -64,7 +49,7 @@ module Docker
|
|
64
49
|
end
|
65
50
|
end
|
66
51
|
|
67
|
-
#
|
52
|
+
# --
|
68
53
|
|
69
54
|
class InvalidYAMLFile < StandardError
|
70
55
|
def initialize(file)
|
@@ -72,23 +57,7 @@ module Docker
|
|
72
57
|
end
|
73
58
|
end
|
74
59
|
|
75
|
-
#
|
76
|
-
|
77
|
-
class NoRootMetadata < StandardError
|
78
|
-
def initialize
|
79
|
-
super "Metadata without the root flag must provide the root_metadata."
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# ----------------------------------------------------------------------
|
84
|
-
|
85
|
-
class NoRootfsMkimg < StandardError
|
86
|
-
def initialize
|
87
|
-
super "Unable to find rootfs.rb in your repo folder."
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# ----------------------------------------------------------------------
|
60
|
+
# --
|
92
61
|
|
93
62
|
class NoSetupContext < StandardError
|
94
63
|
def initialize
|
@@ -96,7 +65,7 @@ module Docker
|
|
96
65
|
end
|
97
66
|
end
|
98
67
|
|
99
|
-
#
|
68
|
+
# --
|
100
69
|
|
101
70
|
class NotImplemented < StandardError
|
102
71
|
def initialize
|
@@ -104,7 +73,7 @@ module Docker
|
|
104
73
|
end
|
105
74
|
end
|
106
75
|
|
107
|
-
#
|
76
|
+
# --
|
108
77
|
|
109
78
|
class RepoNotFound < StandardError
|
110
79
|
def initialize(repo = nil)
|
@@ -115,7 +84,7 @@ module Docker
|
|
115
84
|
end
|
116
85
|
end
|
117
86
|
|
118
|
-
#
|
87
|
+
# --
|
119
88
|
|
120
89
|
class ImageNotFound < StandardError
|
121
90
|
def initialize(image)
|
@@ -1,19 +1,44 @@
|
|
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
|
class Logger
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
class << self
|
9
|
+
attr_writer :stdout, :stderr
|
10
|
+
|
11
|
+
# --
|
12
|
+
|
13
|
+
def stdout
|
14
|
+
return @stdout || $stdout
|
15
|
+
end
|
16
|
+
|
17
|
+
# --
|
18
|
+
|
19
|
+
def stderr
|
20
|
+
return @stderr || $stderr
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
|
-
#
|
24
|
+
# --
|
25
|
+
|
26
|
+
def initialize(repo = nil, stdout = nil, stderr = nil)
|
27
|
+
@stdout = stdout || self.class.stdout
|
28
|
+
@stderr = stderr || self.class.stderr
|
29
|
+
@repo = repo
|
30
|
+
@lines = {
|
31
|
+
0 => 0
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# --
|
36
|
+
|
37
|
+
def output?
|
38
|
+
return !!@output
|
39
|
+
end
|
40
|
+
|
41
|
+
# --
|
17
42
|
|
18
43
|
def increment
|
19
44
|
@lines.update({
|
@@ -21,61 +46,84 @@ module Docker
|
|
21
46
|
})
|
22
47
|
end
|
23
48
|
|
24
|
-
#
|
49
|
+
# --
|
25
50
|
# A simple TTY stream that just prints out the data that it is given.
|
26
51
|
# This is the logger that most will use for most of their building.
|
27
|
-
#
|
52
|
+
# --
|
28
53
|
|
29
54
|
def tty(stream)
|
30
|
-
|
55
|
+
@output = true
|
56
|
+
@stdout.print(encode_str(
|
57
|
+
stream
|
58
|
+
))
|
31
59
|
end
|
32
60
|
|
33
|
-
#
|
61
|
+
# --
|
34
62
|
# A simple logger that accepts a multi-type stream.
|
35
|
-
#
|
63
|
+
# --
|
36
64
|
|
37
65
|
def simple(type, str)
|
38
|
-
|
66
|
+
str = encode_str(str ||= "")
|
67
|
+
type == :stderr ? @stderr.print(str) : \
|
68
|
+
@stdout.print(str)
|
39
69
|
end
|
40
70
|
|
41
|
-
#
|
71
|
+
# --
|
42
72
|
# A more complex streamer designed for the actual output of the Docker.
|
43
|
-
#
|
73
|
+
# --
|
74
|
+
# This method will save parts into a buffer until it can either parse
|
75
|
+
# that buffer or it parses the actual part itself, if it can parse the
|
76
|
+
# part itself, it will first dump the buffer as errors and then parse.
|
77
|
+
# --
|
78
|
+
# This method has to buffer because Docker-API (or Excon, it's depend)
|
79
|
+
# gives us no indication of whether or not this is part of a larger chunk
|
80
|
+
# it just dumps it on us, so we have to blindly work around that.
|
81
|
+
# --
|
82
|
+
|
83
|
+
def api(part, *args)
|
84
|
+
part = encode_str(part)
|
85
|
+
chunked_part = @chunks.push(part).join if @chunks && !@chunks.empty?
|
86
|
+
chunked_part = part if !@chunks
|
87
|
+
stream = JSON.parse(
|
88
|
+
chunked_part
|
89
|
+
)
|
44
90
|
|
45
|
-
|
46
|
-
|
47
|
-
|
91
|
+
if chunked_part == part && @chunks && !@chunks.empty?
|
92
|
+
then @chunks.each do |chunk|
|
93
|
+
@stderr.puts format("Unparsable JSON: %s",
|
94
|
+
chunk
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
48
98
|
|
99
|
+
@chunks = nil
|
49
100
|
return progress_bar(stream) if stream.any_key?("progress", "progressDetail")
|
50
101
|
return output(stream["status"] || stream["stream"]) if stream.any_key?("status", "stream")
|
51
102
|
return progress_error(stream) if stream.any_key?("errorDetail", "error")
|
52
|
-
|
53
103
|
warn Simple::Ansi.red("Unhandled Stream.")
|
54
|
-
|
104
|
+
@stdout.puts(
|
55
105
|
part
|
56
106
|
)
|
57
107
|
|
58
|
-
|
108
|
+
@output = true
|
59
109
|
rescue JSON::ParserError => e
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
retry
|
64
|
-
else
|
65
|
-
raise e
|
66
|
-
end
|
110
|
+
(@chunks ||= []).push(
|
111
|
+
part
|
112
|
+
)
|
67
113
|
end
|
68
114
|
|
69
|
-
#
|
115
|
+
# --
|
70
116
|
|
71
117
|
def output(msg)
|
72
118
|
unless filter_matches?(msg)
|
73
|
-
|
119
|
+
@stdout.puts msg
|
74
120
|
increment
|
75
121
|
end
|
122
|
+
|
123
|
+
@output = true
|
76
124
|
end
|
77
125
|
|
78
|
-
#
|
126
|
+
# --
|
79
127
|
|
80
128
|
def progress_error(stream)
|
81
129
|
abort Object::Simple::Ansi.red(
|
@@ -83,7 +131,20 @@ module Docker
|
|
83
131
|
)
|
84
132
|
end
|
85
133
|
|
86
|
-
#
|
134
|
+
# --
|
135
|
+
# Some applications return some invalid ASCII so we need to work
|
136
|
+
# around that so that no errors happen. This mostly happens
|
137
|
+
# with Node.js NPM.
|
138
|
+
# --
|
139
|
+
|
140
|
+
private
|
141
|
+
def encode_str(str)
|
142
|
+
str.encode("utf-8", {
|
143
|
+
:invalid => :replace, :undef => :replace, :replace => ""
|
144
|
+
})
|
145
|
+
end
|
146
|
+
|
147
|
+
# --
|
87
148
|
|
88
149
|
private
|
89
150
|
def progress_bar(stream)
|
@@ -91,16 +152,16 @@ module Docker
|
|
91
152
|
|
92
153
|
return unless id
|
93
154
|
before, diff = progress_diff(id)
|
94
|
-
|
155
|
+
@stderr.print before if before
|
95
156
|
str = stream["progress"] || stream["status"]
|
96
157
|
str = "#{id}: #{str}\r"
|
97
158
|
|
98
|
-
|
159
|
+
@stderr.print(Object::Simple::Ansi.jump(
|
99
160
|
str, diff
|
100
161
|
))
|
101
162
|
end
|
102
163
|
|
103
|
-
#
|
164
|
+
# --
|
104
165
|
|
105
166
|
private
|
106
167
|
def progress_diff(id)
|
@@ -113,13 +174,13 @@ module Docker
|
|
113
174
|
return before, 0
|
114
175
|
end
|
115
176
|
|
116
|
-
#
|
177
|
+
# --
|
117
178
|
|
118
179
|
private
|
119
180
|
def filter_matches?(msg)
|
120
|
-
return false unless @
|
181
|
+
return false unless @repo
|
121
182
|
|
122
|
-
@
|
183
|
+
@repo.meta["log_filters"].any? do |filter|
|
123
184
|
filter.is_a?(Regexp) && msg =~ filter || msg == filter
|
124
185
|
end
|
125
186
|
end
|