docker-template 0.1.2 → 0.2.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/Rakefile +39 -2
- data/bin/docker-template +3 -5
- data/lib/docker/template.rb +19 -7
- data/lib/docker/template/alias.rb +1 -1
- data/lib/docker/template/ansi.rb +27 -17
- data/lib/docker/template/auth.rb +3 -3
- data/lib/docker/template/common.rb +14 -10
- data/lib/docker/template/config.rb +14 -18
- data/lib/docker/template/interface.rb +8 -9
- data/lib/docker/template/metadata.rb +33 -29
- data/lib/docker/template/parser.rb +10 -9
- data/lib/docker/template/patches/hash.rb +11 -16
- data/lib/docker/template/patches/pathname.rb +3 -3
- data/lib/docker/template/repo.rb +22 -28
- data/lib/docker/template/scratch.rb +3 -6
- data/lib/docker/template/simple.rb +3 -5
- data/lib/docker/template/stream.rb +5 -4
- data/lib/docker/template/util.rb +23 -8
- data/lib/docker/template/util/copy.rb +8 -13
- data/lib/docker/template/util/data.rb +1 -1
- data/lib/docker/template/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a041995698dcbe6253e4c997a940e1e7eb492e4b
|
4
|
+
data.tar.gz: 39b3a79d100a7ddb4f75d7352b1dac9db157ee94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e2949a9cd7ce54000508599cd1c31b07dbdbf654596b3d6984977f2bfa75cc7932bb1a6cd097af97f77122fd5434f150f00b10011cf689edb35455013fd69e8
|
7
|
+
data.tar.gz: e2997be78cc2d37d48cd7ef3184b6481992fcc6befc0d595835d396d7935230e852a76128b933f55aeaa618b1fa31fbf5e16b3416fecd01d325cfbe0ec38e888
|
data/Rakefile
CHANGED
@@ -2,8 +2,11 @@
|
|
2
2
|
# Copyright: 2015 Jordon Bedwell - Apache v2.0 License
|
3
3
|
# Encoding: utf-8
|
4
4
|
|
5
|
-
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
|
6
|
+
require "docker/template/ansi"
|
6
7
|
require "rspec/core/rake_task"
|
8
|
+
require "open3"
|
9
|
+
|
7
10
|
task :default => [:spec]
|
8
11
|
RSpec::Core::RakeTask.new :spec
|
9
12
|
task :test => :spec
|
@@ -15,6 +18,40 @@ task :build do
|
|
15
18
|
end
|
16
19
|
|
17
20
|
task :pry do
|
18
|
-
|
21
|
+
sh "bundle", "exec", "pry", "-Ilib/", \
|
19
22
|
"-rdocker/template"
|
20
23
|
end
|
24
|
+
|
25
|
+
task :analysis do
|
26
|
+
ansi = Docker::Template::Ansi
|
27
|
+
cmd = [
|
28
|
+
"docker", "run", "--rm", "--env=CODE_PATH=#{Dir.pwd}", \
|
29
|
+
"--volume=#{Dir.pwd}:/code", "--volume=/var/run/docker.sock:/var/run/docker.sock", \
|
30
|
+
"--volume=/tmp/cc:/tmp/cc", "-i", "codeclimate/codeclimate", "analyze"
|
31
|
+
]
|
32
|
+
|
33
|
+
file = File.open(".analysis", "w+")
|
34
|
+
Open3.popen3(cmd.shelljoin) do |_, out, err, _|
|
35
|
+
while data = out.gets
|
36
|
+
file.write data
|
37
|
+
if data =~ /\A==/
|
38
|
+
$stdout.print ansi.yellow(data)
|
39
|
+
|
40
|
+
elsif data !~ %r!\A[0-9\-]+!
|
41
|
+
$stdout.puts data
|
42
|
+
|
43
|
+
else
|
44
|
+
h, d = data.split(":", 2)
|
45
|
+
$stdout.print ansi.cyan(h)
|
46
|
+
$stdout.print ":", d
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
while data = err.gets
|
51
|
+
file.write data
|
52
|
+
$stderr.print ansi.red(data)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
file.close
|
57
|
+
end
|
data/bin/docker-template
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
# Copyright: 2015 Jordon Bedwell - Apache v2.0 License
|
4
4
|
# Encoding: utf-8
|
5
5
|
|
6
|
-
|
7
|
-
"../lib", __dir__
|
8
|
-
))
|
6
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
9
7
|
|
10
8
|
trap :SIGINT do
|
11
9
|
$stderr.puts "\nApparently that's all for now."
|
@@ -20,5 +18,5 @@ rescue LoadError
|
|
20
18
|
require "docker/template"
|
21
19
|
end
|
22
20
|
|
23
|
-
Docker::Template::Interface
|
24
|
-
start($
|
21
|
+
Docker::Template::Interface \
|
22
|
+
.start($PROGRAM_NAME)
|
data/lib/docker/template.rb
CHANGED
@@ -12,7 +12,9 @@ require "erb"
|
|
12
12
|
require "set"
|
13
13
|
|
14
14
|
module Docker
|
15
|
-
module Template
|
15
|
+
module Template
|
16
|
+
module_function
|
17
|
+
|
16
18
|
autoload :Util, "docker/template/util"
|
17
19
|
autoload :Config, "docker/template/config"
|
18
20
|
autoload :Ansi, "docker/template/ansi"
|
@@ -31,8 +33,12 @@ module Docker
|
|
31
33
|
autoload :Alias, "docker/template/alias"
|
32
34
|
autoload :Auth, "docker/template/auth"
|
33
35
|
|
36
|
+
def repo_is_root?
|
37
|
+
root.join("copy").exist? && !root.join("../..", config["repos_dir"]).exist?
|
38
|
+
end
|
39
|
+
|
34
40
|
def config
|
35
|
-
|
41
|
+
@config ||= begin
|
36
42
|
Config.new
|
37
43
|
end
|
38
44
|
end
|
@@ -40,7 +46,7 @@ module Docker
|
|
40
46
|
#
|
41
47
|
|
42
48
|
def root
|
43
|
-
|
49
|
+
@root ||= begin
|
44
50
|
Pathname.new(Dir.pwd)
|
45
51
|
end
|
46
52
|
end
|
@@ -51,17 +57,23 @@ module Docker
|
|
51
57
|
# guarantees that an absolute path will work.
|
52
58
|
|
53
59
|
def repos_root
|
54
|
-
|
60
|
+
@repos_root ||= begin
|
55
61
|
root.join(config["repos_dir"])
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
65
|
+
#
|
66
|
+
|
67
|
+
def repo_root_for(name)
|
68
|
+
repo_is_root?? root : repos_root.join(name)
|
69
|
+
end
|
70
|
+
|
59
71
|
# Provides the root to Docker template, wherever it is installed so that
|
60
|
-
# we can do things, mostly ignore files for the profiler.
|
72
|
+
# we can do things, mostly ignore files for the profiler. Otherwise it's
|
61
73
|
# not really used, it's just an encapsulator.
|
62
74
|
|
63
75
|
def gem_root
|
64
|
-
|
76
|
+
@gem_root ||= begin
|
65
77
|
path = File.expand_path("../../", __dir__)
|
66
78
|
Pathname.new(path)
|
67
79
|
end
|
@@ -71,7 +83,7 @@ module Docker
|
|
71
83
|
# from our templates and use it if you wish to.
|
72
84
|
|
73
85
|
def template_root
|
74
|
-
|
86
|
+
@template_root ||= begin
|
75
87
|
gem_root.join("lib/docker/template/templates")
|
76
88
|
end
|
77
89
|
end
|
data/lib/docker/template/ansi.rb
CHANGED
@@ -4,18 +4,28 @@
|
|
4
4
|
|
5
5
|
module Docker
|
6
6
|
module Template
|
7
|
-
module Ansi
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
module Ansi
|
8
|
+
module_function
|
9
|
+
|
10
|
+
ESCAPE = format("%c", 27)
|
11
|
+
MATCH = /#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m/ix.freeze
|
12
|
+
COLORS = {
|
13
|
+
:red => 31,
|
14
|
+
:green => 32,
|
15
|
+
:black => 30,
|
16
|
+
:magenta => 35,
|
17
|
+
:yellow => 33,
|
18
|
+
:white => 37,
|
19
|
+
:blue => 34,
|
20
|
+
:cyan => 36
|
21
|
+
}
|
12
22
|
|
13
23
|
# Strip ANSI from the current string. It also strips cursor stuff,
|
14
24
|
# well some of it, and it also strips some other stuff that a lot of
|
15
25
|
# the other ANSI strippers don't.
|
16
26
|
|
17
27
|
def strip(str)
|
18
|
-
str.gsub
|
28
|
+
str.gsub MATCH, ""
|
19
29
|
end
|
20
30
|
|
21
31
|
# Reset the vterm view if it's supported. Depending on how badly
|
@@ -23,24 +33,24 @@ module Docker
|
|
23
33
|
# with a few empty lines added on the top.
|
24
34
|
|
25
35
|
def clear
|
26
|
-
$stdout.print("%c[H%c[2J"
|
36
|
+
$stdout.print(format("%c[H%c[2J", 27, 27))
|
27
37
|
end
|
28
38
|
|
29
39
|
#
|
30
40
|
|
31
41
|
def has?(str)
|
32
|
-
!!(str =~
|
42
|
+
!!(str =~ MATCH)
|
33
43
|
end
|
34
44
|
|
35
45
|
# Jump the cursor up and then back down or just up and down. This is
|
36
46
|
# useful when streaming async downloads from something like Docker. It
|
37
47
|
# also works better than using `tput`
|
38
48
|
|
39
|
-
def jump(str = "", up: nil, down: nil, both: nil
|
40
|
-
str = clear_line(str)
|
49
|
+
def jump(str = "", up: nil, down: nil, both: nil)
|
50
|
+
str = clear_line(str)
|
41
51
|
|
42
|
-
return "%c[%dA%s%c[%dB"
|
43
|
-
up ? "%c[%dA%s"
|
52
|
+
return format("%c[%dA%s%c[%dB", 27, up || both, str, 27, down || both) if (up && down) || both
|
53
|
+
up ? format("%c[%dA%s", 27, up, str) : format("%s%c[%dB", str, 27, down)
|
44
54
|
end
|
45
55
|
|
46
56
|
# Reset the color back to the default color so that you do not leak any
|
@@ -48,26 +58,26 @@ module Docker
|
|
48
58
|
# used as part of a wrapper so that we don't leak colors.
|
49
59
|
|
50
60
|
def reset(str = "")
|
51
|
-
@ansi_reset ||= "%c[0m"
|
61
|
+
@ansi_reset ||= format("%c[0m", 27)
|
52
62
|
"#{@ansi_reset}#{str}"
|
53
63
|
end
|
54
64
|
|
55
65
|
#
|
56
66
|
|
57
67
|
def clear_line(str = "")
|
58
|
-
@ansi_clear_line ||= "%c[2K\r"
|
68
|
+
@ansi_clear_line ||= format("%c[2K\r", 27)
|
59
69
|
"#{@ansi_clear_line}#{str}\r"
|
60
70
|
end
|
61
71
|
|
62
|
-
# SEE: `self::
|
72
|
+
# SEE: `self::COLORS` for a list of methods. They are mostly
|
63
73
|
# standard base colors supported by pretty much any xterm-color, we do
|
64
74
|
# not need more than the base colors so we do not include them.
|
65
75
|
# Actually... if I'm honest we don't even need most of the
|
66
76
|
# base colors.
|
67
77
|
|
68
|
-
|
78
|
+
COLORS.each do |color, num|
|
69
79
|
define_method color do |str|
|
70
|
-
"#{"%c"
|
80
|
+
"#{format("%c", 27)}[#{num}m#{str}#{reset}"
|
71
81
|
end; module_function color
|
72
82
|
end
|
73
83
|
end
|
data/lib/docker/template/auth.rb
CHANGED
@@ -4,7 +4,7 @@ module Docker
|
|
4
4
|
module_function
|
5
5
|
|
6
6
|
def auth!
|
7
|
-
return unless login =
|
7
|
+
return unless login = credentials
|
8
8
|
login["auths"].each do |server, auth|
|
9
9
|
username, password = Base64.decode64(auth["auth"]).split(":", 2)
|
10
10
|
Docker.authenticate!({
|
@@ -16,9 +16,9 @@ module Docker
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def credentials
|
20
20
|
path = Pathname.new("~/.docker/config.json").expand_path
|
21
|
-
|
21
|
+
JSON.parse(path.read) if path.exist?
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -35,9 +35,9 @@ module Docker
|
|
35
35
|
|
36
36
|
def parent_repo
|
37
37
|
return false unless aliased?
|
38
|
-
@parent_repo ||=
|
39
|
-
"tag" => @repo.aliased
|
40
|
-
|
38
|
+
@parent_repo ||= begin
|
39
|
+
Repo.new(@repo.to_h.merge("tag" => @repo.aliased))
|
40
|
+
end
|
41
41
|
end
|
42
42
|
|
43
43
|
#
|
@@ -58,14 +58,8 @@ module Docker
|
|
58
58
|
|
59
59
|
Ansi.clear
|
60
60
|
Util.notify_build(@repo, rootfs: rootfs?)
|
61
|
-
logger = Stream.new.method(:log)
|
62
61
|
copy_build_and_verify
|
63
|
-
|
64
|
-
Dir.chdir(@context) do
|
65
|
-
@img = Docker::Image.build_from_dir(".", &logger)
|
66
|
-
@img.tag rootfs?? @repo.to_rootfs_h : @repo.to_tag_h
|
67
|
-
push
|
68
|
-
end
|
62
|
+
chdir_build
|
69
63
|
rescue SystemExit => exit_
|
70
64
|
unlink img: true
|
71
65
|
raise exit_
|
@@ -77,6 +71,16 @@ module Docker
|
|
77
71
|
|
78
72
|
#
|
79
73
|
|
74
|
+
def chdir_build
|
75
|
+
Dir.chdir(@context) do
|
76
|
+
@img = Docker::Image.build_from_dir(".", &Stream.new.method(:log))
|
77
|
+
@img.tag rootfs?? @repo.to_rootfs_h : @repo.to_tag_h
|
78
|
+
push
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
|
80
84
|
private
|
81
85
|
def copy_build_and_verify
|
82
86
|
unless respond_to?(:setup_context, true)
|
@@ -18,11 +18,13 @@ module Docker
|
|
18
18
|
def_delegator :@config, :keys
|
19
19
|
def_delegator :@config, :to_h
|
20
20
|
def_delegator :@config, :to_enum
|
21
|
+
def_delegator :@config, :key?, :has_default?
|
21
22
|
def_delegator :@config, :has_key?
|
23
|
+
def_delegator :@config, :key?
|
22
24
|
def_delegator :@config, :each
|
23
25
|
def_delegator :@config, :[]
|
24
26
|
|
25
|
-
|
27
|
+
DEFAULTS = {
|
26
28
|
"type" => "simple",
|
27
29
|
"user" => "envygeeks",
|
28
30
|
"local_prefix" => "local",
|
@@ -33,24 +35,24 @@ module Docker
|
|
33
35
|
"copy_dir" => "copy",
|
34
36
|
"tag" => "latest",
|
35
37
|
|
36
|
-
"
|
37
|
-
|
38
|
-
"entries"
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
"env" => { "tag" => {}, "type" => {}, "all" => nil },
|
39
|
+
"pkgs" => { "tag" => {}, "type" => {}, "all" => nil },
|
40
|
+
"entries" => { "tag" => {}, "type" => {}, "all" => nil },
|
41
|
+
"releases" => { "tag" => {}, "type" => {}, "all" => nil },
|
42
|
+
"versions" => { "tag" => {}, "type" => {}, "all" => nil },
|
43
|
+
"aliases" => {},
|
44
|
+
"tags" => {}
|
43
45
|
}.freeze
|
44
46
|
|
45
|
-
|
47
|
+
EMPTY_DEFAULTS = {
|
46
48
|
"tags" => { "latest" => "normal" }
|
47
49
|
}
|
48
50
|
|
49
51
|
#
|
50
52
|
|
51
53
|
def initialize
|
52
|
-
@config =
|
53
|
-
@config = @config.merge(
|
54
|
+
@config = DEFAULTS.deep_merge(read_config_from)
|
55
|
+
@config = @config.merge(EMPTY_DEFAULTS) do |_, oval, nval|
|
54
56
|
oval.nil? || oval.empty?? nval : oval
|
55
57
|
end
|
56
58
|
|
@@ -70,14 +72,8 @@ module Docker
|
|
70
72
|
|
71
73
|
#
|
72
74
|
|
73
|
-
def has_default?(key)
|
74
|
-
return @config.has_key?(key)
|
75
|
-
end
|
76
|
-
|
77
|
-
#
|
78
|
-
|
79
75
|
def build_types
|
80
|
-
|
76
|
+
@build_types ||= %W(simple scratch).freeze
|
81
77
|
end
|
82
78
|
end
|
83
79
|
end
|
@@ -32,12 +32,11 @@ module Docker
|
|
32
32
|
|
33
33
|
private
|
34
34
|
def sync
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
35
|
+
return unless wants_sync?
|
36
|
+
Parser.new.parse.each do |repo|
|
37
|
+
next unless repo.syncable?
|
38
|
+
repo.builder.tap(&:sync) \
|
39
|
+
.unlink(sync: false)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
@@ -45,7 +44,7 @@ module Docker
|
|
45
44
|
|
46
45
|
private
|
47
46
|
def argv_without_flags
|
48
|
-
|
47
|
+
@argv.select do |val|
|
49
48
|
!["--sync", "--push"].include?(val)
|
50
49
|
end
|
51
50
|
end
|
@@ -81,9 +80,9 @@ module Docker
|
|
81
80
|
|
82
81
|
private
|
83
82
|
def self.discover
|
84
|
-
rtn = bins.
|
83
|
+
rtn = bins.find do |path|
|
85
84
|
path.basename.fnmatch?("docker") && path.executable_real?
|
86
|
-
end
|
85
|
+
end
|
87
86
|
|
88
87
|
if rtn
|
89
88
|
rtn.to_s
|
@@ -10,12 +10,12 @@ module Docker
|
|
10
10
|
# Provides aliases for the root element so you can do something like:
|
11
11
|
# * data["release"].fallback
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
ALIASES = {
|
14
|
+
"entry" => "entries",
|
15
15
|
"release" => "releases",
|
16
16
|
"version" => "versions",
|
17
|
-
|
18
|
-
|
17
|
+
"script" => "scripts",
|
18
|
+
"image" => "images"
|
19
19
|
}
|
20
20
|
|
21
21
|
def_delegator :@metadata, :keys
|
@@ -26,6 +26,7 @@ module Docker
|
|
26
26
|
def_delegator :@metadata, :delete
|
27
27
|
def_delegator :@metadata, :each
|
28
28
|
def_delegator :@metadata, :to_h
|
29
|
+
def_delegator :@metadata, :key?
|
29
30
|
route_to_ivar :is_root, :@is_root, bool: true
|
30
31
|
route_to_hash :for_all, :self, :all
|
31
32
|
|
@@ -34,22 +35,24 @@ module Docker
|
|
34
35
|
@root_metadata = root_metadata || {}
|
35
36
|
@metadata = metadata || {}
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
return unless is_root?
|
39
|
+
@root_metadata = @metadata
|
40
|
+
@base = Template.config
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
|
45
|
+
def as_gem_version
|
46
|
+
"#{self["repo"]}@#{self["version"].fallback}"
|
41
47
|
end
|
42
48
|
|
43
49
|
#
|
44
50
|
|
45
51
|
def aliased
|
46
|
-
aliases = from_root("aliases")
|
47
52
|
tag = from_root("tag")
|
48
|
-
|
49
|
-
if aliases.
|
50
|
-
|
51
|
-
end
|
52
|
-
tag
|
53
|
+
aliases = from_root("aliases")
|
54
|
+
return aliases[tag] if aliases.key?(tag)
|
55
|
+
tag
|
53
56
|
end
|
54
57
|
|
55
58
|
# Queries providing a default value if on the root repo hash otherwise
|
@@ -72,8 +75,8 @@ module Docker
|
|
72
75
|
|
73
76
|
#
|
74
77
|
|
75
|
-
def merge(
|
76
|
-
@metadata.merge!(
|
78
|
+
def merge(new_)
|
79
|
+
@metadata.merge!(new_)
|
77
80
|
self
|
78
81
|
end
|
79
82
|
|
@@ -86,18 +89,19 @@ module Docker
|
|
86
89
|
#
|
87
90
|
|
88
91
|
def as_hash
|
89
|
-
{}
|
90
|
-
|
91
|
-
|
92
|
+
{} \
|
93
|
+
.merge(for_all.to_h) \
|
94
|
+
.merge(by_type.to_h) \
|
95
|
+
.merge(by_tag. to_h)
|
92
96
|
end
|
93
97
|
|
94
98
|
#
|
95
99
|
|
96
100
|
def as_set
|
97
|
-
Set.new
|
98
|
-
merge(for_all.to_a)
|
99
|
-
merge(by_type.to_a)
|
100
|
-
merge(by_tag .to_a)
|
101
|
+
Set.new \
|
102
|
+
.merge(for_all.to_a) \
|
103
|
+
.merge(by_type.to_a) \
|
104
|
+
.merge(by_tag .to_a)
|
101
105
|
end
|
102
106
|
|
103
107
|
#
|
@@ -118,7 +122,7 @@ module Docker
|
|
118
122
|
|
119
123
|
def by_tag
|
120
124
|
return unless tag = aliased
|
121
|
-
return unless
|
125
|
+
return unless key?("tag")
|
122
126
|
hash = self["tag"]
|
123
127
|
hash[tag]
|
124
128
|
end
|
@@ -129,8 +133,8 @@ module Docker
|
|
129
133
|
|
130
134
|
def by_type
|
131
135
|
return unless tag = aliased
|
132
|
-
type =
|
133
|
-
return unless
|
136
|
+
type = from_root("tags")[tag]
|
137
|
+
return unless key?("type")
|
134
138
|
return unless type
|
135
139
|
|
136
140
|
hash = self["type"]
|
@@ -141,10 +145,10 @@ module Docker
|
|
141
145
|
|
142
146
|
private
|
143
147
|
def determine_key(key)
|
144
|
-
if is_root? && !
|
145
|
-
key =
|
148
|
+
if is_root? && !key?(key) && ALIASES.key?(key)
|
149
|
+
key = ALIASES[key]
|
146
150
|
end
|
147
|
-
|
151
|
+
key
|
148
152
|
end
|
149
153
|
|
150
154
|
#
|
@@ -5,9 +5,9 @@
|
|
5
5
|
module Docker
|
6
6
|
module Template
|
7
7
|
class Parser
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
SLASH_REGEXP = /\//.freeze
|
9
|
+
SPLIT_REGEXP = /:|\//.freeze
|
10
|
+
COLON_REGEXP = /:/.freeze
|
11
11
|
|
12
12
|
def initialize(argv = [].freeze)
|
13
13
|
@argv = argv.freeze
|
@@ -19,7 +19,7 @@ module Docker
|
|
19
19
|
|
20
20
|
def all
|
21
21
|
return @argv unless @argv.empty?
|
22
|
-
|
22
|
+
Template.repos_root.children.map do |path|
|
23
23
|
path.basename.to_s
|
24
24
|
end
|
25
25
|
rescue Errno::ENOENT
|
@@ -34,22 +34,24 @@ module Docker
|
|
34
34
|
raise Docker::Template::Error::BadRepoName, val if hash.empty?
|
35
35
|
out += as == :repos ? Repo.new(hash).to_repos : [hash]
|
36
36
|
end
|
37
|
-
|
37
|
+
out
|
38
38
|
end
|
39
39
|
|
40
40
|
#
|
41
41
|
|
42
42
|
private
|
43
43
|
def build_repo_hash(val)
|
44
|
-
data
|
44
|
+
data = val.split(SPLIT_REGEXP)
|
45
|
+
hsh = {}
|
46
|
+
|
45
47
|
if data.size == 1
|
46
48
|
hsh["repo"] = data[0]
|
47
49
|
|
48
|
-
elsif val =~
|
50
|
+
elsif val =~ COLON_REGEXP && data.size == 2
|
49
51
|
hsh["repo"] = data[0]
|
50
52
|
hsh[ "tag"] = data[1]
|
51
53
|
|
52
|
-
elsif val =~
|
54
|
+
elsif val =~ SLASH_REGEXP && data.size == 2
|
53
55
|
hsh["user"] = data[0]
|
54
56
|
hsh["repo"] = data[1]
|
55
57
|
|
@@ -58,7 +60,6 @@ module Docker
|
|
58
60
|
hsh["repo"] = data[1]
|
59
61
|
hsh[ "tag"] = data[2]
|
60
62
|
end
|
61
|
-
|
62
63
|
hsh
|
63
64
|
end
|
64
65
|
end
|
@@ -4,18 +4,17 @@
|
|
4
4
|
|
5
5
|
class Hash
|
6
6
|
def to_env
|
7
|
-
|
7
|
+
each_with_object({}) do |(key, val), hsh|
|
8
8
|
val = val.is_a?(Array) ? val.join(" ") : val.to_s
|
9
9
|
key = key.to_s.upcase
|
10
10
|
hsh[key] = val
|
11
|
-
hsh
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
15
14
|
#
|
16
15
|
|
17
16
|
def any_keys?(*keys)
|
18
|
-
keys.map(&method(:
|
17
|
+
keys.map(&method(:key?)).any? do |val|
|
19
18
|
val == true
|
20
19
|
end
|
21
20
|
end
|
@@ -23,32 +22,31 @@ class Hash
|
|
23
22
|
#
|
24
23
|
|
25
24
|
def leftover_keys?(*keys)
|
26
|
-
|
25
|
+
(self.keys - keys).any?
|
27
26
|
end
|
28
27
|
|
29
28
|
#
|
30
29
|
|
31
|
-
def
|
30
|
+
def keys?(*keys)
|
32
31
|
return false unless rtn = true && any?
|
33
32
|
while rtn && key = keys.shift
|
34
|
-
rtn =
|
33
|
+
rtn = key?(key) || false
|
35
34
|
end
|
36
|
-
|
37
|
-
rtn
|
35
|
+
rtn
|
38
36
|
end
|
39
37
|
|
40
38
|
#
|
41
39
|
|
42
40
|
def to_env_ary
|
43
|
-
|
44
|
-
|
41
|
+
each_with_object([]) do |(key, val), ary|
|
42
|
+
ary << "#{key}=#{val}"
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
48
46
|
#
|
49
47
|
|
50
48
|
def deep_merge(newh)
|
51
|
-
merge(newh) do |
|
49
|
+
merge(newh) do |_, oval, nval|
|
52
50
|
if oval.is_a?(self.class) && nval.is_a?(self.class)
|
53
51
|
then oval.deep_merge(nval) else nval
|
54
52
|
end
|
@@ -58,19 +56,16 @@ class Hash
|
|
58
56
|
#
|
59
57
|
|
60
58
|
def stringify
|
61
|
-
|
59
|
+
each_with_object({}) do |(key, val), hsh|
|
62
60
|
hsh[key.to_s] = val.is_a?(Array) || val.is_a?(Hash) ? val.stringify : val.to_s
|
63
|
-
hsh
|
64
61
|
end
|
65
62
|
end
|
66
63
|
|
67
64
|
#
|
68
65
|
|
69
66
|
def stringify_keys
|
70
|
-
|
67
|
+
each_with_object({}) do |(key, val), hsh|
|
71
68
|
hsh[key.to_s] = val
|
72
|
-
|
73
|
-
hsh
|
74
69
|
end
|
75
70
|
end
|
76
71
|
end
|
@@ -11,7 +11,7 @@ class Pathname
|
|
11
11
|
#
|
12
12
|
|
13
13
|
def write(data)
|
14
|
-
File.write(
|
14
|
+
File.write(to_s, data)
|
15
15
|
end
|
16
16
|
|
17
17
|
#
|
@@ -25,7 +25,7 @@ class Pathname
|
|
25
25
|
#
|
26
26
|
|
27
27
|
def expanded_realpath
|
28
|
-
|
28
|
+
@expanded_real_path ||= begin
|
29
29
|
expanded_path.realpath
|
30
30
|
end
|
31
31
|
end
|
@@ -39,7 +39,7 @@ class Pathname
|
|
39
39
|
#
|
40
40
|
|
41
41
|
def glob(*args)
|
42
|
-
Dir.glob(
|
42
|
+
Dir.glob(join(*args)).map do |path|
|
43
43
|
self.class.new(path)
|
44
44
|
end
|
45
45
|
end
|
data/lib/docker/template/repo.rb
CHANGED
@@ -12,6 +12,7 @@ module Docker
|
|
12
12
|
class Repo
|
13
13
|
extend Forwardable, Routable
|
14
14
|
|
15
|
+
def_delegator :builder, :build
|
15
16
|
route_to_hash :name, :@base_metadata, :repo
|
16
17
|
route_to_hash [:tag, :type, :user], :metadata
|
17
18
|
def_delegator :@base_metadata, :to_h
|
@@ -19,12 +20,12 @@ module Docker
|
|
19
20
|
def_delegator :metadata, :tags
|
20
21
|
|
21
22
|
def initialize(base_metadata)
|
22
|
-
raise ArgumentError, "Metadata not a hash"
|
23
|
-
|
23
|
+
raise ArgumentError, "Metadata not a hash" unless base_metadata.is_a?(Hash)
|
24
|
+
|
24
25
|
@base_metadata = base_metadata.freeze
|
25
26
|
@sync_allowed = type == "simple" ? true : false
|
26
|
-
raise Error::InvalidRepoType, type
|
27
|
-
raise Error::RepoNotFound, name
|
27
|
+
raise Error::InvalidRepoType, type unless Template.config.build_types.include?(type)
|
28
|
+
raise Error::RepoNotFound, name unless root.exist?
|
28
29
|
end
|
29
30
|
|
30
31
|
def builder
|
@@ -32,14 +33,6 @@ module Docker
|
|
32
33
|
const.new(self)
|
33
34
|
end
|
34
35
|
|
35
|
-
# Simply initializes the the builder and passes itself onto
|
36
|
-
# it so that it the builder can take over and do it's job cleanly
|
37
|
-
# without us needing to care about what's going on.
|
38
|
-
|
39
|
-
def build
|
40
|
-
return builder.build
|
41
|
-
end
|
42
|
-
|
43
36
|
#
|
44
37
|
|
45
38
|
def disable_sync!
|
@@ -68,7 +61,7 @@ module Docker
|
|
68
61
|
#
|
69
62
|
|
70
63
|
def building_all?
|
71
|
-
|
64
|
+
!@base_metadata.key?("tag")
|
72
65
|
end
|
73
66
|
|
74
67
|
#
|
@@ -81,8 +74,8 @@ module Docker
|
|
81
74
|
#
|
82
75
|
|
83
76
|
def root
|
84
|
-
|
85
|
-
Template.
|
77
|
+
@root ||= begin
|
78
|
+
Template.repo_root_for(name)
|
86
79
|
end
|
87
80
|
end
|
88
81
|
|
@@ -90,9 +83,9 @@ module Docker
|
|
90
83
|
|
91
84
|
def to_tag_h
|
92
85
|
{
|
93
|
-
"
|
94
|
-
|
95
|
-
|
86
|
+
"tag" => tag,
|
87
|
+
"repo" => "#{user}/#{name}",
|
88
|
+
"force" => true
|
96
89
|
}
|
97
90
|
end
|
98
91
|
|
@@ -102,9 +95,9 @@ module Docker
|
|
102
95
|
prefix = metadata["local_prefix"]
|
103
96
|
|
104
97
|
{
|
105
|
-
"
|
106
|
-
|
107
|
-
|
98
|
+
"tag" => name,
|
99
|
+
"repo" => "#{prefix}/rootfs",
|
100
|
+
"force" => true
|
108
101
|
}
|
109
102
|
end
|
110
103
|
|
@@ -133,11 +126,12 @@ module Docker
|
|
133
126
|
|
134
127
|
def to_repos
|
135
128
|
if building_all?
|
136
|
-
|
129
|
+
set = Set.new
|
130
|
+
base = to_h
|
131
|
+
|
137
132
|
tags.each do |tag|
|
138
|
-
|
139
|
-
|
140
|
-
})))
|
133
|
+
base = base.merge("tag" => tag)
|
134
|
+
set << self.class.new(base)
|
141
135
|
end
|
142
136
|
|
143
137
|
set
|
@@ -151,8 +145,8 @@ module Docker
|
|
151
145
|
#
|
152
146
|
|
153
147
|
def metadata
|
154
|
-
|
155
|
-
metadata = Template.
|
148
|
+
@metadata ||= begin
|
149
|
+
metadata = Template.repo_root_for(name)
|
156
150
|
metadata = Template.config.read_config_from(metadata)
|
157
151
|
Metadata.new(metadata).merge(@base_metadata)
|
158
152
|
end
|
@@ -172,7 +166,7 @@ module Docker
|
|
172
166
|
"BUILD_TYPE" => type,
|
173
167
|
"COPY" => copy_dir,
|
174
168
|
"TAR" => tar_gz,
|
175
|
-
"TAG" => tag
|
169
|
+
"TAG" => tag
|
176
170
|
}).to_env
|
177
171
|
end
|
178
172
|
end
|
@@ -77,7 +77,7 @@ module Docker
|
|
77
77
|
# and stream the logs after it's exited if we have given no output,
|
78
78
|
# we want you to always get the output that was given.
|
79
79
|
|
80
|
-
|
80
|
+
unless output_given
|
81
81
|
img.streaming_logs "stdout" => true, "stderr" => true do |type, str|
|
82
82
|
type == :stdout ? $stdout.print(str) : $stderr.print(Ansi.red(str))
|
83
83
|
end
|
@@ -87,10 +87,7 @@ module Docker
|
|
87
87
|
raise Error::BadExitStatus, status
|
88
88
|
end
|
89
89
|
ensure
|
90
|
-
if img
|
91
|
-
img.stop rescue nil
|
92
|
-
img.delete
|
93
|
-
end
|
90
|
+
img.tap(&:stop).delete("force" => true) if img
|
94
91
|
end
|
95
92
|
|
96
93
|
#
|
@@ -130,7 +127,7 @@ module Docker
|
|
130
127
|
def start_args
|
131
128
|
{
|
132
129
|
"Binds" => [
|
133
|
-
"#{@copy
|
130
|
+
"#{@copy}:#{@copy}:ro", "#{@tar_gz}:#{@tar_gz}"
|
134
131
|
]
|
135
132
|
}
|
136
133
|
end
|
@@ -14,17 +14,15 @@ module Docker
|
|
14
14
|
|
15
15
|
def sync
|
16
16
|
copy_build_and_verify unless @context
|
17
|
-
Util.create_dockerhub_context(
|
18
|
-
self, @context)
|
17
|
+
Util.create_dockerhub_context(self, @context)
|
19
18
|
end
|
20
19
|
|
21
20
|
#
|
22
21
|
|
23
22
|
def unlink(img: false, sync: true)
|
24
|
-
self.sync if sync && @repo.syncable?
|
25
23
|
@img.delete "force" => true if @img && img
|
26
|
-
@context.rmtree if @context &&
|
27
|
-
|
24
|
+
@context.rmtree if @context && @context.directory?
|
25
|
+
self.sync if sync && @repo.syncable?
|
28
26
|
end
|
29
27
|
|
30
28
|
#
|
@@ -6,7 +6,7 @@ module Docker
|
|
6
6
|
module Template
|
7
7
|
class Stream
|
8
8
|
def initialize
|
9
|
-
@lines
|
9
|
+
@lines = {}
|
10
10
|
end
|
11
11
|
|
12
12
|
#
|
@@ -38,9 +38,9 @@ module Docker
|
|
38
38
|
end
|
39
39
|
|
40
40
|
before, diff = progress_diff(id)
|
41
|
-
$stdout.print
|
41
|
+
$stdout.print before if before
|
42
42
|
str = stream["progress"] || stream["status"]
|
43
|
-
str = "
|
43
|
+
str = "#{id}: #{str}\r"
|
44
44
|
|
45
45
|
$stdout.print(Ansi.jump(str, both: diff))
|
46
46
|
end
|
@@ -49,12 +49,13 @@ module Docker
|
|
49
49
|
|
50
50
|
private
|
51
51
|
def progress_diff(id)
|
52
|
-
if @lines.
|
52
|
+
if @lines.key?(id)
|
53
53
|
return nil, @lines.size - @lines[id]
|
54
54
|
end
|
55
55
|
|
56
56
|
@lines[id] = @lines.size
|
57
57
|
before = "\n" unless @lines.size == 1
|
58
|
+
# rubocop:disable RedundantReturn
|
58
59
|
return before, 0
|
59
60
|
end
|
60
61
|
end
|
data/lib/docker/template/util.rb
CHANGED
@@ -4,7 +4,9 @@
|
|
4
4
|
|
5
5
|
module Docker
|
6
6
|
module Template
|
7
|
-
module Util
|
7
|
+
module Util
|
8
|
+
module_function
|
9
|
+
|
8
10
|
autoload :Copy, "docker/template/util/copy"
|
9
11
|
autoload :Data, "docker/template/util/data"
|
10
12
|
|
@@ -24,15 +26,28 @@ module Docker
|
|
24
26
|
#
|
25
27
|
|
26
28
|
def create_dockerhub_context(builder, context)
|
27
|
-
|
28
|
-
|
29
|
-
context = tags.join(builder.repo.aliased) if builder.aliased?
|
30
|
-
dir = tags.join(builder.repo.tag)
|
31
|
-
|
29
|
+
dir = builder.repo.root.join("tags", builder.repo.tag)
|
30
|
+
context = get_context(builder, context)
|
32
31
|
FileUtils.mkdir_p dir
|
33
|
-
|
32
|
+
|
33
|
+
$stdout.puts Ansi.yellow("Copying context for #{builder.repo}")
|
34
|
+
Util::Copy.file(readme_file(builder), dir)
|
34
35
|
Util::Copy.directory(context, dir)
|
35
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
|
40
|
+
def get_context(builder, context)
|
41
|
+
return context unless builder.aliased?
|
42
|
+
builder.repo.root.join("tags", builder.repo.aliased)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
|
47
|
+
def readme_file(builder)
|
48
|
+
builder.repo.root.children.find do |val|
|
49
|
+
val.to_s =~ /readme/i
|
50
|
+
end
|
36
51
|
end
|
37
52
|
end
|
38
53
|
end
|
@@ -8,7 +8,7 @@ module Docker
|
|
8
8
|
class Copy
|
9
9
|
def initialize(from, to)
|
10
10
|
@root = Template.root.realpath
|
11
|
-
@repos_root = Template.repos_root.realpath
|
11
|
+
@repos_root = Template.repo_is_root?? Template.root.realpath : Template.repos_root.realpath
|
12
12
|
@from = from.to_pathname
|
13
13
|
@to = to.to_pathname
|
14
14
|
end
|
@@ -30,18 +30,15 @@ module Docker
|
|
30
30
|
def directory
|
31
31
|
FileUtils.cp_r(@from.children, @to, :dereference_root => false)
|
32
32
|
@from.all_children.select(&:symlink?).each do |path|
|
33
|
+
path = @to.join(path.relative_path_from(@from))
|
33
34
|
resolved = path.realpath
|
34
|
-
pth = path.relative_path_from(@from)
|
35
|
-
pth = @to.join(path)
|
36
35
|
|
37
36
|
unless in_path?(resolved)
|
38
|
-
raise Errno::EPERM, "#{
|
37
|
+
raise Errno::EPERM, "#{path} not in #{@root}"
|
39
38
|
end
|
40
39
|
|
41
|
-
FileUtils.rm_r(
|
42
|
-
FileUtils.cp_r(resolved,
|
43
|
-
:dereference_root => false
|
44
|
-
})
|
40
|
+
FileUtils.rm_r(path)
|
41
|
+
FileUtils.cp_r(resolved, path, :dereference_root => false)
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
@@ -56,9 +53,7 @@ module Docker
|
|
56
53
|
#
|
57
54
|
|
58
55
|
def file
|
59
|
-
|
60
|
-
return FileUtils.cp(@from, @to)
|
61
|
-
end
|
56
|
+
return FileUtils.cp(@from, @to) unless @from.symlink?
|
62
57
|
|
63
58
|
resolved = @from.realpath
|
64
59
|
allowed = resolved.in_path?(@root)
|
@@ -73,8 +68,8 @@ module Docker
|
|
73
68
|
private
|
74
69
|
def in_path?(resolved)
|
75
70
|
resolved.in_path?(@repos_root) || \
|
76
|
-
|
77
|
-
|
71
|
+
resolved.in_path?(@from.realpath) || \
|
72
|
+
resolved.in_path?(@root)
|
78
73
|
end
|
79
74
|
end
|
80
75
|
end
|