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.
@@ -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 = Metadata.new(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
- reselect_repos if @opts.diff?
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 reselect_repos
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.metadata[:aliases][
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 PlaceHolderError < StandardError
17
- def initialize(error)
18
- super format(
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
- def initialize(builder = nil)
11
- @lines = { 0 => 0 }
12
- @builder = \
13
- builder
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
- $stdout.print stream
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
- type == :stderr ? $stderr.print(str) : $stdout.print(str)
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
- def api(part, *_)
46
- stream = JSON.parse(part)
47
- retried ||= false
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
- $stdout.puts(
104
+ @stdout.puts(
55
105
  part
56
106
  )
57
107
 
58
- # Addresses a Docker 1.9 bug.
108
+ @output = true
59
109
  rescue JSON::ParserError => e
60
- if !retried
61
- retried = true
62
- part = "#{part}\" }"
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
- $stdout.puts msg
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
- $stderr.print before if before
155
+ @stderr.print before if before
95
156
  str = stream["progress"] || stream["status"]
96
157
  str = "#{id}: #{str}\r"
97
158
 
98
- $stderr.print(Object::Simple::Ansi.jump(
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 @builder
181
+ return false unless @repo
121
182
 
122
- @builder.repo.metadata["log_filters"].any? do |filter|
183
+ @repo.meta["log_filters"].any? do |filter|
123
184
  filter.is_a?(Regexp) && msg =~ filter || msg == filter
124
185
  end
125
186
  end