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,195 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require 'nrser/props/mutable/stash'
|
11
|
+
|
12
|
+
# Need the experimental {NRSER::Stash} class that lets us intercept hash
|
13
|
+
# writes.
|
14
|
+
require 'nrser/labs/stash'
|
15
|
+
|
16
|
+
|
17
|
+
# Refinements
|
18
|
+
# =======================================================================
|
19
|
+
|
20
|
+
using NRSER::Types
|
21
|
+
|
22
|
+
|
23
|
+
# Definitions
|
24
|
+
# =======================================================================
|
25
|
+
|
26
|
+
|
27
|
+
# Encapsulation of data that an Ansible module responds to Ansible with.
|
28
|
+
#
|
29
|
+
# Ansible calls this a module's "return value".
|
30
|
+
#
|
31
|
+
# @see http://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html
|
32
|
+
#
|
33
|
+
class QB::Ansible::Module::Response < NRSER::Stash
|
34
|
+
|
35
|
+
# Mixins
|
36
|
+
# ========================================================================
|
37
|
+
|
38
|
+
include NRSER::Props::Mutable::Stash
|
39
|
+
|
40
|
+
|
41
|
+
# @!group Props
|
42
|
+
# ==========================================================================
|
43
|
+
|
44
|
+
# "Common" Values
|
45
|
+
# --------------------------------------------------------------------------
|
46
|
+
|
47
|
+
# For those modules that implement backup=no|yes when manipulating files,
|
48
|
+
# a path to the backup file created.
|
49
|
+
#
|
50
|
+
# The file must exist if provided.
|
51
|
+
#
|
52
|
+
prop :backup_file,
|
53
|
+
type: t.file_path?
|
54
|
+
|
55
|
+
|
56
|
+
# A boolean indicating if the task had to make changes.
|
57
|
+
#
|
58
|
+
prop :changed,
|
59
|
+
type: t.bool,
|
60
|
+
default: false
|
61
|
+
|
62
|
+
|
63
|
+
# A boolean that indicates if the task was failed or not.
|
64
|
+
#
|
65
|
+
prop :failed,
|
66
|
+
type: t.bool,
|
67
|
+
default: false
|
68
|
+
|
69
|
+
# Ansible says "Information on how the module was invoked."
|
70
|
+
#
|
71
|
+
# I have no idea what that means and couldn't find anywhere it was being
|
72
|
+
# set in a quick search of their module sources.
|
73
|
+
#
|
74
|
+
prop :invocation,
|
75
|
+
type: t.any
|
76
|
+
|
77
|
+
|
78
|
+
# A string with a generic message relayed to the user.
|
79
|
+
#
|
80
|
+
prop :msg,
|
81
|
+
type: t.str?
|
82
|
+
|
83
|
+
|
84
|
+
# A return (exit) code, if one makes sense, I guess.
|
85
|
+
#
|
86
|
+
# Ansible says:
|
87
|
+
#
|
88
|
+
# > Some modules execute command line utilities or are geared for executing
|
89
|
+
# > commands directly (raw, shell, command, etc), this field contains
|
90
|
+
# > ‘return code’ of these utilities.
|
91
|
+
#
|
92
|
+
prop :rc,
|
93
|
+
type: t.unsigned?
|
94
|
+
|
95
|
+
|
96
|
+
# "Internal Use" (Consumed by Ansible)
|
97
|
+
# --------------------------------------------------------------------------
|
98
|
+
|
99
|
+
# This key should contain a dictionary which will be appended to the facts
|
100
|
+
# assigned to the host.
|
101
|
+
#
|
102
|
+
# These will be directly accessible and don’t require using a registered
|
103
|
+
# variable.
|
104
|
+
#
|
105
|
+
prop :ansible_facts,
|
106
|
+
aliases: [ :facts ],
|
107
|
+
type: t.hash_( keys: t.non_empty_str ),
|
108
|
+
default: -> { HashWithIndifferentAccess.new },
|
109
|
+
from_data: :with_indifferent_access.to_proc
|
110
|
+
|
111
|
+
|
112
|
+
# This key can contain traceback information caused by an exception in a
|
113
|
+
# module. It will only be displayed [to the user] on high verbosity (-vvv).
|
114
|
+
#
|
115
|
+
# Unclear what the value type is, guessing string...
|
116
|
+
#
|
117
|
+
prop :exception,
|
118
|
+
type: t.str?
|
119
|
+
|
120
|
+
|
121
|
+
# @!attribute [rw] warnings
|
122
|
+
# This key contains a list of strings that will be presented to the user.
|
123
|
+
#
|
124
|
+
# @return [Array<String>]
|
125
|
+
# Non-empty string warning messages to return to Ansible.
|
126
|
+
#
|
127
|
+
prop :warnings,
|
128
|
+
type: t.array( t.non_empty_str ),
|
129
|
+
default: -> { [] }
|
130
|
+
|
131
|
+
|
132
|
+
# @!attribute [rw] depreciations
|
133
|
+
# This key contains a list of dictionaries that will be presented to the
|
134
|
+
# user. Keys of the dictionaries are msg and version, values are string,
|
135
|
+
# value for the version key can be an empty string.
|
136
|
+
#
|
137
|
+
# @return [Array<{ msg: String, version: String }>]
|
138
|
+
#
|
139
|
+
prop :depreciations,
|
140
|
+
type: t.array(
|
141
|
+
t.shape( msg: t.non_empty_str, version: t.non_empty_str )
|
142
|
+
),
|
143
|
+
default: ->{ [] }
|
144
|
+
|
145
|
+
|
146
|
+
metadata.freeze
|
147
|
+
|
148
|
+
# @!endgroup Props # *******************************************************
|
149
|
+
|
150
|
+
|
151
|
+
# Constructor
|
152
|
+
# ======================================================================
|
153
|
+
|
154
|
+
# Instantiate a new `QB::Ansible::Module::Response`.
|
155
|
+
def initialize values = {}
|
156
|
+
super()
|
157
|
+
initialize_props values
|
158
|
+
end # #initialize
|
159
|
+
|
160
|
+
|
161
|
+
# Instance Methods
|
162
|
+
# ======================================================================
|
163
|
+
|
164
|
+
# Uses {Symbol} keys, and they can not be empty. Will convert non-empty
|
165
|
+
# strings to their symbols.
|
166
|
+
#
|
167
|
+
# @param [Symbol | String] key
|
168
|
+
# @return [Symbol]
|
169
|
+
#
|
170
|
+
def convert_key key
|
171
|
+
t.match key,
|
172
|
+
t.non_empty_str, :to_sym.to_proc,
|
173
|
+
t.non_empty_sym, key
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
# Create a new response to represent a failure, copying the stuff that makes
|
178
|
+
# sense to keep from this one.
|
179
|
+
#
|
180
|
+
# @param [type] arg_name
|
181
|
+
# @todo Add name param description.
|
182
|
+
#
|
183
|
+
# @return [return_type]
|
184
|
+
# @todo Document return value.
|
185
|
+
#
|
186
|
+
def to_failure msg:, warnings: [], depreciations: [], **values
|
187
|
+
self.class.new \
|
188
|
+
failed: true,
|
189
|
+
msg: msg,
|
190
|
+
warnings: (self.warnings + warnings),
|
191
|
+
depreciations: (self.depreciations + depreciations)
|
192
|
+
end # #to_failure
|
193
|
+
|
194
|
+
|
195
|
+
end # class QB::Ansible::Module::Response
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module QB
|
3
|
+
module Ansible
|
4
|
+
# QB's built-in Ansible modules (that are written in Ruby).
|
5
|
+
#
|
6
|
+
# Putting them here seems better than in `//library` 'cause we want to support
|
7
|
+
# composing modules, something Ansible either totally doesn't support or at
|
8
|
+
# least doesn't advertise or encourage. This means we want our Ruby modules
|
9
|
+
# in the load path, and here seemed like a decent spot.
|
10
|
+
#
|
11
|
+
# None of these are required with `require 'qb'` - they need to be required
|
12
|
+
# individually.
|
13
|
+
#
|
14
|
+
# I created a "super module" to run them without needed to create executables
|
15
|
+
# for each one:
|
16
|
+
#
|
17
|
+
# - name: >-
|
18
|
+
# Run me some QB module...
|
19
|
+
#
|
20
|
+
# qb.module:
|
21
|
+
#
|
22
|
+
# # The module's relative path from `//lib/qb/ansible/modules`
|
23
|
+
# #
|
24
|
+
# # You can also use "relative" class name like `Docker::Image` or
|
25
|
+
# # "absolute" like `::QB::Some::Other::Module` to reach classes
|
26
|
+
# # *not* in `//lib/qb/ansible/modules`
|
27
|
+
# #
|
28
|
+
# name: docker/image
|
29
|
+
#
|
30
|
+
# # The arguments for the module
|
31
|
+
# args:
|
32
|
+
# path: /path/to/image/source
|
33
|
+
# # ...
|
34
|
+
#
|
35
|
+
# Check out `//library/qb.module.rb` for the source.
|
36
|
+
#
|
37
|
+
# This will also let us do other "super-level" stuff like provide common
|
38
|
+
# result-value-to-fact binding or whatever (just an idea).
|
39
|
+
#
|
40
|
+
#
|
41
|
+
#
|
42
|
+
module Modules; end; end; end
|
@@ -0,0 +1,273 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
|
5
|
+
# Requirements
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
# Project / Package
|
9
|
+
# ------------------------------------------------------------------------
|
10
|
+
|
11
|
+
require 'qb'
|
12
|
+
require 'qb/docker/image'
|
13
|
+
|
14
|
+
|
15
|
+
# Namespace
|
16
|
+
# ========================================================================
|
17
|
+
|
18
|
+
module QB
|
19
|
+
module Ansible
|
20
|
+
module Modules
|
21
|
+
module Docker
|
22
|
+
|
23
|
+
|
24
|
+
# Definitions
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
# Build a Docker image if needed. Features to deal with version-tagging.
|
28
|
+
#
|
29
|
+
class Image < QB::Ansible::Module
|
30
|
+
|
31
|
+
# Arguments
|
32
|
+
# ========================================================================
|
33
|
+
|
34
|
+
arg :name,
|
35
|
+
type: QB::Docker::Image::Name
|
36
|
+
|
37
|
+
arg :path,
|
38
|
+
type: t.dir_path
|
39
|
+
# FIXME ( from_s: ->( s ) { Pathname.new( s ).expand_path } )
|
40
|
+
|
41
|
+
arg :from_image,
|
42
|
+
type: QB::Docker::Image::Name
|
43
|
+
|
44
|
+
arg :fact_name,
|
45
|
+
type: t.non_empty_str?
|
46
|
+
|
47
|
+
arg :build_arg,
|
48
|
+
type: t.hash_,
|
49
|
+
aliases: [ :build_args, :buildargs ],
|
50
|
+
reader: {
|
51
|
+
build_args: false,
|
52
|
+
buildargs: false,
|
53
|
+
},
|
54
|
+
default: ->{ {} }
|
55
|
+
|
56
|
+
arg :include_from_image_build,
|
57
|
+
type: t.bool,
|
58
|
+
default: true
|
59
|
+
|
60
|
+
# @!attribute [r] now
|
61
|
+
# The time to use as now. Defaults to get the current time, but here so
|
62
|
+
# that it can be provided externally so if you're doing a bunch of work
|
63
|
+
# you can make all the timestamps sync up. Pls don't abuse.
|
64
|
+
#
|
65
|
+
# @return [Time]
|
66
|
+
# UTC {Time} to use as now.
|
67
|
+
#
|
68
|
+
arg :now,
|
69
|
+
type: Time,
|
70
|
+
default: ->{ Time.now.utc }
|
71
|
+
|
72
|
+
|
73
|
+
# Helpers
|
74
|
+
# ========================================================================
|
75
|
+
|
76
|
+
# 'openresty/openresty:1.11.2.4-xenial'
|
77
|
+
# => repository: 'openresty'
|
78
|
+
# name: 'openresty'
|
79
|
+
# tag: {
|
80
|
+
# major: 1,
|
81
|
+
# minor: 11,
|
82
|
+
# patch: 2,
|
83
|
+
# revision: [4],
|
84
|
+
# prerelease: ['xenial'],
|
85
|
+
# }
|
86
|
+
# => ['openresty--openresty', 1, 11, 2, 4, 'xenial']
|
87
|
+
#
|
88
|
+
# which eventually becomes the Docker tag
|
89
|
+
#
|
90
|
+
# <semver>_openresty.openresty.1.11.2.4.xenial.<build_info?>
|
91
|
+
#
|
92
|
+
def build_segments_for_from_image
|
93
|
+
return [] unless include_from_image_build
|
94
|
+
|
95
|
+
[
|
96
|
+
[
|
97
|
+
(from_image.repository == 'beiarea' ? nil : from_image.repository),
|
98
|
+
from_image.name,
|
99
|
+
].
|
100
|
+
compact.
|
101
|
+
map { |name| name.gsub( '_', '-' ) }.
|
102
|
+
join( '-' ),
|
103
|
+
*from_image.tag.version.to_a.flatten,
|
104
|
+
]
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def git
|
109
|
+
lazy_var :@git do
|
110
|
+
QB::Repo::Git.from_path path
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def source_base_version
|
116
|
+
lazy_var :@source_base_version do
|
117
|
+
QB::Package::Version.from_string (path.to_pn / 'VERSION').read
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def source_dev_version
|
123
|
+
lazy_var :@source_dev_version do
|
124
|
+
source_base_version.build_version \
|
125
|
+
branch: git.branch,
|
126
|
+
ref: git.head_short,
|
127
|
+
dirty: !git.clean?
|
128
|
+
# time: now
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def source_version
|
134
|
+
lazy_var :@source_version do
|
135
|
+
if source_base_version.dev?
|
136
|
+
source_dev_version
|
137
|
+
else
|
138
|
+
source_non_dev_version
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def source_non_dev_version
|
145
|
+
tag = "v#{ source_base_version.semver }"
|
146
|
+
|
147
|
+
# We check...
|
148
|
+
#
|
149
|
+
# 1. Repo is clean
|
150
|
+
unless git.clean?
|
151
|
+
raise "Can't build #{ source_base_version.level } version from " \
|
152
|
+
"dirty repo"
|
153
|
+
end
|
154
|
+
|
155
|
+
# 2. Tag exists
|
156
|
+
unless git.tags.include? tag
|
157
|
+
raise "Tag #{ tag } not found"
|
158
|
+
end
|
159
|
+
|
160
|
+
# 3. Tag points to current commit
|
161
|
+
tag_commit = Cmds.
|
162
|
+
new( "git rev-list -n 1 %s", chdir: path ).
|
163
|
+
out!( tag ).
|
164
|
+
chomp
|
165
|
+
|
166
|
+
unless tag_commit == git.head
|
167
|
+
raise "Repo is not at tag #{ tag } commit #{ tag_commit }"
|
168
|
+
end
|
169
|
+
|
170
|
+
# Ok, we just use the version in the file!
|
171
|
+
source_base_version
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
def image_version
|
176
|
+
lazy_var :@image_version do
|
177
|
+
source_version.merge \
|
178
|
+
build: [
|
179
|
+
*build_segments_for_from_image,
|
180
|
+
*source_version.build
|
181
|
+
]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
def image_name
|
187
|
+
lazy_var :@image_name do
|
188
|
+
name.merge \
|
189
|
+
source: nil, # NEED this!
|
190
|
+
tag: QB::Docker::Image::Tag.from_s(
|
191
|
+
image_version.docker_tag
|
192
|
+
)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
def repo_clean?
|
198
|
+
lazy_var :@repo_clean do
|
199
|
+
git.clean?
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
def repo_dirty?
|
205
|
+
!repo_clean?
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def force?
|
210
|
+
source_base_version.dev? && repo_dirty?
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
# Execution
|
215
|
+
# ==========================================================================
|
216
|
+
|
217
|
+
# Entry point for the module. invoked by {#run!}.
|
218
|
+
#
|
219
|
+
# @return [nil | {Symbol => #to_json}]
|
220
|
+
# when returning:
|
221
|
+
#
|
222
|
+
# - `nil`: module will successfully exit with no additional changes.
|
223
|
+
#
|
224
|
+
# - `{Symbol => #to_json}`: Hash will be merged over @facts that
|
225
|
+
# are returned by the module to be set in the Ansible runtime and
|
226
|
+
# the module will exit successfully.
|
227
|
+
#
|
228
|
+
def main
|
229
|
+
logger.info \
|
230
|
+
"Starting `_image`...",
|
231
|
+
path: path,
|
232
|
+
from_image: from_image.to_s,
|
233
|
+
build_arg: build_arg,
|
234
|
+
fact_name: fact_name
|
235
|
+
|
236
|
+
|
237
|
+
QB::Docker::Image.ensure_present! \
|
238
|
+
name: image_name,
|
239
|
+
pull: !image_version.dev?,
|
240
|
+
build: {
|
241
|
+
path: path,
|
242
|
+
build_arg: {
|
243
|
+
from_image: from_image.string,
|
244
|
+
image_version: image_version.semver,
|
245
|
+
**build_arg.to_options,
|
246
|
+
},
|
247
|
+
},
|
248
|
+
# Don't push dev images
|
249
|
+
push: !image_version.dev?,
|
250
|
+
force: force?
|
251
|
+
|
252
|
+
response[:image] = {
|
253
|
+
name: image_name,
|
254
|
+
version: image_version,
|
255
|
+
}
|
256
|
+
|
257
|
+
if fact_name
|
258
|
+
response.facts[fact_name] = response[:image]
|
259
|
+
end
|
260
|
+
|
261
|
+
return nil
|
262
|
+
end # #main
|
263
|
+
|
264
|
+
end # class Image
|
265
|
+
|
266
|
+
|
267
|
+
# /Namespace
|
268
|
+
# ========================================================================
|
269
|
+
|
270
|
+
end # module Docker
|
271
|
+
end # module Modules
|
272
|
+
end # module Ansible
|
273
|
+
end # module QB
|