opswalrus 1.0.12 → 1.0.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9c838dbf7a64b90664fa94e0b6579508e0967d20a2fa8d8779616fa36cf9b8f
4
- data.tar.gz: 9787c55859ab6ed5f5ceb50803c72df06f9d021e25dcbe7dc917db4f2f30b2ab
3
+ metadata.gz: 1199faea66fca54073c2446271ef2c31a8e78e6dd55e7e9de5173baae5da7ac4
4
+ data.tar.gz: 1bbe73114e2cf1449ad296245d4cf53a2c2f8c523a1652f0ce1776bf742e4438
5
5
  SHA512:
6
- metadata.gz: 644d62c00d36280d5be184f8408c0fc8d5da05d02bae7207b6899d819c98c3f6456be34bb50db1ebfd4012419e6710e193d278c6065bdf2a5b5cc6025b291606
7
- data.tar.gz: a0a2f5663a4bc748feba02bf4609de61347a8ef5519420ba578dfade18c5fdb877f9aada5332bc705c3714db3284b0e137844fa43a56718c3a99d23ceda8b613
6
+ metadata.gz: d4e9a452262cf8a3a82c967bfc5dc9e8b39f87f80b42fb9b641fa764811e2735a78b307cc0c2751c6c185c8223561c0d41b5913b7c62c78d76c020907c8f8286
7
+ data.tar.gz: 15f772925cb50837543ee0277ca3e4fbee42c0c64e3c0ad28c940617c008d51c4507f3950a3fb28a96086ea8d759368f7b06e04b2f4aaee406a6883cc61956cf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- opswalrus (1.0.12)
4
+ opswalrus (1.0.13)
5
5
  bcrypt_pbkdf (~> 1.1)
6
6
  citrus (~> 3.0)
7
7
  ed25519 (~> 1.3)
@@ -173,9 +173,8 @@ module OpsWalrus
173
173
  end
174
174
  end
175
175
 
176
- package_uri = package_url
177
- if Git.repo?(package_uri) # git repo
178
- download_git_package(package_url, version, destination_package_path)
176
+ if package_uri = Git.repo?(package_url) # git repo
177
+ download_git_package(package_uri, version, destination_package_path)
179
178
  end
180
179
  end
181
180
 
@@ -2,6 +2,7 @@ require "set"
2
2
  require "sshkit"
3
3
 
4
4
  require_relative "interaction_handlers"
5
+ require_relative "invocation"
5
6
 
6
7
  module OpsWalrus
7
8
 
@@ -48,6 +49,52 @@ module OpsWalrus
48
49
 
49
50
  # the subclasses of HostProxy will define methods that handle method dispatch via HostProxyOpsFileInvocationBuilder objects
50
51
  class HostProxy
52
+ # def self.define_host_proxy_class(ops_file)
53
+ # klass = Class.new(HostProxy)
54
+
55
+ # methods_defined = Set.new
56
+
57
+ # # define methods for every import in the script
58
+ # ops_file.local_symbol_table.each do |symbol_name, import_reference|
59
+ # unless methods_defined.include? symbol_name
60
+ # # puts "1. defining: #{symbol_name}(...)"
61
+ # klass.define_method(symbol_name) do |*args, **kwargs, &block|
62
+ # invocation_builder = case import_reference
63
+ # # we know we're dealing with a package dependency reference, so we want to run an ops file contained within the bundle directory,
64
+ # # therefore, we want to reference the specified ops file with respect to the bundle dir
65
+ # when PackageDependencyReference
66
+ # HostProxyOpsFileInvocationBuilder.new(self, true)
67
+
68
+ # # we know we're dealing with a directory reference or OpsFile reference outside of the bundle dir, so we want to reference
69
+ # # the specified ops file with respect to the root directory, and not with respect to the bundle dir
70
+ # when DirectoryReference, OpsFileReference
71
+ # HostProxyOpsFileInvocationBuilder.new(self, false)
72
+ # end
73
+
74
+ # invocation_builder.send(symbol_name, *args, **kwargs, &block)
75
+ # end
76
+ # methods_defined << symbol_name
77
+ # end
78
+ # end
79
+
80
+ # # define methods for every Namespace or OpsFile within the namespace that the OpsFile resides within
81
+ # sibling_symbol_table = Set.new
82
+ # sibling_symbol_table |= ops_file.dirname.glob("*.ops").map {|ops_file_path| ops_file_path.basename(".ops").to_s } # OpsFiles
83
+ # sibling_symbol_table |= ops_file.dirname.glob("*").select(&:directory?).map {|dir_path| dir_path.basename.to_s } # Namespaces
84
+ # sibling_symbol_table.each do |symbol_name|
85
+ # unless methods_defined.include? symbol_name
86
+ # # puts "2. defining: #{symbol_name}(...)"
87
+ # klass.define_method(symbol_name) do |*args, **kwargs, &block|
88
+ # invocation_builder = HostProxyOpsFileInvocationBuilder.new(self, false)
89
+ # invocation_builder.invoke(symbol_name, *args, **kwargs, &block)
90
+ # end
91
+ # methods_defined << symbol_name
92
+ # end
93
+ # end
94
+
95
+ # klass
96
+ # end
97
+
51
98
  def self.define_host_proxy_class(ops_file)
52
99
  klass = Class.new(HostProxy)
53
100
 
@@ -56,21 +103,40 @@ module OpsWalrus
56
103
  # define methods for every import in the script
57
104
  ops_file.local_symbol_table.each do |symbol_name, import_reference|
58
105
  unless methods_defined.include? symbol_name
59
- # puts "1. defining: #{symbol_name}(...)"
60
106
  klass.define_method(symbol_name) do |*args, **kwargs, &block|
61
- invocation_builder = case import_reference
107
+ # puts "resolving local symbol table entry: #{symbol_name}"
108
+ namespace_or_ops_file = @runtime_env.resolve_import_reference(ops_file, import_reference)
109
+ # puts "namespace_or_ops_file=#{namespace_or_ops_file.to_s}"
110
+
111
+ invocation_context = case import_reference
62
112
  # we know we're dealing with a package dependency reference, so we want to run an ops file contained within the bundle directory,
63
113
  # therefore, we want to reference the specified ops file with respect to the bundle dir
64
114
  when PackageDependencyReference
65
- HostProxyOpsFileInvocationBuilder.new(self, true)
115
+ RemoteImportInvocationContext.new(@runtime_env, self, namespace_or_ops_file, true)
66
116
 
67
117
  # we know we're dealing with a directory reference or OpsFile reference outside of the bundle dir, so we want to reference
68
118
  # the specified ops file with respect to the root directory, and not with respect to the bundle dir
69
119
  when DirectoryReference, OpsFileReference
70
- HostProxyOpsFileInvocationBuilder.new(self, false)
120
+ RemoteImportInvocationContext.new(@runtime_env, self, namespace_or_ops_file, false)
71
121
  end
72
122
 
73
- invocation_builder.send(symbol_name, *args, **kwargs, &block)
123
+ invocation_context._invoke(*args, **kwargs)
124
+
125
+
126
+
127
+ # invocation_builder = case import_reference
128
+ # # we know we're dealing with a package dependency reference, so we want to run an ops file contained within the bundle directory,
129
+ # # therefore, we want to reference the specified ops file with respect to the bundle dir
130
+ # when PackageDependencyReference
131
+ # HostProxyOpsFileInvocationBuilder.new(self, true)
132
+
133
+ # # we know we're dealing with a directory reference or OpsFile reference outside of the bundle dir, so we want to reference
134
+ # # the specified ops file with respect to the root directory, and not with respect to the bundle dir
135
+ # when DirectoryReference, OpsFileReference
136
+ # HostProxyOpsFileInvocationBuilder.new(self, false)
137
+ # end
138
+
139
+ # invocation_builder.send(symbol_name, *args, **kwargs, &block)
74
140
  end
75
141
  methods_defined << symbol_name
76
142
  end
@@ -84,8 +150,11 @@ module OpsWalrus
84
150
  unless methods_defined.include? symbol_name
85
151
  # puts "2. defining: #{symbol_name}(...)"
86
152
  klass.define_method(symbol_name) do |*args, **kwargs, &block|
87
- invocation_builder = HostProxyOpsFileInvocationBuilder.new(self, false)
88
- invocation_builder.invoke(symbol_name, *args, **kwargs, &block)
153
+ # invocation_builder = HostProxyOpsFileInvocationBuilder.new(self, false)
154
+ # invocation_builder.invoke(symbol_name, *args, **kwargs, &block)
155
+
156
+ invocation_context = RemoteImportInvocationContext.new(@runtime_env, self, namespace_or_ops_file, false)
157
+ invocation_context._invoke(*args, **kwargs)
89
158
  end
90
159
  methods_defined << symbol_name
91
160
  end
@@ -97,8 +166,9 @@ module OpsWalrus
97
166
 
98
167
  attr_accessor :_host
99
168
 
100
- def initialize(host)
169
+ def initialize(runtime_env, host)
101
170
  @_host = host
171
+ @runtime_env = runtime_env
102
172
  end
103
173
 
104
174
  # the subclasses of this class will define methods that handle method dispatch via HostProxyOpsFileInvocationBuilder objects
@@ -11,8 +11,137 @@
11
11
  # require_relative 'sshkit_ext'
12
12
  # require_relative 'walrus_lang'
13
13
 
14
- # module OpsWalrus
15
-
14
+ module OpsWalrus
15
+
16
+ class ImportInvocationContext
17
+ def _invoke(*args, **kwargs)
18
+ raise "Not implemented in base class"
19
+ end
20
+
21
+ def _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs, &block)
22
+ raise "Not implemented in base class"
23
+ end
24
+
25
+ def method_missing(name, *args, **kwargs, &block)
26
+ raise "Not implemented in base class"
27
+ end
28
+ end
29
+
30
+ class RemoteImportInvocationContext < ImportInvocationContext
31
+ def initialize(runtime_env, host_proxy, namespace_or_ops_file, is_invocation_a_call_to_package_in_bundle_dir = false)
32
+ @runtime_env = runtime_env
33
+ @host_proxy = host_proxy
34
+ @initial_namespace_or_ops_file = @namespace_or_ops_file = namespace_or_ops_file
35
+ @is_invocation_a_call_to_package_in_bundle_dir = is_invocation_a_call_to_package_in_bundle_dir
36
+
37
+ initial_method_name = @namespace_or_ops_file.dirname.basename
38
+ @method_chain = [initial_method_name]
39
+ end
40
+
41
+ def _invoke(*args, **kwargs)
42
+ case @namespace_or_ops_file
43
+ when Namespace
44
+ _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
45
+ when OpsFile
46
+ _invoke_remote(*args, **kwargs)
47
+ end
48
+ end
49
+
50
+ def _invoke_remote(*args, **kwargs)
51
+ # when there are args or kwargs, then the method invocation represents an attempt to run an OpsFile on a remote host,
52
+ # so we want to build up a command and send it to the remote host via HostDSL#run_ops
53
+ @method_chain.unshift(Bundler::BUNDLE_DIR) if @is_invocation_a_call_to_package_in_bundle_dir
54
+
55
+ remote_run_command_args = @method_chain.join(" ")
56
+
57
+ unless args.empty?
58
+ remote_run_command_args << " "
59
+ remote_run_command_args << args.join(" ")
60
+ end
61
+
62
+ unless kwargs.empty?
63
+ remote_run_command_args << " "
64
+ remote_run_command_args << kwargs.map do |k, v|
65
+ case v
66
+ when Array
67
+ v.map {|v_element| "#{k}:#{v_element}" }
68
+ else
69
+ "#{k}:#{v}"
70
+ end
71
+ end.join(" ")
72
+ end
73
+
74
+ @host_proxy.run_ops(:run, "--script", remote_run_command_args)
75
+ end
76
+
77
+ # if this namespace contains an OpsFile of the same name as the namespace, e.g. pkg/install/install.ops, then this
78
+ # method invokes the OpsFile of that same name and returns the result;
79
+ # otherwise we return this namespace object
80
+ def _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs, &block)
81
+ method_name = @namespace_or_ops_file.dirname.basename
82
+ resolved_symbol = @namespace_or_ops_file.resolve_symbol(method_name)
83
+ if resolved_symbol.is_a? OpsFile
84
+ _resolve_method_and_invoke(method_name)
85
+ else
86
+ self
87
+ end
88
+ end
89
+
90
+ def _resolve_method_and_invoke(name, *args, **kwargs)
91
+ @method_chain << name.to_s
92
+
93
+ @namespace_or_ops_file = @namespace_or_ops_file.resolve_symbol(name)
94
+ _invoke(*args, **kwargs)
95
+ end
96
+
97
+ def method_missing(name, *args, **kwargs, &block)
98
+ _resolve_method_and_invoke(name, *args, **kwargs)
99
+ end
100
+ end
101
+
102
+ class LocalImportInvocationContext < ImportInvocationContext
103
+ def initialize(runtime_env, namespace_or_ops_file)
104
+ @runtime_env = runtime_env
105
+ @initial_namespace_or_ops_file = @namespace_or_ops_file = namespace_or_ops_file
106
+ end
107
+
108
+ def _invoke(*args, **kwargs)
109
+ case @namespace_or_ops_file
110
+ when Namespace
111
+ _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
112
+ when OpsFile
113
+ _invoke_local(*args, **kwargs)
114
+ end
115
+ end
116
+
117
+ def _invoke_local(*args, **kwargs)
118
+ params_hash = @namespace_or_ops_file.build_params_hash(*args, **kwargs)
119
+ @namespace_or_ops_file.invoke(@runtime_env, params_hash)
120
+ end
121
+
122
+ # if this namespace contains an OpsFile of the same name as the namespace, e.g. pkg/install/install.ops, then this
123
+ # method invokes the OpsFile of that same name and returns the result;
124
+ # otherwise we return this namespace object
125
+ def _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs, &block)
126
+ method_name = @namespace_or_ops_file.dirname.basename
127
+ resolved_symbol = @namespace_or_ops_file.resolve_symbol(method_name)
128
+ if resolved_symbol.is_a? OpsFile
129
+ params_hash = resolved_symbol.build_params_hash(*args, **kwargs)
130
+ resolved_symbol.invoke(runtime_env, params_hash)
131
+ else
132
+ self
133
+ end
134
+ end
135
+
136
+ def _resolve_method_and_invoke(name, *args, **kwargs)
137
+ @namespace_or_ops_file = @namespace_or_ops_file.resolve_symbol(name)
138
+ _invoke(*args, **kwargs)
139
+ end
140
+
141
+ def method_missing(name, *args, **kwargs, &block)
142
+ _resolve_method_and_invoke(name, *args, **kwargs)
143
+ end
144
+ end
16
145
  # class ArrayOrHashNavigationProxy
17
146
  # def initialize(array_or_hash)
18
147
  # @obj = array_or_hash
@@ -443,4 +572,4 @@
443
572
  # # end
444
573
  # # end
445
574
  # end
446
- # end
575
+ end
@@ -1,4 +1,5 @@
1
1
  require 'set'
2
+ require_relative 'invocation'
2
3
  require_relative 'ops_file_script_dsl'
3
4
 
4
5
  module OpsWalrus
@@ -8,8 +9,6 @@ module OpsWalrus
8
9
  def self.define_for(ops_file, ruby_script)
9
10
  klass = Class.new(OpsFileScript)
10
11
 
11
- # puts "OpsFileScript.define_for(#{ops_file.to_s}, #{ruby_script.to_s})"
12
-
13
12
  methods_defined = Set.new
14
13
 
15
14
  # define methods for the OpsFile's local_symbol_table: local imports and private lib directory
@@ -21,14 +20,16 @@ module OpsWalrus
21
20
  namespace_or_ops_file = @runtime_env.resolve_import_reference(ops_file, import_reference)
22
21
  # puts "namespace_or_ops_file=#{namespace_or_ops_file.to_s}"
23
22
 
24
- case namespace_or_ops_file
25
- when Namespace
26
- namespace_or_ops_file
27
- namespace_or_ops_file._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
28
- when OpsFile
29
- params_hash = namespace_or_ops_file.build_params_hash(*args, **kwargs)
30
- namespace_or_ops_file.invoke(@runtime_env, params_hash)
31
- end
23
+ invocation_context = LocalImportInvocationContext.new(@runtime_env, namespace_or_ops_file)
24
+ invocation_context._invoke(*args, **kwargs)
25
+
26
+ # case namespace_or_ops_file
27
+ # when Namespace
28
+ # namespace_or_ops_file._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
29
+ # when OpsFile
30
+ # params_hash = namespace_or_ops_file.build_params_hash(*args, **kwargs)
31
+ # namespace_or_ops_file.invoke(@runtime_env, params_hash)
32
+ # end
32
33
  end
33
34
  methods_defined << symbol_name
34
35
  end
@@ -48,14 +49,17 @@ module OpsWalrus
48
49
  namespace_or_ops_file = @runtime_env.resolve_sibling_symbol(ops_file, symbol_name)
49
50
  # puts "namespace_or_ops_file=#{namespace_or_ops_file.to_s}"
50
51
 
51
- case namespace_or_ops_file
52
- when Namespace
53
- namespace_or_ops_file
54
- namespace_or_ops_file._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
55
- when OpsFile
56
- params_hash = namespace_or_ops_file.build_params_hash(*args, **kwargs)
57
- namespace_or_ops_file.invoke(@runtime_env, params_hash)
58
- end
52
+ invocation_context = LocalImportInvocationContext.new(@runtime_env, namespace_or_ops_file)
53
+ invocation_context._invoke(*args, **kwargs)
54
+
55
+
56
+ # case namespace_or_ops_file
57
+ # when Namespace
58
+ # namespace_or_ops_file._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
59
+ # when OpsFile
60
+ # params_hash = namespace_or_ops_file.build_params_hash(*args, **kwargs)
61
+ # namespace_or_ops_file.invoke(@runtime_env, params_hash)
62
+ # end
59
63
  end
60
64
  methods_defined << symbol_name
61
65
  end
@@ -114,10 +114,11 @@ module OpsWalrus
114
114
 
115
115
  module OpsFileScriptDSL
116
116
  def ssh(*args, **kwargs, &block)
117
- hosts = inventory(*args, **kwargs).map {|host| host_proxy_class.new(host) }
117
+ runtime_env = @runtime_env
118
+
119
+ hosts = inventory(*args, **kwargs).map {|host| host_proxy_class.new(runtime_env, host) }
118
120
  sshkit_hosts = hosts.map(&:sshkit_host)
119
121
  sshkit_host_to_ops_host_map = sshkit_hosts.zip(hosts).to_h
120
- runtime_env = @runtime_env
121
122
  local_host = self
122
123
  # bootstrap_shell_script = BootstrapLinuxHostShellScript
123
124
  # on sshkit_hosts do |sshkit_host|
@@ -82,32 +82,31 @@ module OpsWalrus
82
82
  @symbol_table[symbol_name.to_s]
83
83
  end
84
84
 
85
- # if this namespace contains an OpsFile of the same name as the namespace, e.g. pkg/install/install.ops, then this
86
- # method invokes the OpsFile of that same name and returns the result;
87
- # otherwise we return this namespace object
88
- def _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs, &block)
89
- resolved_symbol = resolve_symbol(@dirname.basename)
90
- if resolved_symbol.is_a? OpsFile
91
- params_hash = resolved_symbol.build_params_hash(*args, **kwargs)
92
- resolved_symbol.invoke(runtime_env, params_hash)
93
- else
94
- self
95
- end
96
- end
97
-
98
- def method_missing(name, *args, **kwargs, &block)
99
- # puts "method_missing: #{name}"
100
- # puts caller
101
- resolved_symbol = resolve_symbol(name)
102
- case resolved_symbol
103
- when Namespace
104
- resolved_symbol
105
- resolved_symbol._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
106
- when OpsFile
107
- params_hash = resolved_symbol.build_params_hash(*args, **kwargs)
108
- resolved_symbol.invoke(runtime_env, params_hash)
109
- end
110
- end
85
+ # # if this namespace contains an OpsFile of the same name as the namespace, e.g. pkg/install/install.ops, then this
86
+ # # method invokes the OpsFile of that same name and returns the result;
87
+ # # otherwise we return this namespace object
88
+ # def _invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs, &block)
89
+ # resolved_symbol = resolve_symbol(@dirname.basename)
90
+ # if resolved_symbol.is_a? OpsFile
91
+ # params_hash = resolved_symbol.build_params_hash(*args, **kwargs)
92
+ # resolved_symbol.invoke(runtime_env, params_hash)
93
+ # else
94
+ # self
95
+ # end
96
+ # end
97
+
98
+ # def method_missing(name, *args, **kwargs, &block)
99
+ # # puts "method_missing: #{name}"
100
+ # # puts caller
101
+ # resolved_symbol = resolve_symbol(name)
102
+ # case resolved_symbol
103
+ # when Namespace
104
+ # resolved_symbol._invoke_if_namespace_has_ops_file_of_same_name(*args, **kwargs)
105
+ # when OpsFile
106
+ # params_hash = resolved_symbol.build_params_hash(*args, **kwargs)
107
+ # resolved_symbol.invoke(runtime_env, params_hash)
108
+ # end
109
+ # end
111
110
  end
112
111
 
113
112
  # the assumption is that we have a bundle directory with all the packages in it
@@ -316,7 +315,7 @@ module OpsWalrus
316
315
  ops_file.invoke(self, params_hash)
317
316
  end
318
317
 
319
- # returns a Namespace or OpsFile
318
+ # returns a Namespace | OpsFile
320
319
  def resolve_sibling_symbol(origin_ops_file, symbol_name)
321
320
  @app_load_path.resolve_symbol(origin_ops_file, symbol_name)
322
321
  end
@@ -1,3 +1,3 @@
1
1
  module OpsWalrus
2
- VERSION = "1.0.12"
2
+ VERSION = "1.0.13"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opswalrus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.12
4
+ version: 1.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Ellis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-21 00:00:00.000000000 Z
11
+ date: 2023-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: citrus