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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/ansible.cfg +10 -1
  4. data/exe/.qb_interop_receive +3 -10
  5. data/exe/qb +8 -2
  6. data/lib/python/qb/__init__.py +6 -0
  7. data/{roles/qb/ruby/rspec/setup/tasks/persistence.yml → lib/python/qb/ansible/__init__.py} +0 -0
  8. data/lib/python/qb/ansible/modules/__init__.py +0 -0
  9. data/lib/python/qb/ansible/modules/docker/__init__.py +0 -0
  10. data/lib/python/qb/ansible/modules/docker/client.py +177 -0
  11. data/lib/python/qb/ansible/modules/docker/image_manager.py +754 -0
  12. data/lib/python/qb/ipc/__init__.py +0 -0
  13. data/lib/python/qb/ipc/stdio/__init__.py +99 -0
  14. data/lib/python/qb/ipc/stdio/logging.py +151 -0
  15. data/lib/qb.rb +3 -3
  16. data/lib/qb/ansible/cmds/playbook.rb +5 -14
  17. data/lib/qb/ansible/env.rb +36 -6
  18. data/lib/qb/ansible/module.rb +396 -152
  19. data/lib/qb/ansible/module/response.rb +195 -0
  20. data/lib/qb/ansible/modules.rb +42 -0
  21. data/lib/qb/ansible/modules/docker/image.rb +273 -0
  22. data/lib/qb/cli.rb +5 -18
  23. data/lib/qb/cli/run.rb +2 -2
  24. data/lib/qb/data.rb +22 -0
  25. data/lib/qb/data/immutable.rb +39 -0
  26. data/lib/qb/docker.rb +2 -0
  27. data/lib/qb/docker/cli.rb +430 -0
  28. data/lib/qb/docker/image.rb +207 -0
  29. data/lib/qb/docker/image/name.rb +309 -0
  30. data/lib/qb/docker/image/tag.rb +113 -0
  31. data/lib/qb/docker/repo.rb +0 -0
  32. data/lib/qb/errors.rb +17 -3
  33. data/lib/qb/execution.rb +83 -0
  34. data/lib/qb/ipc.rb +48 -0
  35. data/lib/qb/ipc/stdio.rb +32 -0
  36. data/lib/qb/ipc/stdio/client.rb +267 -0
  37. data/lib/qb/ipc/stdio/server.rb +229 -0
  38. data/lib/qb/ipc/stdio/server/in_service.rb +18 -0
  39. data/lib/qb/ipc/stdio/server/log_service.rb +168 -0
  40. data/lib/qb/ipc/stdio/server/out_service.rb +20 -0
  41. data/lib/qb/ipc/stdio/server/service.rb +229 -0
  42. data/lib/qb/options.rb +360 -502
  43. data/lib/qb/options/option.rb +293 -115
  44. data/lib/qb/options/option/option_parser_concern.rb +228 -0
  45. data/lib/qb/options/types.rb +73 -0
  46. data/lib/qb/package.rb +0 -1
  47. data/lib/qb/package/version.rb +179 -58
  48. data/lib/qb/package/version/from.rb +192 -51
  49. data/lib/qb/package/version/leveled.rb +1 -1
  50. data/lib/qb/path.rb +3 -2
  51. data/lib/qb/repo/git.rb +9 -85
  52. data/lib/qb/role/default_dir.rb +2 -2
  53. data/lib/qb/role/errors.rb +2 -8
  54. data/lib/qb/util.rb +1 -2
  55. data/lib/qb/util/bundler.rb +73 -43
  56. data/lib/qb/util/decorators.rb +99 -0
  57. data/lib/qb/util/interop.rb +7 -8
  58. data/lib/qb/util/resource.rb +12 -13
  59. data/lib/qb/version.rb +10 -0
  60. data/library/path_facts +5 -10
  61. data/library/qb.module.rb +105 -0
  62. data/library/stream +6 -26
  63. data/load/ansible/module/autorun.rb +25 -0
  64. data/load/ansible/module/script.rb +123 -0
  65. data/load/rebundle.rb +39 -0
  66. data/plugins/filter/dict_filters.py +56 -0
  67. data/plugins/{filter_plugins/path_plugins.py → filter/path_filters.py} +0 -0
  68. data/plugins/{filter_plugins/ruby_interop_plugins.py → filter/ruby_interop_filters.py} +1 -17
  69. data/plugins/{filter_plugins/string_plugins.py → filter/string_filters.py} +1 -20
  70. data/plugins/{filter_plugins/version_plugins.py → filter/version_filters.py} +3 -18
  71. data/plugins/{lookup_plugins/every.py → lookup/every_lookups.py} +0 -0
  72. data/plugins/{lookup_plugins/resolve.py → lookup/resolve_lookups.py} +0 -0
  73. data/plugins/{lookup_plugins/version.py → lookup/version_lookups.py} +0 -16
  74. data/plugins/test/dict_tests.py +36 -0
  75. data/plugins/test/string_tests.py +36 -0
  76. data/qb.gemspec +7 -3
  77. data/roles/nrser.rb/library/set_fact_with_ruby.rb +3 -9
  78. data/roles/nrser.state_mate/library/state +3 -17
  79. data/roles/qb/call/meta/qb.yml +1 -1
  80. data/roles/qb/dev/ref/repo/git/meta/qb.yml +1 -1
  81. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/defaults/main.yml +1 -1
  82. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/main.yml +3 -2
  83. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/qb.yml +12 -7
  84. data/roles/qb/docker/mac/kubernetes/tasks/main.yml +45 -0
  85. data/roles/qb/git/check/clean/meta/qb.yml +1 -1
  86. data/roles/qb/git/ignore/meta/qb +10 -3
  87. data/roles/qb/git/submodule/update/library/git_submodule_update +17 -27
  88. data/roles/qb/github/pages/setup/meta/qb.yml +1 -1
  89. data/roles/qb/labs/atom/apm/meta/qb.yml +1 -1
  90. data/roles/qb/osx/git/change_case/meta/qb.yml +1 -1
  91. data/roles/qb/osx/notif/meta/qb.yml +1 -1
  92. data/roles/qb/pkg/bump/library/bump +4 -16
  93. data/roles/qb/role/qb/defaults/main.yml +2 -0
  94. data/roles/qb/role/qb/meta/qb.yml +10 -5
  95. data/roles/qb/role/qb/templates/qb.yml.j2 +7 -2
  96. data/roles/qb/role/templates/library/module.rb.j2 +12 -23
  97. data/roles/qb/role/templates/meta/main.yml.j2 +14 -1
  98. data/roles/qb/ruby/bundler/meta/qb.yml +1 -1
  99. data/roles/qb/ruby/dependency/meta/qb.yml +1 -1
  100. data/roles/qb/ruby/gem/bin_stubs/meta/qb.yml +1 -1
  101. data/roles/qb/ruby/gem/bin_stubs/templates/console +8 -2
  102. data/roles/qb/ruby/gem/build/meta/qb.yml +1 -1
  103. data/roles/qb/ruby/gem/new/meta/qb.yml +1 -1
  104. data/roles/qb/ruby/nrser/rspex/generate/meta/qb.yml +5 -5
  105. data/roles/qb/ruby/nrser/rspex/issue/meta/qb.yml +1 -1
  106. data/roles/qb/ruby/yard/clean/meta/qb.yml +1 -1
  107. data/roles/qb/ruby/yard/config/library/yard.get_output_dir +5 -15
  108. data/roles/qb/ruby/yard/config/meta/qb.yml +1 -1
  109. data/roles/qb/ruby/yard/setup/meta/qb.yml +1 -1
  110. metadata +71 -22
  111. data/lib/qb/ansible_module.rb +0 -5
  112. data/lib/qb/util/stdio.rb +0 -187
  113. data/roles/qb/ruby/rspec/setup/tasks/main.yml +0 -4
@@ -6,22 +6,6 @@ import sys
6
6
 
7
7
  from ansible.errors import AnsibleError
8
8
 
9
-
10
- HERE = os.path.dirname(os.path.realpath(__file__))
11
-
12
- PROJECT_ROOT = os.path.realpath(
13
- os.path.join(
14
- HERE, # //plugins/filter_plugins
15
- '..', # //plugins
16
- '..', # //
17
- )
18
- )
19
-
20
- LIB_PYTHON_DIR = os.path.join( PROJECT_ROOT, 'lib', 'python' )
21
-
22
- if not (LIB_PYTHON_DIR in sys.path):
23
- sys.path.insert(0, LIB_PYTHON_DIR)
24
-
25
9
  import qb.interop
26
10
 
27
11
 
@@ -43,4 +27,4 @@ class FilterModule( object ):
43
27
  if __name__ == '__main__':
44
28
  import doctest
45
29
  doctest.testmod()
46
-
30
+
@@ -30,25 +30,6 @@ import os
30
30
 
31
31
  from ansible.errors import AnsibleError
32
32
 
33
-
34
- # Project Imports Setup
35
- # ----------------------------------------------------------------------------
36
-
37
- PROJECT_ROOT = os.path.realpath(
38
- os.path.join(
39
- os.path.dirname(os.path.realpath(__file__)), # //plugins/filter_plugins
40
- '..', # //plugins
41
- '..', # //
42
- )
43
- )
44
-
45
- LIB_PYTHON_DIR = os.path.join( PROJECT_ROOT, 'lib', 'python' )
46
-
47
- if not (LIB_PYTHON_DIR in sys.path):
48
- sys.path.insert(0, LIB_PYTHON_DIR)
49
-
50
- # Now we can import from `//lib/python`...
51
-
52
33
  import qb.strings
53
34
 
54
35
 
@@ -116,4 +97,4 @@ class FilterModule(object):
116
97
  if __name__ == '__main__':
117
98
  import doctest
118
99
  doctest.testmod()
119
-
100
+
@@ -8,27 +8,12 @@ import sys
8
8
 
9
9
  from ansible.errors import AnsibleError
10
10
 
11
-
12
- HERE = os.path.dirname(os.path.realpath(__file__))
13
-
14
- PROJECT_ROOT = os.path.realpath(
15
- os.path.join(
16
- HERE, # //plugins/filter_plugins
17
- '..', # //plugins
18
- '..', # //
19
- )
20
- )
21
-
22
- LIB_PYTHON_DIR = os.path.join( PROJECT_ROOT, 'lib', 'python' )
23
-
24
- if not (LIB_PYTHON_DIR in sys.path):
25
- sys.path.insert(0, LIB_PYTHON_DIR)
26
-
11
+ import qb
27
12
  import qb.interop
28
13
 
29
14
 
30
15
  def get_semver_path():
31
- bin_path = os.path.join(PROJECT_ROOT, 'node_modules', 'semver', 'bin', 'semver')
16
+ bin_path = os.path.join(qb.ROOT, 'node_modules', 'semver', 'bin', 'semver')
32
17
 
33
18
  if not os.path.isfile(bin_path):
34
19
  raise Exception("can't find semver at %s" % bin_path)
@@ -93,7 +78,7 @@ def semver_parse(version):
93
78
 
94
79
  out = subprocess.check_output(
95
80
  cmd,
96
- cwd = PROJECT_ROOT
81
+ cwd = qb.ROOT
97
82
  )
98
83
 
99
84
  version = json.loads(out)
@@ -14,22 +14,6 @@ except ImportError:
14
14
  from ansible.utils.display import Display
15
15
  display = Display()
16
16
 
17
-
18
- HERE = os.path.dirname(os.path.realpath(__file__))
19
-
20
- PROJECT_ROOT = os.path.realpath(
21
- os.path.join(
22
- HERE, # //plugins/filter_plugins
23
- '..', # //plugins
24
- '..', # //
25
- )
26
- )
27
-
28
- LIB_PYTHON_DIR = os.path.join( PROJECT_ROOT, 'lib', 'python' )
29
-
30
- if not (LIB_PYTHON_DIR in sys.path):
31
- sys.path.insert(0, LIB_PYTHON_DIR)
32
-
33
17
  import qb.interop
34
18
 
35
19
 
@@ -0,0 +1,36 @@
1
+ # Imports
2
+ # ============================================================================
3
+
4
+ from __future__ import (absolute_import, division, print_function)
5
+ __metaclass__ = type
6
+
7
+ import sys
8
+ import re
9
+ import os
10
+
11
+ from ansible.errors import AnsibleError
12
+
13
+ def key_prefix(key_and_value, prefix):
14
+ '''
15
+
16
+ >>> key_prefix(('key', 'value'), 'k')
17
+ True
18
+ '''
19
+
20
+ return key_and_value[0].startswith(prefix)
21
+
22
+
23
+ class TestModule(object):
24
+ '''Some dict filters'''
25
+
26
+ def tests(self):
27
+ return {
28
+ 'key_prefix': key_prefix,
29
+ }
30
+
31
+
32
+ # testing - call camel_case on first cli arg and print result
33
+ if __name__ == '__main__':
34
+ import doctest
35
+ doctest.testmod()
36
+
@@ -0,0 +1,36 @@
1
+ # Imports
2
+ # ============================================================================
3
+
4
+ from __future__ import (absolute_import, division, print_function)
5
+ __metaclass__ = type
6
+
7
+ import sys
8
+ import re
9
+ import os
10
+
11
+ from ansible.errors import AnsibleError
12
+
13
+ def startswith(string, prefix):
14
+ '''
15
+ >>> startswith('bigfoot', 'big')
16
+ True
17
+ '''
18
+
19
+ return string.startswith( prefix )
20
+
21
+
22
+ class TestModule(object):
23
+ '''Some string filters'''
24
+
25
+ def tests(self):
26
+ return {
27
+ 'startswith': startswith,
28
+ 'startwith': startswith,
29
+ }
30
+
31
+
32
+ # testing - call camel_case on first cli arg and print result
33
+ if __name__ == '__main__':
34
+ import doctest
35
+ doctest.testmod()
36
+
data/qb.gemspec CHANGED
@@ -195,13 +195,13 @@ Gem::Specification.new do |spec|
195
195
  # ----------------------------------------------------------------------------
196
196
 
197
197
  # My guns
198
- spec.add_dependency "nrser", '~> 0.2.0'
198
+ spec.add_dependency 'nrser', '~> 0.3.3'
199
199
 
200
200
  # My favorite wrapper
201
- spec.add_dependency "cmds", '~> 0.2.10'
201
+ spec.add_dependency "cmds", '~> 0.2.11'
202
202
 
203
203
  # My gem to help manage system state
204
- spec.add_dependency "state_mate", '~> 0.1.3'
204
+ spec.add_dependency "state_mate", '~> 0.1.4'
205
205
 
206
206
  # Used to parse `ansible.cfg` files
207
207
  spec.add_dependency 'parseconfig', '~> 1.0', '>= 1.0.8'
@@ -218,6 +218,10 @@ Gem::Specification.new do |spec|
218
218
  # Ruby lib wrapping `git` binary system calls for use in {QB::Repo::Git}
219
219
  spec.add_dependency 'git', '~> 1.3'
220
220
 
221
+ # Trying out a method decoration gem, aimed to be like Python (which I did
222
+ # really like, once you got past the confusion of it)
223
+ spec.add_dependency 'method_decorators', '~> 0.9.6'
224
+
221
225
 
222
226
  # Development-Only Extra Metadata
223
227
  # ============================================================================
@@ -6,15 +6,9 @@
6
6
  # WANT_JSON
7
7
  # ^ tell Ansible to provide args as JSON encoded file.
8
8
 
9
- # init bundler in dev env
10
- if ENV['QB_DEV_ENV']
11
- ENV.each {|k, v|
12
- if k.start_with? 'QB_DEV_ENV_'
13
- ENV[k.sub('QB_DEV_ENV_', '')] = v
14
- end
15
- }
16
- require 'bundler/setup'
17
- end
9
+ # Reinstate Bundler ENV vars if they have been moved
10
+ load ENV['QB_REBUNDLE_PATH'] if ENV['QB_REBUNDLE_PATH']
11
+
18
12
 
19
13
  # stdlib
20
14
  require 'json'
@@ -1,23 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
  # WANT_JSON
3
3
 
4
- # ugh... we need to clear the bundler env vars before running
5
- # `ansible-playbook` because they break the `git` ansible modules, so we
6
- # don't have the bundler env vars here when we're in dev.
7
- #
8
- # what we do is have exe/qb copy all the bundler env vars to
9
- # `QB_DEV_ENV_<NAME` ones around the env sanitization, along with adding
10
- # `QB_DEV_ENV=true`. then we pick those up here and restore them.
11
- #
12
- if ENV['QB_DEV_ENV']
13
- ENV.each {|k, v|
14
- if k.start_with? 'QB_DEV_ENV_'
15
- ENV[k.sub('QB_DEV_ENV_', '')] = v
16
- end
17
- }
18
-
19
- require 'bundler/setup'
20
- end
4
+ # Reinstate Bundler ENV vars if they have been moved
5
+ load ENV['QB_REBUNDLE_PATH'] if ENV['QB_REBUNDLE_PATH']
6
+
21
7
 
22
8
  require 'pp'
23
9
  require 'json'
@@ -11,7 +11,7 @@ description: null
11
11
  # generalize in the future.
12
12
  requirements:
13
13
  gems:
14
- qb: ~> 0.3.0
14
+ qb: '>= 0.3.0'
15
15
 
16
16
  # prefix for role variables
17
17
  var_prefix: call
@@ -11,7 +11,7 @@ description: null
11
11
  # generalize in the future.
12
12
  requirements:
13
13
  gems:
14
- qb: ~> 0.3.0
14
+ qb: '>= 0.3.0'
15
15
 
16
16
  # prefix for role variables
17
17
  var_prefix: false
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  ##############################################################################
3
- # Variable defaults for `qb/ruby/rspec/setup` role
3
+ # Variable defaults for `qb/docker/mac/kubernetes` role
4
4
  #
5
5
  # @see http://docs.ansible.com/ansible/latest/playbooks_reuse_roles.html#role-default-variables
6
6
  #
@@ -1,9 +1,10 @@
1
1
  ---
2
2
  ##############################################################################
3
- # Ansible metadata for `qb/ruby/rspec/setup` role
3
+ # Ansible metadata for `qb/docker/mac/kubernetes` role
4
4
  ##############################################################################
5
5
 
6
- allow_duplicates: no
6
+ allow_duplicates: yes
7
7
 
8
8
  dependencies: []
9
9
  # - role: role-name
10
+
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  ##############################################################################
3
- # QB metadata for `qb/ruby/rspec/setup` role.
3
+ # QB metadata for `qb/docker/mac/kubernetes` role.
4
4
  #
5
5
  # QB settings for this role.
6
6
  #
@@ -10,21 +10,26 @@
10
10
 
11
11
  # Shown in help output, etc.
12
12
  description: >-
13
- TODO describe qb/ruby/rspec/setup role
13
+ Setup steps for local dev with Kubernetes on Docker for Mac
14
14
 
15
15
  # Gemspec-style requirements. Right now only `.gems.qb` is used.
16
16
  requirements:
17
17
  gems:
18
- qb: ~> 0.3.0
18
+ # Role options taking advantage of the {NRSER::Types} system require
19
+ # QB 0.4.
20
+ #
21
+ # TODO Change this to `>= 0.4.0` when 0.4.0 is released.
22
+ #
23
+ qb: '>= 0.4.0.dev'
19
24
 
20
25
  # Prefix for role variables
21
- var_prefix: setup
26
+ var_prefix: kubernetes
22
27
 
23
28
  # How to get a default for `DIRECTORY` arg if not provided by user.
24
29
  #
25
30
  # @see http://www.rubydoc.info/gems/qb/file/doc/qb_roles/metadata/default_dir.md
26
31
  #
27
- default_dir: null # means use *must* provide `DIRECTORY` arg
32
+ default_dir: false # means use *must* provide `DIRECTORY` arg
28
33
 
29
34
  # If `true`, QB will ensure `DIRECTORY` exists before starting the play.
30
35
  mkdir: false
@@ -33,13 +38,13 @@ mkdir: false
33
38
  default_user: null
34
39
 
35
40
  # Save options in `.qb-options.yml` files
36
- save_options: true
41
+ save_options: false
37
42
 
38
43
  # Options to pass to `ansible-playbook`
39
44
  ansible_options: {}
40
45
 
41
46
  # Role CLI options that become Ansible vars
42
- options: []
47
+ options:
43
48
  # - name: example
44
49
  # description: an example of a variable.
45
50
  # required: false
@@ -0,0 +1,45 @@
1
+ ---
2
+ ##############################################################################
3
+ # Main tasks for `qb/docker/mac/kubernetes` role
4
+ ##############################################################################
5
+
6
+ - name: |-
7
+ Use the `docker-for-desktop` kubectl context
8
+ command: >-
9
+ kubectl config use-context docker-for-desktop
10
+
11
+
12
+ - name: |-
13
+ Install the Kubernetes dashboard
14
+
15
+ https://rominirani.com/tutorial-getting-started-with-kubernetes-with-docker-on-mac-7f58467203fd
16
+
17
+ command: >-
18
+ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
19
+
20
+
21
+ - name: |-
22
+ Tap `nrser/versions` in Homebrew to get `kubernetes-helm@2.8.2`
23
+
24
+ 2.9 is busted: https://github.com/kubernetes/helm/issues/2520
25
+
26
+ homebrew_tap:
27
+ name: nrser/versions
28
+
29
+
30
+ - name: |-
31
+ Make sure `kubernetes-helm` is not linked in Homebrew
32
+ homebrew:
33
+ name: kubernetes-helm
34
+ state: unlinked
35
+
36
+
37
+ - name: |-
38
+ Install `kubernetes-helm@2.8.2`
39
+ homebrew:
40
+ name: kubernetes-helm@2.8.2
41
+
42
+
43
+ - name: |-
44
+ Init Helm
45
+ command: helm init
@@ -15,7 +15,7 @@ description: >-
15
15
  # Gemspec-style requirements. Right now only `.gems.qb` is used.
16
16
  requirements:
17
17
  gems:
18
- qb: ~> 0.3.0
18
+ qb: '>= 0.3.0'
19
19
 
20
20
  # Prefix for role variables
21
21
  var_prefix: git_check_clean
@@ -12,13 +12,20 @@ names = Dir.chdir(GITIGNORE_DIR) do
12
12
  end
13
13
 
14
14
  puts JSON.pretty_generate({
15
+ requirements: {
16
+ gems: {
17
+ # The `type: {in: ...}` syntax for the `name` option requires QB 0.4
18
+ qb: '>= 0.4.0.dev',
19
+ }
20
+ },
21
+
15
22
  save_options: false,
16
23
 
17
24
  default_dir: {
18
25
  find_up: '.gitignore',
19
26
  },
20
27
 
21
- # TODO added this to preserve prefix from when role was named
28
+ # TODO added this to preserve prefix from when role was named
22
29
  # `qb.gitignore`, might want to change once we sort all that out.
23
30
  #
24
31
  var_prefix: 'gitignore',
@@ -29,9 +36,9 @@ puts JSON.pretty_generate({
29
36
  description: "name of gitignore.",
30
37
  required: true,
31
38
  type: {
32
- one_of: names,
39
+ in: names,
33
40
  },
34
41
  short: 'n',
35
42
  },
36
43
  ],
37
- })
44
+ })