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.
@@ -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