qb 0.3.25 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/ansible.cfg +10 -1
- data/exe/.qb_interop_receive +3 -10
- data/exe/qb +8 -2
- data/lib/python/qb/__init__.py +6 -0
- data/{roles/qb/ruby/rspec/setup/tasks/persistence.yml → lib/python/qb/ansible/__init__.py} +0 -0
- data/lib/python/qb/ansible/modules/__init__.py +0 -0
- data/lib/python/qb/ansible/modules/docker/__init__.py +0 -0
- data/lib/python/qb/ansible/modules/docker/client.py +177 -0
- data/lib/python/qb/ansible/modules/docker/image_manager.py +754 -0
- data/lib/python/qb/ipc/__init__.py +0 -0
- data/lib/python/qb/ipc/stdio/__init__.py +99 -0
- data/lib/python/qb/ipc/stdio/logging.py +151 -0
- data/lib/qb.rb +3 -3
- data/lib/qb/ansible/cmds/playbook.rb +5 -14
- data/lib/qb/ansible/env.rb +36 -6
- data/lib/qb/ansible/module.rb +396 -152
- data/lib/qb/ansible/module/response.rb +195 -0
- data/lib/qb/ansible/modules.rb +42 -0
- data/lib/qb/ansible/modules/docker/image.rb +273 -0
- data/lib/qb/cli.rb +5 -18
- data/lib/qb/cli/run.rb +2 -2
- data/lib/qb/data.rb +22 -0
- data/lib/qb/data/immutable.rb +39 -0
- data/lib/qb/docker.rb +2 -0
- data/lib/qb/docker/cli.rb +430 -0
- data/lib/qb/docker/image.rb +207 -0
- data/lib/qb/docker/image/name.rb +309 -0
- data/lib/qb/docker/image/tag.rb +113 -0
- data/lib/qb/docker/repo.rb +0 -0
- data/lib/qb/errors.rb +17 -3
- data/lib/qb/execution.rb +83 -0
- data/lib/qb/ipc.rb +48 -0
- data/lib/qb/ipc/stdio.rb +32 -0
- data/lib/qb/ipc/stdio/client.rb +267 -0
- data/lib/qb/ipc/stdio/server.rb +229 -0
- data/lib/qb/ipc/stdio/server/in_service.rb +18 -0
- data/lib/qb/ipc/stdio/server/log_service.rb +168 -0
- data/lib/qb/ipc/stdio/server/out_service.rb +20 -0
- data/lib/qb/ipc/stdio/server/service.rb +229 -0
- data/lib/qb/options.rb +360 -502
- data/lib/qb/options/option.rb +293 -115
- data/lib/qb/options/option/option_parser_concern.rb +228 -0
- data/lib/qb/options/types.rb +73 -0
- data/lib/qb/package.rb +0 -1
- data/lib/qb/package/version.rb +179 -58
- data/lib/qb/package/version/from.rb +192 -51
- data/lib/qb/package/version/leveled.rb +1 -1
- data/lib/qb/path.rb +3 -2
- data/lib/qb/repo/git.rb +9 -85
- data/lib/qb/role/default_dir.rb +2 -2
- data/lib/qb/role/errors.rb +2 -8
- data/lib/qb/util.rb +1 -2
- data/lib/qb/util/bundler.rb +73 -43
- data/lib/qb/util/decorators.rb +99 -0
- data/lib/qb/util/interop.rb +7 -8
- data/lib/qb/util/resource.rb +12 -13
- data/lib/qb/version.rb +10 -0
- data/library/path_facts +5 -10
- data/library/qb.module.rb +105 -0
- data/library/stream +6 -26
- data/load/ansible/module/autorun.rb +25 -0
- data/load/ansible/module/script.rb +123 -0
- data/load/rebundle.rb +39 -0
- data/plugins/filter/dict_filters.py +56 -0
- data/plugins/{filter_plugins/path_plugins.py → filter/path_filters.py} +0 -0
- data/plugins/{filter_plugins/ruby_interop_plugins.py → filter/ruby_interop_filters.py} +1 -17
- data/plugins/{filter_plugins/string_plugins.py → filter/string_filters.py} +1 -20
- data/plugins/{filter_plugins/version_plugins.py → filter/version_filters.py} +3 -18
- data/plugins/{lookup_plugins/every.py → lookup/every_lookups.py} +0 -0
- data/plugins/{lookup_plugins/resolve.py → lookup/resolve_lookups.py} +0 -0
- data/plugins/{lookup_plugins/version.py → lookup/version_lookups.py} +0 -16
- data/plugins/test/dict_tests.py +36 -0
- data/plugins/test/string_tests.py +36 -0
- data/qb.gemspec +7 -3
- data/roles/nrser.rb/library/set_fact_with_ruby.rb +3 -9
- data/roles/nrser.state_mate/library/state +3 -17
- data/roles/qb/call/meta/qb.yml +1 -1
- data/roles/qb/dev/ref/repo/git/meta/qb.yml +1 -1
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/defaults/main.yml +1 -1
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/main.yml +3 -2
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/qb.yml +12 -7
- data/roles/qb/docker/mac/kubernetes/tasks/main.yml +45 -0
- data/roles/qb/git/check/clean/meta/qb.yml +1 -1
- data/roles/qb/git/ignore/meta/qb +10 -3
- data/roles/qb/git/submodule/update/library/git_submodule_update +17 -27
- data/roles/qb/github/pages/setup/meta/qb.yml +1 -1
- data/roles/qb/labs/atom/apm/meta/qb.yml +1 -1
- data/roles/qb/osx/git/change_case/meta/qb.yml +1 -1
- data/roles/qb/osx/notif/meta/qb.yml +1 -1
- data/roles/qb/pkg/bump/library/bump +4 -16
- data/roles/qb/role/qb/defaults/main.yml +2 -0
- data/roles/qb/role/qb/meta/qb.yml +10 -5
- data/roles/qb/role/qb/templates/qb.yml.j2 +7 -2
- data/roles/qb/role/templates/library/module.rb.j2 +12 -23
- data/roles/qb/role/templates/meta/main.yml.j2 +14 -1
- data/roles/qb/ruby/bundler/meta/qb.yml +1 -1
- data/roles/qb/ruby/dependency/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/bin_stubs/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/bin_stubs/templates/console +8 -2
- data/roles/qb/ruby/gem/build/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/new/meta/qb.yml +1 -1
- data/roles/qb/ruby/nrser/rspex/generate/meta/qb.yml +5 -5
- data/roles/qb/ruby/nrser/rspex/issue/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/clean/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/config/library/yard.get_output_dir +5 -15
- data/roles/qb/ruby/yard/config/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/setup/meta/qb.yml +1 -1
- metadata +71 -22
- data/lib/qb/ansible_module.rb +0 -5
- data/lib/qb/util/stdio.rb +0 -187
- data/roles/qb/ruby/rspec/setup/tasks/main.yml +0 -4
@@ -0,0 +1,207 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Deps
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
# Project / Package
|
14
|
+
# -----------------------------------------------------------------------
|
15
|
+
|
16
|
+
require 'qb/data'
|
17
|
+
|
18
|
+
require_relative './image/name'
|
19
|
+
require_relative './image/tag'
|
20
|
+
|
21
|
+
|
22
|
+
# Refinements
|
23
|
+
# =======================================================================
|
24
|
+
|
25
|
+
require 'nrser/refinements/types'
|
26
|
+
using NRSER::Types
|
27
|
+
|
28
|
+
|
29
|
+
# Definitions
|
30
|
+
# =======================================================================
|
31
|
+
|
32
|
+
# @todo document Docker::Image class.
|
33
|
+
module QB
|
34
|
+
module Docker
|
35
|
+
class Image < QB::Data::Immutable
|
36
|
+
|
37
|
+
include NRSER::Log::Mixin
|
38
|
+
|
39
|
+
# Constants
|
40
|
+
# ======================================================================
|
41
|
+
|
42
|
+
|
43
|
+
# Class Methods
|
44
|
+
# ======================================================================
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
def self.with_name name, &block
|
50
|
+
block.call \
|
51
|
+
case name
|
52
|
+
when QB::Docker::Image::Name
|
53
|
+
name
|
54
|
+
when String
|
55
|
+
QB::Docker::Image::Name.from_s name
|
56
|
+
when Hash
|
57
|
+
QB::Docker::Image::Name.from_data name
|
58
|
+
else
|
59
|
+
raise NRSER::TypeError.new \
|
60
|
+
"Not sure what to do with ", name,
|
61
|
+
name: name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def self.names **opts
|
67
|
+
QB::Docker::CLI.image_names **opts
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def self.run_cmd cmd, stream: true, raise_on_fail: false
|
72
|
+
if stream
|
73
|
+
if raise_on_fail
|
74
|
+
cmd.stream!
|
75
|
+
else
|
76
|
+
cmd.stream
|
77
|
+
end
|
78
|
+
else
|
79
|
+
cmd.capture.tap { |result|
|
80
|
+
if raise_on_fail && result.error?
|
81
|
+
raise QB::Docker::CLI::Error.from_result result
|
82
|
+
end
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def self.run_cmd! cmd, stream: true
|
89
|
+
run_cmd cmd, stream: stream, raise_on_fail: true
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def self.build! name:,
|
94
|
+
path:,
|
95
|
+
push: false,
|
96
|
+
tags: [],
|
97
|
+
_cmd_stream: true,
|
98
|
+
**build_opts
|
99
|
+
|
100
|
+
cmd = QB::Docker::CLI.build_cmd path, tag: name.to_s, **build_opts
|
101
|
+
|
102
|
+
logger.info "building...",
|
103
|
+
name: name.to_s,
|
104
|
+
path: path,
|
105
|
+
push: push,
|
106
|
+
_cmd_stream: _cmd_stream,
|
107
|
+
cmd: cmd.prepare
|
108
|
+
|
109
|
+
result = run_cmd! cmd, stream: _cmd_stream
|
110
|
+
|
111
|
+
tags.each do |tag_arg|
|
112
|
+
cmd = QB::Docker::CLI.tag_cmd name, tag_arg
|
113
|
+
tag = cmd.args[1]
|
114
|
+
logger.debug "Tagging #{ name } as #{ tag }",
|
115
|
+
tag_arg: tag_arg
|
116
|
+
|
117
|
+
result = run_cmd cmd, stream: _cmd_stream
|
118
|
+
|
119
|
+
if result.ok?
|
120
|
+
logger.info "Tagged #{ name } as #{ tag }.",
|
121
|
+
cmd: cmd.last_prepared_cmd
|
122
|
+
else
|
123
|
+
logger.error "Failed to tag #{ name } as #{ tag }",
|
124
|
+
tag_arg: tag_arg,
|
125
|
+
cmd: cmd.last_prepared_cmd
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
QB::Docker::CLI.push( name ) if push
|
130
|
+
|
131
|
+
result
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def self.ensure_present! name:,
|
136
|
+
pull: nil,
|
137
|
+
build: nil,
|
138
|
+
force: false,
|
139
|
+
push: false
|
140
|
+
|
141
|
+
name = QB::Docker::Image::Name.from name
|
142
|
+
|
143
|
+
if pull.nil? &&
|
144
|
+
name.tag &&
|
145
|
+
name.tag.version.is_a?( QB::Package::Version::Leveled )
|
146
|
+
pull = !name.tag.version.dev?
|
147
|
+
end
|
148
|
+
|
149
|
+
logger.info "Ensuring image is present...",
|
150
|
+
name: name.to_s,
|
151
|
+
pull: pull,
|
152
|
+
push: push,
|
153
|
+
force: force
|
154
|
+
|
155
|
+
if force
|
156
|
+
logger.info "Forcing build...",
|
157
|
+
name: name.to_s
|
158
|
+
|
159
|
+
build! name: name, **build
|
160
|
+
|
161
|
+
QB::Docker::CLI.push?( name: name ) if push
|
162
|
+
|
163
|
+
return
|
164
|
+
end
|
165
|
+
|
166
|
+
if name.exists?
|
167
|
+
logger.info "Image exists", name: name.to_s
|
168
|
+
return
|
169
|
+
end
|
170
|
+
|
171
|
+
logger.info "Name does NOT exist",
|
172
|
+
name: name.to_s
|
173
|
+
|
174
|
+
if pull
|
175
|
+
logger.info "Attempting to pull...",
|
176
|
+
name: name.to_s
|
177
|
+
|
178
|
+
return if QB::Docker::CLI.pull?( name )
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
logger.info "Resorting to building...",
|
183
|
+
name: name.to_s,
|
184
|
+
path: build[:path]
|
185
|
+
|
186
|
+
build! name: name, **build
|
187
|
+
|
188
|
+
QB::Docker::CLI.push( name: name ) if push
|
189
|
+
|
190
|
+
end # .ensure_present!
|
191
|
+
|
192
|
+
|
193
|
+
# Properties
|
194
|
+
# ======================================================================
|
195
|
+
|
196
|
+
prop :id, type: t.non_empty_str
|
197
|
+
|
198
|
+
# prop :repo, type: QB::Docker::Repo
|
199
|
+
#
|
200
|
+
# prop :tag, type: QB::Docker::Image::Tag
|
201
|
+
|
202
|
+
|
203
|
+
# Instance Methods
|
204
|
+
# ======================================================================
|
205
|
+
|
206
|
+
|
207
|
+
end; end; end # class QB::Docker::Image
|
@@ -0,0 +1,309 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Deps
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
# Project / Package
|
14
|
+
# -----------------------------------------------------------------------
|
15
|
+
|
16
|
+
require_relative './tag'
|
17
|
+
|
18
|
+
|
19
|
+
# Refinements
|
20
|
+
# ========================================================================
|
21
|
+
|
22
|
+
require 'nrser/refinements/types'
|
23
|
+
using NRSER::Types
|
24
|
+
|
25
|
+
|
26
|
+
# Definitions
|
27
|
+
# =======================================================================
|
28
|
+
|
29
|
+
# Image name.
|
30
|
+
#
|
31
|
+
# Input format will be one of:
|
32
|
+
#
|
33
|
+
# 1. name[:tag]
|
34
|
+
# 2. repository/name[:tag]
|
35
|
+
# 3. registry_server:port/name[:tag]
|
36
|
+
#
|
37
|
+
module QB
|
38
|
+
module Docker
|
39
|
+
class Image < QB::Data::Immutable
|
40
|
+
class Name < QB::Data::Immutable
|
41
|
+
|
42
|
+
# Mixins
|
43
|
+
# ========================================================================
|
44
|
+
|
45
|
+
extend ::MethodDecorators
|
46
|
+
|
47
|
+
include NRSER::Log::Mixin
|
48
|
+
|
49
|
+
|
50
|
+
# Class Methods
|
51
|
+
# ======================================================================
|
52
|
+
|
53
|
+
# Load from a {String}.
|
54
|
+
#
|
55
|
+
# @param [String] string
|
56
|
+
# @return [self]
|
57
|
+
#
|
58
|
+
def self.from_s string
|
59
|
+
strings = {}
|
60
|
+
segments = string.split '/'
|
61
|
+
|
62
|
+
if segments[-1].include? ':'
|
63
|
+
rest, _, tag = segments[-1].rpartition ':'
|
64
|
+
strings[:tag] = tag
|
65
|
+
segments[-1] = rest
|
66
|
+
else
|
67
|
+
rest = string
|
68
|
+
end
|
69
|
+
|
70
|
+
case segments.length
|
71
|
+
when 0
|
72
|
+
# Pass - construction will error
|
73
|
+
when 1
|
74
|
+
# Just a name
|
75
|
+
strings[:name] = segments[0]
|
76
|
+
else
|
77
|
+
if segments[0].include? ':'
|
78
|
+
# segments = [s_0, s_1, ... s_n]
|
79
|
+
# => repository = s_0
|
80
|
+
# segments = [s_1, s_2, ... s_n]
|
81
|
+
#
|
82
|
+
# like
|
83
|
+
#
|
84
|
+
# segments = ['docker.beiarea.com:8888', 'beiarea', 'wall']
|
85
|
+
# => registry_server = 'docker.beiarea.com'
|
86
|
+
# port = '8888'
|
87
|
+
# segments = ['beiarea', 'wall']
|
88
|
+
#
|
89
|
+
registry_server, _, port = segments.shift.rpartition ':'
|
90
|
+
strings[:registry_server] = registry_server
|
91
|
+
strings[:port] = port
|
92
|
+
end
|
93
|
+
|
94
|
+
if segments.length > 1
|
95
|
+
# segments = [s_0, s_1, ... s_m]
|
96
|
+
# => repository = s_0
|
97
|
+
# segments = [s_1, s_2, ... s_m]
|
98
|
+
#
|
99
|
+
# like
|
100
|
+
#
|
101
|
+
# segments = ['beiarea', 'wall']
|
102
|
+
# => repository = 'beiarea'
|
103
|
+
# segments = ['wall']
|
104
|
+
#
|
105
|
+
repository = segments.shift
|
106
|
+
strings[:repository] = repository
|
107
|
+
end
|
108
|
+
|
109
|
+
# I think Docker image names *can* have more than just a repo and name
|
110
|
+
# segment, though it's poorly supported from what I recall... though
|
111
|
+
# we will handle it by just re-joining whatever's left into the name.
|
112
|
+
#
|
113
|
+
# segments = [s_0, s_1, ... s_p]
|
114
|
+
# => name = "s_0/s_1/.../s_p"
|
115
|
+
#
|
116
|
+
# like
|
117
|
+
#
|
118
|
+
# segments = ['wall']
|
119
|
+
# => name = 'wall'
|
120
|
+
#
|
121
|
+
# or
|
122
|
+
#
|
123
|
+
# segments = ['www_rails', 'web']
|
124
|
+
# => name = 'www_rails/web'
|
125
|
+
#
|
126
|
+
strings[:name] = segments.join '/'
|
127
|
+
end
|
128
|
+
|
129
|
+
logger.debug "strings", strings
|
130
|
+
|
131
|
+
# Now turn them into value using their prop types
|
132
|
+
values = strings.transform_values_with_keys { |name, string|
|
133
|
+
prop = metadata[name]
|
134
|
+
|
135
|
+
if prop.type.respond_to? :from_s
|
136
|
+
prop.type.from_s string
|
137
|
+
else
|
138
|
+
string
|
139
|
+
end
|
140
|
+
}
|
141
|
+
|
142
|
+
logger.debug "values", values
|
143
|
+
|
144
|
+
# And construct!
|
145
|
+
new source: string, **values
|
146
|
+
end # .from_s
|
147
|
+
|
148
|
+
|
149
|
+
# Get an instance from a source.
|
150
|
+
#
|
151
|
+
# @param [self | String | Hash] source
|
152
|
+
# @return [self]
|
153
|
+
#
|
154
|
+
def self.from source
|
155
|
+
t.match source,
|
156
|
+
self, source,
|
157
|
+
t.str, method( :from_s ),
|
158
|
+
t.hash_, method( :from_data )
|
159
|
+
end # .from
|
160
|
+
|
161
|
+
|
162
|
+
# Queries
|
163
|
+
# --------------------------------------------------------------------------
|
164
|
+
|
165
|
+
# @see QB::Docker::CLI.image_named?
|
166
|
+
#
|
167
|
+
def self.exists? name
|
168
|
+
QB::Docker::CLI.image_named? name
|
169
|
+
end # .exists?
|
170
|
+
|
171
|
+
|
172
|
+
# @see QB::Docker::CLI.image_names
|
173
|
+
#
|
174
|
+
+QB::Util::Decorators::NoPropsInKwds
|
175
|
+
def self.list *args, **opts
|
176
|
+
QB::Docker::CLI.image_names *args, **opts
|
177
|
+
end # .list
|
178
|
+
|
179
|
+
singleton_class.send :alias_method, :all, :list
|
180
|
+
|
181
|
+
|
182
|
+
# Props
|
183
|
+
# ======================================================================
|
184
|
+
|
185
|
+
# @!attribute [r] source
|
186
|
+
# Source string this name was loaded from, if any.
|
187
|
+
#
|
188
|
+
# @return [String?]
|
189
|
+
#
|
190
|
+
prop :source,
|
191
|
+
type: t.non_empty_str?
|
192
|
+
|
193
|
+
|
194
|
+
# @!attribute [r] name
|
195
|
+
# For lack of a better name, the part of the name that's not anything
|
196
|
+
# else. It's also the only required part.
|
197
|
+
#
|
198
|
+
# @return [String]
|
199
|
+
# Can't be empty.
|
200
|
+
#
|
201
|
+
prop :name,
|
202
|
+
type: t.non_empty_str
|
203
|
+
|
204
|
+
|
205
|
+
# @!attribute [r] repository
|
206
|
+
# The repository name, if any.
|
207
|
+
#
|
208
|
+
# @return [String?]
|
209
|
+
# String is non-empty.
|
210
|
+
prop :repository,
|
211
|
+
type: t.non_empty_str?
|
212
|
+
|
213
|
+
|
214
|
+
# @!attribute [r] registry_server
|
215
|
+
# Registry server, if any.
|
216
|
+
#
|
217
|
+
# @return [String?]
|
218
|
+
# String is non-empty.
|
219
|
+
prop :registry_server,
|
220
|
+
type: t.non_empty_str?
|
221
|
+
|
222
|
+
|
223
|
+
# @!attribute [r] port
|
224
|
+
# Registry server port, if any.
|
225
|
+
#
|
226
|
+
# @return [Integer?]
|
227
|
+
# In range [1, 2**16 - 1]
|
228
|
+
prop :port,
|
229
|
+
type: t.port?
|
230
|
+
|
231
|
+
|
232
|
+
prop :tag,
|
233
|
+
type: t.maybe( QB::Docker::Image::Tag )
|
234
|
+
|
235
|
+
|
236
|
+
prop :string,
|
237
|
+
type: t.non_empty_str,
|
238
|
+
source: :to_s
|
239
|
+
|
240
|
+
|
241
|
+
invariant t.attrs( registry_server: t.nil, port: t.nil ) |
|
242
|
+
t.attrs( registry_server: ~t.nil, port: ~t.nil )
|
243
|
+
|
244
|
+
|
245
|
+
# Instance Methods
|
246
|
+
# ======================================================================
|
247
|
+
|
248
|
+
# Does the name exist in the local daemon?
|
249
|
+
#
|
250
|
+
# @see QB::Docker::CLI.image_named?
|
251
|
+
#
|
252
|
+
# @return [Boolean]
|
253
|
+
#
|
254
|
+
def exists?
|
255
|
+
QB::Docker::CLI.image_named? self
|
256
|
+
end # #exist?
|
257
|
+
|
258
|
+
alias_method :exist?, :exists?
|
259
|
+
|
260
|
+
|
261
|
+
# @todo Document dirty? method.
|
262
|
+
#
|
263
|
+
# @param [type] arg_name
|
264
|
+
# @todo Add name param description.
|
265
|
+
#
|
266
|
+
# @return [return_type]
|
267
|
+
# @todo Document return value.
|
268
|
+
#
|
269
|
+
def dirty?
|
270
|
+
!!tag.try( :dirty? )
|
271
|
+
end # #dirty?
|
272
|
+
|
273
|
+
|
274
|
+
def host
|
275
|
+
"#{ registry_server }:#{ port }" if registry_server && port
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
def formatted
|
280
|
+
[
|
281
|
+
host,
|
282
|
+
repository,
|
283
|
+
name,
|
284
|
+
].compact.join( '/' ).thru { |without_tag|
|
285
|
+
if tag
|
286
|
+
"#{ without_tag }:#{ tag }"
|
287
|
+
else
|
288
|
+
without_tag
|
289
|
+
end
|
290
|
+
}
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
def to_s
|
295
|
+
formatted
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
def inspect
|
300
|
+
"#<#{ self.class.safe_name } #{ to_s }>"
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
def pretty_print q
|
305
|
+
q.text inspect
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
end; end; end; end # class QB::Docker::Image::Name
|