opswalrus 1.0.12 → 1.0.13

Sign up to get free protection for your applications and to get access to all the features.
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