loom-core 0.0.1 → 0.0.2

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: '00595d8a3c27f3c3a2567849e6d188c68a3c5914646238f0009767bff5769687'
4
- data.tar.gz: 1988e1d88027c87309183db5355a2167f46ef2c48efcde7d5d143daf04011ea3
3
+ metadata.gz: fca395ca95a28376331f0163c1748fcd3eb083c2f6d677627edb04a795c5b858
4
+ data.tar.gz: 29fc16366271bfe121eb57b7315daa87a6d8017210d41a061cdecc6665bb26bc
5
5
  SHA512:
6
- metadata.gz: a48f5d6d82ec87da2c8e0dca0107602a434f8e4d8f42e1eb5d4d5638106aea1733836745d91db52f497b0eb4d2b9812909a42e9aef10a6408a26b23cb227758c
7
- data.tar.gz: dc23a63efd9405c7834911e66a709f944793e8b9bca62858e0a86864f999d0d8e942a21f9bda9893bd2672291806205d0b7e752cb9dbe70e0b2854630434bb97
6
+ metadata.gz: 291da2a4d0b793019dd65c511dfc1caa113a3a12c3a7f2ab12e9b991a8e5ce09b4fba97fb150b15b01edd6c67f0ea0536f16fc00384bf80c6ec54f9b21c9c1c2
7
+ data.tar.gz: 0b18248b8cf5583a48fb3844c39e15b0db216ad6c6ab62a160b5013d05e6f8931bbf165c35c7e107ce3de28a88e7227662480fd263f11031fb5356da2729c5a6
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  pkg
2
+ loom-core-0.0.1.gem
data/lib/loom/dsl.rb CHANGED
@@ -31,6 +31,7 @@ module Loom
31
31
  sshkit_backend = self
32
32
 
33
33
  begin
34
+ # TODO: document the reciever of this yield
34
35
  yield sshkit_backend, host_spec
35
36
  rescue SocketError => e
36
37
  Loom.log.error "error connecting to host => #{host_spec.hostname}"
@@ -53,6 +54,7 @@ module Loom
53
54
  end
54
55
  end
55
56
 
57
+ # TODO: Why did I make this "shadow" class?
56
58
  class SSHKitDSLShadow
57
59
  extend SSHKit::DSL
58
60
  end
@@ -11,6 +11,8 @@ module Loom
11
11
  attr_accessor :disabled
12
12
  attr_reader :sshkit_host
13
13
 
14
+ # TODO: change this to take an sshkit_host and make parse public. Stop calling parse from the
15
+ # ctor.
14
16
  def initialize(host_string)
15
17
  @sshkit_host = parse host_string
16
18
  end
@@ -26,7 +28,15 @@ module Loom
26
28
 
27
29
  private
28
30
  def parse(host_string)
29
- SSHKit::Host.new host_string
31
+ host = SSHKit::Host.new host_string
32
+ host.ssh_options = {
33
+ :auth_methods => ['publickey'],
34
+ :keys => ["~/.ssh/id_esd25519_2"],
35
+ # :verbose => :debug,
36
+ }
37
+ Loom.log.debug1(self) { "parsing hoststring[#{host_string}] => #{host}" }
38
+ Loom.log.debug1(self) { "netssh options for host[#{host}] => #{host.netssh_options}" }
39
+ host
30
40
  end
31
41
  end
32
42
  end
@@ -41,11 +41,11 @@ module Loom::Mods
41
41
  bound_action_name = tuple[1]
42
42
 
43
43
  define_method public_action_name do |*args, &block|
44
- # TODO: Effectively this is the API for all mods, but it's burried
45
- # here in the middle of nowhere. Add documentation - or make it
46
- # easier to read.
47
- Loom.log.debug2(self) do
48
- "proxy to mod #{@mod} => #{public_action_name}: #{args} #{block}"
44
+ # TODO[P0]: Effectively this is the API for all mods, but it's
45
+ # burried here in the middle of nowhere. Add documentation - or make
46
+ # it easier to read.
47
+ Loom.log.debug(self) do
48
+ "proxy to mod action: #{public_action_name} => #{bound_action_name}, #{@mod}"
49
49
  end
50
50
 
51
51
  @mod.send bound_action_name, *args, &block
@@ -89,7 +89,7 @@ module Loom::Mods
89
89
  def add_action(action_name, bound_method_name, namespace=nil)
90
90
  if namespace.nil?
91
91
  tuple = [action_name, bound_method_name]
92
- @action_tuples << tuple unless namespace
92
+ @action_tuples << tuple unless namespace
93
93
  else
94
94
  # Adds an action name to a nested ActionMap
95
95
  add_namespace(namespace).add_action action_name, bound_method_name
@@ -40,6 +40,9 @@ module Loom::Mods
40
40
  else
41
41
  Loom.log.debug3(self) { "initing action => #{args}" }
42
42
  init_action *args, &pattern_block
43
+
44
+ # TODO: ooohhh... the action_proxy code path is fucking
45
+ # crazy. ActionProxy needs some documentation.
43
46
  action_proxy
44
47
  end
45
48
  end
@@ -50,6 +53,8 @@ module Loom::Mods
50
53
  Loom.log.debug2(self) { "registered mod => #{name}" }
51
54
 
52
55
  if block_given?
56
+ # TODO: i forget what mod_blocks are. read through, remember, and
57
+ # document them.
53
58
  Loom.log.debug2(self) { "acting as mod_block => #{name}:#{block}" }
54
59
  define_method :mod_block, &block
55
60
  end
@@ -83,6 +88,11 @@ module Loom::Mods
83
88
  def bind_action(action_name, unbound_method, namespace=nil)
84
89
  bound_method_name = [namespace, action_name].compact.join '_'
85
90
 
91
+ # TODO: document why the `define_method` calls in class only operate on
92
+ # the single mod instance, rather than adding each "bound_method_name"
93
+ # (e.g.) to each instance of Module. (actually I think it's because this
94
+ # is executing from the subclass (via import_actions), so it's only that
95
+ # class). in any case, add more docs and code pointers.
86
96
  define_method bound_method_name do |*args, &block|
87
97
  Loom.log.debug1(self) { "exec mod action #{self.class}##{bound_method_name}" }
88
98
 
@@ -44,6 +44,14 @@ module Loom::Pattern
44
44
  report << "Completed in: %01.3fs" % @delta_t
45
45
 
46
46
  cmds.find_all { |cmd| !cmd.is_test }.each do |cmd|
47
+ # TODO: this is a bit confusing for the user... when you cat a file from
48
+ # a loom pattern, the output of a command isn't visible unless -V is
49
+ # specified... not sure what to do here. I don't want to see the output
50
+ # of every command, and I don't really want to pipe more info through
51
+ # the `@shell_session.command_results` (e.g. should_report_result:)?
52
+ #
53
+ # Although.. maybe that's the better API? then the logic here can be
54
+ # moved and strategized per command/result/shell.
47
55
  if !cmd.success? || @loom_config.run_verbose
48
56
  report.concat generate_cmd_report(cmd)
49
57
  end
data/lib/loom/runner.rb CHANGED
@@ -165,8 +165,8 @@ module Loom
165
165
  result_reporter = Loom::Pattern::ResultReporter.new(
166
166
  @loom_config, pattern_ref.slug, hostname, shell_session)
167
167
 
168
- # TODO: This is a crappy mechanism for tracking errors, there should be an
169
- # exception thrown inside of Shell when a command fails and pattern
168
+ # TODO: This is a crappy mechanism for tracking errors (hency my crappy error reporting :( ),
169
+ # there should be an exception thrown inside of Shell when a command fails and pattern
170
170
  # execution should stop. All errors should come from exceptions.
171
171
  run_failure = []
172
172
  begin
@@ -175,7 +175,8 @@ module Loom
175
175
  Loom.log.debug e.backtrace.join "\n\t"
176
176
  run_failure << e
177
177
  ensure
178
- # TODO: this prints out [Result: OK] even if an exception is raised
178
+ # TODO[P0]: this prints out [Result: OK] even if an exception is raised... this is really
179
+ # annoying.
179
180
  result_reporter.write_report
180
181
 
181
182
  # TODO: this is not the correct error condition.
@@ -24,6 +24,10 @@ module Loom::Shell
24
24
 
25
25
  attr_reader :session, :shell_api, :mod_loader, :dry_run
26
26
 
27
+ def is_sudo?
28
+ !@sudo_users.empty?
29
+ end
30
+
27
31
  def local
28
32
  @local ||= LocalShell.new @mod_loader, @session, @dry_run
29
33
  end
@@ -96,6 +100,35 @@ module Loom::Shell
96
100
  end
97
101
  end
98
102
 
103
+ # def sudo(user=nil, *sudo_cmd, &block)
104
+ # # I'm trying to work around crappy double escaping issues caused by
105
+ # # sudo_legacy... but I'm failing
106
+ # if block_given?
107
+ # # TODO: this shit is broken with these errors:
108
+ # # $ ... 'You cannot switch to user '' using sudo, please check the sudoers file'
109
+ # #
110
+ # # Loom.log.debug3(self) { "sudo with SSHKit::Backend+as+" }
111
+ # # @sshkit_backend.as user, &block
112
+
113
+ # # Aside from probably being unsafe... this implementation leads to a
114
+ # # hung terminal after switching to root.... sigh....
115
+ # #
116
+ # # Loom.log.warn(self) { "fix sudo... this doesn't seem safe" }
117
+ # # execute "sudo", "su", user
118
+ # # begin
119
+ # # yield
120
+ # # ensure
121
+ # # execute "exit"
122
+ # # end
123
+
124
+ # Loom.log.debug3(self) { "sudo legacy... the other way" }
125
+ # sudo_stack_and_wrap(user, *sudo_cmd, &block)
126
+ # else
127
+ # Loom.log.debug3(self) { "sudo legacy" }
128
+ # sudo_stack_and_wrap(user, *sudo_cmd)
129
+ # end
130
+ # end
131
+
99
132
  def cd(path, &block)
100
133
  Loom.log.debug1(self) { "cd => #{path} #{block}" }
101
134
 
@@ -124,6 +157,10 @@ module Loom::Shell
124
157
  execute cmd
125
158
  end
126
159
 
160
+ def upload(local_path, remote_path)
161
+ @sshkit_backend.upload! local_path, remote_path
162
+ end
163
+
127
164
  def execute(*cmd_parts, is_test: false, **cmd_opts)
128
165
  cmd_parts.compact!
129
166
  raise "empty command passed to execute" if cmd_parts.empty?
@@ -159,9 +196,10 @@ module Loom::Shell
159
196
  "[%s]:$ %s" % [prompt_label, output]
160
197
  end
161
198
 
162
- def execute_internal(*cmd_parts, piped_cmds: [])
199
+ def execute_internal(*cmd_parts, pipe_to: [])
163
200
  primary_cmd = create_command *cmd_parts
164
- piped_cmds = piped_cmds.map { |cmd_parts| CmdWrapper.new *cmd_parts }
201
+ # TODO: where is piped_cmds used?
202
+ piped_cmds = pipe_to.map { |cmd_parts| CmdWrapper.new *cmd_parts }
165
203
 
166
204
  cmd = CmdPipeline.new([primary_cmd].concat(piped_cmds)).to_s
167
205
  # Tests if the command looks like "echo\ hi", the trailing slash after
@@ -187,9 +225,13 @@ module Loom::Shell
187
225
  # @return [String|Loom::Shell::CmdWrapper]
188
226
  def create_command(*cmd_parts)
189
227
  cmd_wrapper = if cmd_parts.is_a? CmdWrapper
228
+ Loom.log.debug3(self) { "existing cmd from args => #{cmd_parts}" }
190
229
  cmd_parts
230
+ elsif cmd_parts[0].is_a? CmdWrapper
231
+ Loom.log.debug3(self) { "existing cmd from args[0] => #{cmd_parts[0]}" }
232
+ cmd_parts[0]
191
233
  else
192
- Loom.log.debug3(self) { "new cmd from parts => #{cmd_parts}" }
234
+ Loom.log.debug3(self) { "new cmd from args => #{cmd_parts}" }
193
235
  CmdWrapper.new *cmd_parts
194
236
  end
195
237
 
@@ -0,0 +1,168 @@
1
+ # 10/21/2018: I resurrected this from an auto save file from a LOONNGGGG time
2
+ # ago., not really sure exactly what the original purpose is, but it has the
3
+ # code for uploading the harness script. I believe this was working at one
4
+ # point, but that was long ago
5
+
6
+ module Loom
7
+
8
+ # Ensures loom is setup to run on the remote.
9
+ # - creates the boostrap loom directory
10
+ # - uploads the harness
11
+ # - creates a directoy for loom execution logging
12
+ class HostSession
13
+
14
+ HISTORY_FILE = "command.log"
15
+
16
+ # @param [Loom::HostSpec] host_spec
17
+ # @param [Loom::Config] loom_config
18
+ # @param [SSHKit::Backend::Abstract] sshkit_backend
19
+ def initialize(host_spec, loom_config, sshkit_backend)
20
+ @host_spec = host_spec
21
+ @sshkit_backend = sshkit_backend
22
+ @loom_config = loom_config
23
+
24
+ @remote_loom_root = loom_config.bootstrap_loom_root
25
+ @loom_user = loom_config.loom_user
26
+
27
+ @session_name = "session.%d" % Time.now.to_i
28
+ @disabled = false
29
+ end
30
+
31
+ attr_reader :session_name
32
+
33
+ def bootstrap
34
+ ensure_loom_remote_dirs
35
+ ensure_harness_uploaded
36
+ log_to_command_history "begin loom execution"
37
+ log_to_command_history "start: " + Time.now.to_i.to_s
38
+ end
39
+
40
+ def disabled?
41
+ @disabled
42
+ end
43
+
44
+ # @param [Loom::Pattern::Reference] pattern_ref
45
+ # @return [Loom::Pattern::ExecResult]
46
+ def execute_pattern(pattern_ref)
47
+ shell = create_shell
48
+
49
+ shell_session = shell.session
50
+ result_reporter = Loom::Pattern::ResultReporter.new(
51
+ @loom_config, pattern_ref.slug, hostname, shell_session)
52
+
53
+ # TODO: This is a crappy mechanism for tracking errors, there should be an
54
+ # exception thrown inside of Shell when a command fails and pattern
55
+ # execution should stop. All errors should come from exceptions.
56
+ run_failure = []
57
+ begin
58
+ fact_set = collect_facts_for_host
59
+ pattern_ref.call(shell.shell_api, fact_set)
60
+ rescue => e
61
+ handle_host_failure e
62
+ ensure
63
+ # TODO: this prints out [Result: OK] even if an exception is raised
64
+ result_reporter.write_report
65
+
66
+ # TODO: this is not the correct error condition.
67
+ unless shell_session.success?
68
+ run_failure << result_reporter.failure_summary
69
+ handle_host_failure result_reporter.failure_summary
70
+ end
71
+ @result_reports << result_reporter
72
+ @run_failures << run_failure unless run_failure.empty?
73
+ end
74
+ end
75
+
76
+ def handle_host_failure(error_or_message=nil)
77
+ Loom.log.debug { "handling host failure => #{hostname}" }
78
+ if error_or_message.respond_to? :backtrace
79
+ Loom.log.debug { e.backtrace.join "\n\t" }
80
+ end
81
+
82
+ message = if error_or_message.respond_to? :message
83
+ error_or_message.message
84
+ else
85
+ error_or_message
86
+ end
87
+
88
+ failure_strategy = @loom_config.run_failure_strategy.to_sym
89
+ case failure_strategy
90
+ when :exclude_host
91
+ Loom.log.warn "disabling host due to failure => #{message}"
92
+ @disabled = true
93
+ when :fail_fast
94
+ Loom.log.error "fail fast host failure => #{message}"
95
+ raise FailFastExecutionError, message
96
+ when :cowboy
97
+ # This is mostly for testing, don't use in prod.
98
+ Loom.log.warn "cowboy failure, wooohooo => #{message}"
99
+ else
100
+ raise ConfigError, "unknown failure_strategy: #{failure_stratgy}"
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ # @return [String]
107
+ def script_path
108
+ File.join @remote_loom_root, "scripts"
109
+ end
110
+
111
+ # @return [String]
112
+ def session_path
113
+ File.join @remote_loom_root, "run", @session_name
114
+ end
115
+
116
+ # @return [String]
117
+ def history_file
118
+ File.join session_name, HISTORY_FILE
119
+ end
120
+
121
+ def ensure_loom_remote_dirs
122
+ @sshkit_backend.as user: :root do
123
+ @sshkit_backend.execute :mkdir, '-p', @remote_loom_root
124
+ @sshkit_backend.execute :mkdir, '-p', script_path
125
+ @sshkit_backend.execute :mkdir, '-p', session_path
126
+
127
+ chown_opts = "-R %s:%s %s" % [@loom_user, @loom_user, @remote_loom_root]
128
+ @sshkit_backend.execute :chown, chown_opts
129
+ end
130
+ end
131
+
132
+ def ensure_harness_uploaded
133
+ @sshkit_backend.upload! Loom::Resource::HARNESS, script_path
134
+ end
135
+
136
+ def create_command_history
137
+ @sshkit_backend :touch, history_file
138
+ end
139
+
140
+ def write_to_command_history(text)
141
+ @sshkit_backend :cat, "<<EOS\n#{text}\nEOS", ">>", history_file
142
+ end
143
+
144
+ def log_to_command_history(text)
145
+ write_to_command_history(
146
+ "[%s] %s: #{text}" % [Time.now.utc.to_s, hostname])
147
+ end
148
+
149
+ # The naming inconsistency w/ the missing underscore in hostname (vs
150
+ # host_spec, host_session, etc...) is confusing, but that's *nix's fault.
151
+ def hostname
152
+ @host_spec.hostname
153
+ end
154
+
155
+ def collect_facts_for_host
156
+ Loom.log.info "collecting facts for host => #{hostname}"
157
+ Loom::Facts.fact_set(@host_spec, create_shell, @loom_config)
158
+ end
159
+
160
+ def create_shell
161
+ Loom::Shell.create create_mod_loader, @sshkit_backend
162
+ end
163
+
164
+ def create_mod_loader
165
+ Loom::Mods::ModLoader.new loom_config
166
+ end
167
+ end
168
+ end
data/lib/loom/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Loom
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -10,4 +10,5 @@ require_relative "files"
10
10
  require_relative "net"
11
11
  require_relative "user"
12
12
  require_relative "package/package"
13
+ require_relative "system"
13
14
  require_relative "vm/all"
@@ -31,11 +31,17 @@ module LoomExt::CoreMods
31
31
  end
32
32
 
33
33
  class Sudo < Loom::Mods::Module
34
- register_mod :sudo do |user: nil, cmd: nil, &block|
34
+ register_mod :sudo do |user: :root, cmd: nil, &block|
35
35
  shell.sudo user, cmd, &block
36
36
  end
37
37
  end
38
38
 
39
+ class SudoCheck < Loom::Mods::Module
40
+ register_mod :is_sudo? do
41
+ shell.is_sudo?
42
+ end
43
+ end
44
+
39
45
  class Test < Loom::Mods::Module
40
46
  register_mod :test do |*cmd|
41
47
  shell.test *cmd
@@ -47,4 +53,10 @@ module LoomExt::CoreMods
47
53
  raise FailError, message
48
54
  end
49
55
  end
56
+
57
+ class Upload < Loom::Mods::Module
58
+ register_mod :upload do |local_path, remote_path|
59
+ shell.upload local_path, remote_path
60
+ end
61
+ end
50
62
  end
@@ -3,6 +3,8 @@ module LoomExt::CoreMods
3
3
 
4
4
  register_mod :files
5
5
 
6
+ # TODO: document loom file statements like:
7
+ # `loom.files("some", "different/paths").cat`
6
8
  def init_action(paths)
7
9
  @paths = [paths].flatten.compact
8
10
  end
@@ -45,6 +47,12 @@ module LoomExt::CoreMods
45
47
  end
46
48
  end
47
49
 
50
+ def mv(new_path)
51
+ each_path do |p|
52
+ shell.capture :mv, p, new_path
53
+ end
54
+ end
55
+
48
56
  def match?(pattern: /./)
49
57
  all = true
50
58
  each_path do |p|
@@ -80,20 +88,70 @@ module LoomExt::CoreMods
80
88
  each_path :action => :mkdir, :flags => flags
81
89
  end
82
90
 
91
+ def ensure_line(line, sudo: false)
92
+ if loom.is_sudo?
93
+ Loom.log.warn "do not use files.ensure_line in sudo due to poor command escaping" +
94
+ ": use files.ensure_line and pass sudo: true"
95
+ end
96
+
97
+ each_path do |p|
98
+ file = shell.capture :cat, p
99
+
100
+ unless file.match(line)
101
+ if sudo
102
+ sudo_append(line)
103
+ else
104
+ append(line)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ # this is a hack to accomodate append being f'd inside sudo blocks
111
+ def sudo_append(text="")
112
+ if text.index "\n"
113
+ Loom.log.warn "append lines individually until cmd escaping is fixed.... "
114
+ end
115
+
116
+ each_path do |p|
117
+ text.each_line do |line|
118
+ loom.x "/bin/echo", "-e", line, :pipe_to => [[:sudo, :tee, "-a", p]]
119
+ end
120
+ end
121
+ end
122
+
83
123
  def append(text="")
124
+ if text.index "\n"
125
+ Loom.log.warn "append lines individually until cmd escaping is fixed.... "
126
+ end
127
+
128
+ if loom.is_sudo?
129
+ Loom.log.warn "do not use files.append in sudo" +
130
+ ": use files.sudo_append due to poor command escaping"
131
+ end
132
+
84
133
  each_path do |p|
85
- loom.test "[ -f #{p} ]"
134
+ # TODO: this shit is broken when escaped in a sudo command. This is
135
+ # why I began work on the harness.
136
+ # $ cd /home/pi; sudo -u root -- /bin/sh -c "/bin/echo -e 192.168.1.190 rp0\''; '\'" | tee -a /etc/hosts
137
+ #
138
+ text.each_line do |line|
139
+ loom.x :"/bin/echo", "-e", line, :pipe_to => [[:tee, "-a", p]]
140
+ end
86
141
 
87
- redirect = Loom::Shell::CmdRedirect.append_stdout p
88
- cmd = Loom::Shell::CmdWrapper.new(
89
- :"/bin/echo", "-e", text, redirect: redirect)
90
- shell.execute cmd
142
+ # TODO: fix this broken shit w/ the harness, CmdRedirect and
143
+ # CmdWrapper are dogshit. This was an escaping attempt before harness
144
+ # script.
145
+ #
146
+ # redirect = Loom::Shell::CmdRedirect.append_stdout p
147
+ # cmd = Loom::Shell::CmdWrapper.new(
148
+ # :"/bin/echo", "-e", text, redirect: redirect)
91
149
  end
92
150
  end
93
151
 
94
152
  def write(text="")
95
153
  each_path do |p|
96
- loom.x :"/bin/echo", "-e", text, :piped_cmds => [[:tee, p]]
154
+ loom.x :"/bin/echo", "-e", text, :pipe_to => [[:tee, p]]
97
155
  end
98
156
  end
99
157
 
@@ -54,7 +54,8 @@ module LoomExt::CoreMods
54
54
  class AptAdapter < DpkgAdapter
55
55
 
56
56
  def install(pkg_name)
57
- loom.net.with_net { loom << "echo apt-get install #{pkg_name}" }
57
+ loom.x "apt-get", "-y", "install", pkg_name
58
+ # loom.net.with_net { loom << "echo apt-get install #{pkg_name}" }
58
59
  end
59
60
 
60
61
  def uninstall(pkg_name)
@@ -62,11 +63,14 @@ module LoomExt::CoreMods
62
63
  end
63
64
 
64
65
  def update_cache
65
- loom.net.with_net { loom << "apt update" }
66
+ # loom.net.with_net { loom << "apt update" }
67
+ loom.x "apt", "-y", "update"
66
68
  end
67
69
 
68
- def upgrade(pkg_name)
69
- loom.net.with_net { loom << "apt upgrade" }
70
+ def upgrade(pkg_name = nil)
71
+ # loom.net.with_net { loom << "apt upgrade" }
72
+ args = ["apt-get", "-y", "upgrade", pkg_name].compact
73
+ loom.x(*args)
70
74
  end
71
75
  end
72
76
 
@@ -0,0 +1,52 @@
1
+ module LoomExt::CoreMods
2
+
3
+ class Systemd < Loom::Mods::Module
4
+
5
+ register_mod :systemd
6
+
7
+ def do_systemctl(action, *args)
8
+ shell.execute "systemctl", action, *args
9
+ end
10
+
11
+ module Actions
12
+
13
+ def is_loaded?(unit)
14
+ status(unit).match? /^\s+Loaded:\sloaded\s/
15
+ end
16
+
17
+ def is_active?(unit)
18
+ status(unit).match? /^\s+Active:\sactive\s/
19
+ end
20
+
21
+ def status(unit)
22
+ do_systemctl "status", unit
23
+ end
24
+
25
+ def enable(unit)
26
+ do_systemctl "enable", unit
27
+ end
28
+
29
+ def start(unit)
30
+ do_systemctl "start", unit
31
+ end
32
+
33
+ def disable(unit)
34
+ do_systemctl "disable", unit
35
+ end
36
+
37
+ def restart(unit)
38
+ do_systemctl "restart", unit
39
+ end
40
+
41
+ def stop(unit)
42
+ do_systemctl "stop", unit
43
+ end
44
+
45
+ def link(path)
46
+ do_systemctl "link", path
47
+ end
48
+ end
49
+ end
50
+
51
+ Systemd.import_actions Systemd::Actions
52
+ end
@@ -13,7 +13,7 @@ module LoomExt::CoreMods::VM
13
13
  end
14
14
 
15
15
  def check_running(vm)
16
- loom.test "vboxmanage list runningvms".split, :piped_cmds => [
16
+ loom.test "vboxmanage list runningvms".split, :pipe_to => [
17
17
  "grep \"#{vm}\"".split
18
18
  ]
19
19
  end
data/loom.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.add_dependency 'sshkit', '~> 1.11'
19
19
  s.add_dependency 'commander', '~> 4.4'
20
20
 
21
+ # *** Obsolete, see new issue below ***
21
22
  # Need net-ssh beta and its explicit requirements until for ed25519
22
23
  # elliptic curve key support
23
24
  # https://github.com/net-ssh/net-ssh/issues/214
@@ -26,9 +27,13 @@ Gem::Specification.new do |s|
26
27
  # release due to net-scp gem dependencies.
27
28
  # I can manually `gem install net-ssh --version 4.0.0.beta3` for now.
28
29
  # s.add_dependency 'net-ssh', '>= 4.0.0.beta3'
29
- s.add_dependency 'net-ssh', '>= 3'
30
+ s.add_dependency 'net-ssh', '>= 5'
30
31
  s.add_dependency 'rbnacl-libsodium', '1.0.10'
31
- s.add_dependency 'bcrypt_pbkdf', '1.0.0.alpha1'
32
+ s.add_dependency 'bcrypt_pbkdf', ">= 1.0", "< 2.0"
33
+
34
+ # New net-ssh requiremetns for ed25519
35
+ # https://github.com/net-ssh/net-ssh/issues/565
36
+ s.add_dependency 'ed25519', '>=1.0', '<2.0'
32
37
 
33
38
  s.add_development_dependency 'bundler', '~> 1.13'
34
39
  s.add_development_dependency 'rake', '~> 11.3'
data/scripts/harness.sh CHANGED
@@ -28,7 +28,8 @@
28
28
  # EOS
29
29
  #
30
30
  # There are 2 different shells that the harness deals with. The
31
- # harness shell, and the command shell.
31
+ # harness shell, and the command shell. The point being, to isolate
32
+ # each environment and be independent of the other.
32
33
  #
33
34
  # The harness shell is the shell used to run the harness script (this
34
35
  # file). Only POSIX features are supported in the harness
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loom-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erick Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-27 00:00:00.000000000 Z
11
+ date: 2018-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sshkit
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3'
47
+ version: '5'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3'
54
+ version: '5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rbnacl-libsodium
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +70,42 @@ dependencies:
70
70
  name: bcrypt_pbkdf
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '='
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ - - "<"
74
77
  - !ruby/object:Gem::Version
75
- version: 1.0.0.alpha1
78
+ version: '2.0'
76
79
  type: :runtime
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
80
- - - '='
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '1.0'
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '2.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: ed25519
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
96
+ - - "<"
97
+ - !ruby/object:Gem::Version
98
+ version: '2.0'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '1.0'
106
+ - - "<"
81
107
  - !ruby/object:Gem::Version
82
- version: 1.0.0.alpha1
108
+ version: '2.0'
83
109
  - !ruby/object:Gem::Dependency
84
110
  name: bundler
85
111
  requirement: !ruby/object:Gem::Requirement
@@ -213,6 +239,7 @@ files:
213
239
  - lib/loom/shell/cmd_result.rb
214
240
  - lib/loom/shell/cmd_wrapper.rb
215
241
  - lib/loom/shell/core.rb
242
+ - lib/loom/shell/harness/session.rb
216
243
  - lib/loom/shell/harness_blob.rb
217
244
  - lib/loom/shell/harness_command_builder.rb
218
245
  - lib/loom/shell/session.rb
@@ -229,6 +256,7 @@ files:
229
256
  - lib/loomext/coremods/net.rb
230
257
  - lib/loomext/coremods/package/adapter.rb
231
258
  - lib/loomext/coremods/package/package.rb
259
+ - lib/loomext/coremods/system.rb
232
260
  - lib/loomext/coremods/user.rb
233
261
  - lib/loomext/coremods/vm.rb
234
262
  - lib/loomext/coremods/vm/all.rb
@@ -268,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
296
  version: '0'
269
297
  requirements: []
270
298
  rubyforge_project:
271
- rubygems_version: 2.7.6
299
+ rubygems_version: 2.7.7
272
300
  signing_key:
273
301
  specification_version: 4
274
302
  summary: Repeatable management of remote hosts over SSH