qb 0.3.25 → 0.4.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/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
|