inprovise 0.2.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 +15 -0
- data/.gitignore +4 -0
- data/.travis.yml +28 -0
- data/Gemfile +9 -0
- data/LICENSE +8 -0
- data/README.md +197 -0
- data/Rakefile.rb +9 -0
- data/bin/rig +5 -0
- data/inprovise.gemspec +22 -0
- data/lib/inprovise/channel/ssh.rb +202 -0
- data/lib/inprovise/cli/group.rb +86 -0
- data/lib/inprovise/cli/node.rb +95 -0
- data/lib/inprovise/cli/provision.rb +84 -0
- data/lib/inprovise/cli.rb +105 -0
- data/lib/inprovise/cmd_channel.rb +100 -0
- data/lib/inprovise/cmd_helper.rb +150 -0
- data/lib/inprovise/control.rb +326 -0
- data/lib/inprovise/execution_context.rb +277 -0
- data/lib/inprovise/group.rb +67 -0
- data/lib/inprovise/helper/cygwin.rb +43 -0
- data/lib/inprovise/helper/linux.rb +181 -0
- data/lib/inprovise/helper/windows.rb +123 -0
- data/lib/inprovise/infra.rb +122 -0
- data/lib/inprovise/local_file.rb +120 -0
- data/lib/inprovise/logger.rb +79 -0
- data/lib/inprovise/node.rb +271 -0
- data/lib/inprovise/remote_file.rb +128 -0
- data/lib/inprovise/resolver.rb +36 -0
- data/lib/inprovise/script.rb +175 -0
- data/lib/inprovise/script_index.rb +46 -0
- data/lib/inprovise/script_runner.rb +110 -0
- data/lib/inprovise/sniff.rb +46 -0
- data/lib/inprovise/sniffer/linux.rb +64 -0
- data/lib/inprovise/sniffer/platform.rb +46 -0
- data/lib/inprovise/sniffer/unknown.rb +11 -0
- data/lib/inprovise/sniffer/windows.rb +32 -0
- data/lib/inprovise/template/inprovise.rb.erb +92 -0
- data/lib/inprovise/template.rb +38 -0
- data/lib/inprovise/trigger_runner.rb +36 -0
- data/lib/inprovise/version.rb +10 -0
- data/lib/inprovise.rb +145 -0
- data/test/cli_test.rb +314 -0
- data/test/cli_test_helper.rb +19 -0
- data/test/dsl_test.rb +43 -0
- data/test/fixtures/example.txt +1 -0
- data/test/fixtures/include.rb +4 -0
- data/test/fixtures/inprovise.rb +1 -0
- data/test/fixtures/myscheme.rb +1 -0
- data/test/infra_test.rb +189 -0
- data/test/local_file_test.rb +64 -0
- data/test/remote_file_test.rb +106 -0
- data/test/resolver_test.rb +66 -0
- data/test/script_index_test.rb +53 -0
- data/test/script_test.rb +56 -0
- data/test/test_helper.rb +237 -0
- metadata +182 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# CLI Node commands for Inprovise
|
2
|
+
#
|
3
|
+
# Author:: Martin Corino
|
4
|
+
# License:: Distributes under the same license as Ruby
|
5
|
+
|
6
|
+
class Inprovise::Cli
|
7
|
+
|
8
|
+
desc 'Manage infrastructure nodes'
|
9
|
+
command :node do |cnod|
|
10
|
+
|
11
|
+
cnod.desc 'Add an infrastructure node'
|
12
|
+
cnod.arg_name 'NODE'
|
13
|
+
cnod.command :add do |cnod_add|
|
14
|
+
|
15
|
+
cnod_add.flag [:a, :address], :arg_name => 'ADDRESS', :desc => 'Set the node address (hostname or IP). If not set node name is used as hostname.'
|
16
|
+
cnod_add.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the node.'
|
17
|
+
cnod_add.flag [:C, :credential], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a security credential setting for the node.'
|
18
|
+
cnod_add.switch [:sniff], :default_value => true, :desc => 'Enable or disable running sniffers'
|
19
|
+
cnod_add.flag [:g, :group], :arg_name => 'GROUP', :multiple => true, :desc => 'Existing infrastructure group to add new node to.'
|
20
|
+
|
21
|
+
cnod_add.action do |global,options,args|
|
22
|
+
raise ArgumentError, 'Missing or too many arguments!' unless args.size == 1
|
23
|
+
Inprovise::Controller.run(:add, options, :node, *args)
|
24
|
+
Inprovise::Controller.wait!
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
cnod.desc 'Remove (an) infrastructure node(s)'
|
30
|
+
cnod.arg_name 'NODE[ NODE [...]]'
|
31
|
+
cnod.command :remove do |cnod_del|
|
32
|
+
|
33
|
+
cnod_del.action do |global,options,args|
|
34
|
+
raise ArgumentError, 'Missing argument!' if args.empty?
|
35
|
+
Inprovise::Controller.run(:remove, options, :node, *args)
|
36
|
+
Inprovise::Controller.wait!
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
cnod.desc 'Update node configuration for the given infrastructure node(s) or group(s).'
|
42
|
+
cnod.arg_name 'NAME[ NAME [...]]'
|
43
|
+
cnod.command :update do |cnod_update|
|
44
|
+
|
45
|
+
cnod_update.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the node(s)'
|
46
|
+
cnod_update.flag [:C, :credential], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a security credential setting for the node.'
|
47
|
+
cnod_update.switch [:r, :reset], negatable: false, :desc => 'Reset configuration before update (default is to merge updates)'
|
48
|
+
cnod_update.switch [:sniff], :default_value => true, :desc => 'Enable or disable running sniffers'
|
49
|
+
cnod_update.flag [:g, :group], :arg_name => 'GROUP', :multiple => true, :desc => 'Existing infrastructure group to add node(s) to.'
|
50
|
+
|
51
|
+
cnod_update.action do |global,options,args|
|
52
|
+
raise ArgumentError, 'Missing argument!' if args.empty?
|
53
|
+
Inprovise::Controller.run(:update, options, :node, *args)
|
54
|
+
Inprovise::Controller.wait!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
cnod.desc 'List infrastructure nodes (all or for specified nodes/groups)'
|
59
|
+
cnod.arg_name '[NAME[ NAME [...]]]'
|
60
|
+
cnod.command :list do |cnod_list|
|
61
|
+
cnod_list.switch [:d, :details], negatable: false, :desc => 'Show node details'
|
62
|
+
|
63
|
+
cnod_list.action do |global_options,options,args|
|
64
|
+
$stdout.puts
|
65
|
+
$stdout.puts " INFRASTRUCTURE NODES"
|
66
|
+
$stdout.puts " ===================="
|
67
|
+
if args.empty?
|
68
|
+
Inprovise::Infrastructure.list(Inprovise::Infrastructure::Node).each do |n|
|
69
|
+
Inprovise::Cli.show_target(n, options[:details])
|
70
|
+
end
|
71
|
+
else
|
72
|
+
args.each do |a|
|
73
|
+
tgt = Inprovise::Infrastructure.find(a)
|
74
|
+
case tgt
|
75
|
+
when Inprovise::Infrastructure::Node
|
76
|
+
Inprovise::Cli.show_target(tgt, options[:details])
|
77
|
+
when Inprovise::Infrastructure::Group
|
78
|
+
$stdout.puts " #{tgt.to_s}"
|
79
|
+
$stdout.puts " #{'-' * tgt.to_s.size}"
|
80
|
+
tgt.targets.each {|n| Inprovise::Cli.show_target(n, options[:details]) }
|
81
|
+
$stdout.puts " #{'-' * tgt.to_s.size}"
|
82
|
+
else
|
83
|
+
$stdout.puts "ERROR: #{a} is unknown".red
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
$stdout.puts
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
cnod.default_command :list
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# CLI provisioning commands for Inprovise
|
2
|
+
#
|
3
|
+
# Author:: Martin Corino
|
4
|
+
# License:: Distributes under the same license as Ruby
|
5
|
+
|
6
|
+
class Inprovise::Cli
|
7
|
+
|
8
|
+
desc 'Apply the given script/package to the specified infrastructure nodes and/or groups.'
|
9
|
+
arg_name 'SCRIPT TARGET[ TARGET[...]]'
|
10
|
+
command :apply do |capply|
|
11
|
+
|
12
|
+
capply.desc 'Path to a provisioning scheme to load'
|
13
|
+
capply.flag [:s,:scheme], :arg_name => 'FILE', :multiple => true, :default_value => Inprovise.default_scheme
|
14
|
+
capply.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the script execution'
|
15
|
+
|
16
|
+
capply.action do |global, options, args|
|
17
|
+
raise ArgumentError, 'Missing arguments!' if args.empty?
|
18
|
+
raise ArgumentError, 'Missing targets!' if args.size < 2
|
19
|
+
Inprovise::Controller.run(:apply, options, *args)
|
20
|
+
Inprovise::Controller.wait!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Revert the given script/package on the specified infrastructure nodes and/or groups.'
|
25
|
+
arg_name 'SCRIPT NAME[ NAME[...]]'
|
26
|
+
command :revert do |crevert|
|
27
|
+
|
28
|
+
crevert.desc 'Path to a provisioning scheme to load'
|
29
|
+
crevert.flag [:s,:scheme], :arg_name => 'FILE', :multiple => true, :default_value => Inprovise.default_scheme
|
30
|
+
crevert.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the script execution'
|
31
|
+
|
32
|
+
crevert.action do |global, options, args|
|
33
|
+
raise ArgumentError, 'Missing arguments!' if args.empty?
|
34
|
+
raise ArgumentError, 'Missing targets!' if args.size < 2
|
35
|
+
Inprovise::Controller.run(:revert, options, *args)
|
36
|
+
Inprovise::Controller.wait!
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Validate the given script/package on the specified infrastructure nodes and/or groups.'
|
41
|
+
arg_name 'SCRIPT NAME[ NAME[...]]'
|
42
|
+
command :validate do |cvalid|
|
43
|
+
|
44
|
+
cvalid.desc 'Path to a provisioning scheme to load'
|
45
|
+
cvalid.flag [:s,:scheme], :arg_name => 'FILE', :multiple => true, :default_value => Inprovise.default_scheme
|
46
|
+
cvalid.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the script execution'
|
47
|
+
|
48
|
+
cvalid.action do |global, options, args|
|
49
|
+
raise ArgumentError, 'Missing arguments!' if args.empty?
|
50
|
+
raise ArgumentError, 'Missing targets!' if args.size < 2
|
51
|
+
Inprovise::Controller.run(:validate, options, *args)
|
52
|
+
Inprovise::Controller.wait!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'Trigger a specific action on the specified infrastructure nodes and/or groups.'
|
57
|
+
arg_name 'ACTION NAME[ NAME[...]]'
|
58
|
+
command :trigger do |ctrigger|
|
59
|
+
|
60
|
+
ctrigger.desc 'Path to a provisioning scheme to load'
|
61
|
+
ctrigger.flag [:s,:scheme], :arg_name => 'FILE', :multiple => true, :default_value => Inprovise.default_scheme
|
62
|
+
ctrigger.flag [:c, :config], :arg_name => 'CFGKEY=CFGVAL', :multiple => true, :desc => 'Specify a configuration setting for the script execution'
|
63
|
+
|
64
|
+
ctrigger.action do |global, options, args|
|
65
|
+
raise ArgumentError, 'Missing arguments!' if args.empty?
|
66
|
+
raise ArgumentError, 'Missing targets!' if args.size < 2
|
67
|
+
Inprovise::Controller.run(:trigger, options, *args)
|
68
|
+
Inprovise::Controller.wait!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'List the available scripts. By default lists only described scripts.'
|
73
|
+
command :list do |clist|
|
74
|
+
|
75
|
+
clist.desc 'Path to a provisioning scheme to load'
|
76
|
+
clist.flag [:s,:scheme], :arg_name => 'FILE', :multiple => true, :default_value => Inprovise.default_scheme
|
77
|
+
clist.switch [:a, :all], negatable: false, :desc => 'List all scripts (with or without description)'
|
78
|
+
|
79
|
+
clist.action do |global, options, args|
|
80
|
+
Inprovise::Controller.list_scripts(options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# CLI for Inprovise
|
2
|
+
#
|
3
|
+
# Author:: Martin Corino
|
4
|
+
# License:: Distributes under the same license as Ruby
|
5
|
+
|
6
|
+
require 'gli'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class Inprovise::Cli
|
10
|
+
|
11
|
+
class << self
|
12
|
+
include GLI::App
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
program_desc 'CLI for Inprovise'
|
17
|
+
|
18
|
+
version Inprovise::VERSION
|
19
|
+
|
20
|
+
subcommand_option_handling :normal
|
21
|
+
arguments :strict
|
22
|
+
sort_help :manually
|
23
|
+
|
24
|
+
desc 'Don\'t actually run any commands on the group, just pretend.'
|
25
|
+
switch [:n,:'dry-run'], {negatable: false}
|
26
|
+
|
27
|
+
desc 'Increase verbosity, useful for debugging.'
|
28
|
+
flag [:v, :verbose], :arg_name => 'LEVEL', :default_value => 0, :type => Integer
|
29
|
+
|
30
|
+
desc 'Show exception backtraces on exit.'
|
31
|
+
switch [:x, :'show-backtrace'], {negatable: false}
|
32
|
+
|
33
|
+
desc 'Don\'t run tasks in parrallel across nodes.'
|
34
|
+
switch [:sequential], {negatable: false}
|
35
|
+
|
36
|
+
desc 'Don\'t validate and run dependencies.'
|
37
|
+
switch [:'skip-dependencies'], {negatable: false}
|
38
|
+
|
39
|
+
require_relative './cli/node'
|
40
|
+
require_relative './cli/group'
|
41
|
+
require_relative './cli/provision'
|
42
|
+
|
43
|
+
desc 'Initialize Inprovise project.'
|
44
|
+
command :init do |cinit|
|
45
|
+
cinit.action do |global,options,args|
|
46
|
+
raise RuntimeError, 'Cannot initialize existing project directory.' if File.exists?(Inprovise::INFRA_FILE)
|
47
|
+
raise RuntimeError, "Default scheme #{Inprovise.default_scheme} already exists." if File.exists?(Inprovise.default_scheme)
|
48
|
+
begin
|
49
|
+
Inprovise::Infrastructure.init(Inprovise::INFRA_FILE)
|
50
|
+
path = Inprovise::Template.new(File.join(File.dirname(__FILE__),'template','inprovise.rb.erb')).render_to_tempfile
|
51
|
+
FileUtils.mv(path, Inprovise.default_scheme)
|
52
|
+
rescue
|
53
|
+
File.delete(Inprovise::INFRA_FILE) if File.exists?(Inprovise::INFRA_FILE)
|
54
|
+
File.delete(Inprovise.default_scheme) if File.exists?(Inprovise.default_scheme)
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
pre do |global,command,options,args|
|
61
|
+
# Pre logic here
|
62
|
+
# Return true to proceed; false to abort and not call the
|
63
|
+
# chosen command
|
64
|
+
# Use skips_pre before a command to skip this block
|
65
|
+
# on that command only
|
66
|
+
Inprovise.verbosity = global[:verbose] || 0
|
67
|
+
Inprovise.show_backtrace = global[:'show-backtrace']
|
68
|
+
Inprovise.sequential = global[:sequential]
|
69
|
+
Inprovise.demonstrate = global[:demonstrate]
|
70
|
+
Inprovise.skip_dependencies = global[:'skip-dependencies']
|
71
|
+
unless command.name == :init
|
72
|
+
if File.readable?(File.join(Inprovise.root, Inprovise::RC_FILE))
|
73
|
+
Inprovise.log.local("Loading #{Inprovise::RC_FILE}") if Inprovise.verbosity > 1
|
74
|
+
load File.join(Inprovise.root, Inprovise::RC_FILE)
|
75
|
+
end
|
76
|
+
|
77
|
+
Inprovise::Infrastructure.load
|
78
|
+
end
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
post do |global,command,options,args|
|
83
|
+
# Post logic here
|
84
|
+
# Use skips_post before a command to skip this
|
85
|
+
# block on that command only
|
86
|
+
end
|
87
|
+
|
88
|
+
on_error do |exception|
|
89
|
+
# Error logic here
|
90
|
+
# return false to skip default error handling
|
91
|
+
$stderr.puts "ERROR: #{exception.message}".red
|
92
|
+
if Inprovise.show_backtrace
|
93
|
+
$stderr.puts "#{exception}\n#{exception.backtrace.join("\n")}"
|
94
|
+
end
|
95
|
+
exit 1
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.show_target(tgt, details=false)
|
99
|
+
$stdout.puts " #{tgt.to_s}"
|
100
|
+
if details
|
101
|
+
$stdout.puts " \t"+JSON.pretty_generate(tgt.config).split("\n").join("\n \t")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Command channel for Inprovise
|
2
|
+
#
|
3
|
+
# Author:: Martin Corino
|
4
|
+
# License:: Distributes under the same license as Ruby
|
5
|
+
|
6
|
+
module Inprovise::CmdChannel
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def implementations
|
11
|
+
@implementations ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_implementation
|
15
|
+
@default ||= 'ssh'
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_implementation=(impl)
|
19
|
+
@default = impl
|
20
|
+
end
|
21
|
+
|
22
|
+
def define(impl, base=::Object, &definition)
|
23
|
+
implklass = Class.new(base) do
|
24
|
+
include Inprovise::CmdChannel
|
25
|
+
end
|
26
|
+
implklass.class_eval(&definition)
|
27
|
+
implementations[impl.to_s] = implklass
|
28
|
+
implklass
|
29
|
+
end
|
30
|
+
|
31
|
+
def open(node, impl)
|
32
|
+
implementations[impl || default_implementation].new(node)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :node
|
38
|
+
|
39
|
+
def initialize(node)
|
40
|
+
@node = node
|
41
|
+
end
|
42
|
+
|
43
|
+
# session management
|
44
|
+
|
45
|
+
def close
|
46
|
+
# noop
|
47
|
+
end
|
48
|
+
|
49
|
+
# command execution (MANDATORY)
|
50
|
+
|
51
|
+
def run(command, forcelog=false)
|
52
|
+
raise RuntimeError, 'UNIMPLEMENTED'
|
53
|
+
end
|
54
|
+
|
55
|
+
# MANDATORY file management routines
|
56
|
+
|
57
|
+
def upload(from, to)
|
58
|
+
raise RuntimeError, 'UNIMPLEMENTED'
|
59
|
+
end
|
60
|
+
|
61
|
+
def download(from, to)
|
62
|
+
raise RuntimeError, 'UNIMPLEMENTED'
|
63
|
+
end
|
64
|
+
|
65
|
+
# OPTIONAL file management routines
|
66
|
+
|
67
|
+
# not recursive
|
68
|
+
# def mkdir(path)
|
69
|
+
# end
|
70
|
+
|
71
|
+
# def exists?(path)
|
72
|
+
# end
|
73
|
+
|
74
|
+
# def file?
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# def directory?
|
78
|
+
# end
|
79
|
+
|
80
|
+
# def content
|
81
|
+
# end
|
82
|
+
|
83
|
+
# def delete(path)
|
84
|
+
# end
|
85
|
+
|
86
|
+
# def permissions(path)
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# def set_permissions(path, perm)
|
90
|
+
# end
|
91
|
+
|
92
|
+
# def owner(path)
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# def set_owner(path, user, group=nil)
|
96
|
+
# end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
require_relative './channel/ssh'
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# Command helper for Inprovise
|
2
|
+
#
|
3
|
+
# Author:: Martin Corino
|
4
|
+
# License:: Distributes under the same license as Ruby
|
5
|
+
|
6
|
+
module Inprovise::CmdHelper
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def implementations
|
11
|
+
@implementations ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_implementation
|
15
|
+
@default ||= 'linux'
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_implementation=(impl)
|
19
|
+
@default = impl
|
20
|
+
end
|
21
|
+
|
22
|
+
def define(impl, base=::Object, &definition)
|
23
|
+
implklass = Class.new(base) do
|
24
|
+
include Inprovise::CmdHelper
|
25
|
+
end
|
26
|
+
implklass.class_eval(&definition)
|
27
|
+
implementations[impl.to_s] = implklass
|
28
|
+
implklass
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(node, impl)
|
32
|
+
implementations[impl || default_implementation].new(node.channel)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :channel
|
38
|
+
|
39
|
+
# default init
|
40
|
+
def initialize(channel)
|
41
|
+
@channel = channel
|
42
|
+
end
|
43
|
+
|
44
|
+
# platform properties
|
45
|
+
|
46
|
+
def admin_user
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def env_reference(varname)
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def cwd
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# *must* return previous value
|
59
|
+
def set_cwd(path)
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
# generic command execution
|
64
|
+
|
65
|
+
def run(cmd, forcelog=false)
|
66
|
+
@channel.run(cmd,forcelog)
|
67
|
+
end
|
68
|
+
|
69
|
+
# return sudo helper
|
70
|
+
def sudo
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# file management
|
75
|
+
|
76
|
+
def upload(from, to)
|
77
|
+
@channel.upload(from, to)
|
78
|
+
end
|
79
|
+
|
80
|
+
def download(from, to)
|
81
|
+
@channel.download(from, to)
|
82
|
+
end
|
83
|
+
|
84
|
+
# basic commands
|
85
|
+
|
86
|
+
def echo(arg)
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def env(var)
|
91
|
+
echo(env_reference(var))
|
92
|
+
end
|
93
|
+
|
94
|
+
def cat(path)
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
|
98
|
+
def hash_for(path)
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def mkdir(path)
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def exists?(path)
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
def file?(path)
|
111
|
+
false
|
112
|
+
end
|
113
|
+
|
114
|
+
def directory?(path)
|
115
|
+
false
|
116
|
+
end
|
117
|
+
|
118
|
+
def copy(from, to)
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
|
122
|
+
def delete(path)
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def permissions(path)
|
127
|
+
0
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_permissions(path, perm)
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
def owner(path)
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
def set_owner(path, user, group=nil)
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
def binary_exists?(bin)
|
143
|
+
false
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
require_relative './helper/linux'
|
149
|
+
require_relative './helper/cygwin'
|
150
|
+
require_relative './helper/windows'
|