lxd-common 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/lib/nexussw/lxd/driver/mixins/cli.rb +7 -1
- data/lib/nexussw/lxd/driver/mixins/helpers/wait.rb +39 -0
- data/lib/nexussw/lxd/driver/mixins/rest.rb +41 -25
- data/lib/nexussw/lxd/driver.rb +10 -38
- data/lib/nexussw/lxd/transport/mixins/cli.rb +9 -0
- data/lib/nexussw/lxd/transport/mixins/helpers/execute.rb +53 -0
- data/lib/nexussw/lxd/transport/mixins/helpers/upload_folder.rb +79 -0
- data/lib/nexussw/lxd/transport/mixins/local.rb +3 -2
- data/lib/nexussw/lxd/transport/mixins/rest.rb +13 -8
- data/lib/nexussw/lxd/transport.rb +9 -51
- data/lib/nexussw/lxd/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ca7ef26b1a5f3811c395b2c90ab29bf5f0e8127
|
4
|
+
data.tar.gz: 56e6fd7f480fd6278bb011ba1052bebcea703172
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2719010fc06f675be0ae6c8720ecb5144119f962a4be36392a4b8e9c404532f784c81a3a3ef237a761d5cb70ca2dea2b8cf3afd3c7f6a62dfce11724d56b311
|
7
|
+
data.tar.gz: ffccf9fa39e661c337be6e04145da71dda189612db57fb87e21aba68e185e97f476af06e0f5b84517b5a4547b3e89436f61d0afea5277d5e1b20e66170a938eb
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'nexussw/lxd/driver/mixins/helpers/wait'
|
2
|
+
require 'nexussw/lxd/transport/cli'
|
1
3
|
require 'tempfile'
|
2
4
|
require 'yaml'
|
3
5
|
require 'json'
|
@@ -14,6 +16,10 @@ module NexusSW
|
|
14
16
|
|
15
17
|
attr_reader :inner_transport, :driver_options
|
16
18
|
|
19
|
+
def transport_for(container_name)
|
20
|
+
Transport::CLI.new inner_transport, container_name, info: YAML.load(inner_transport.execute('lxc info').error!.stdout)
|
21
|
+
end
|
22
|
+
|
17
23
|
def create_container(container_name, container_options = {})
|
18
24
|
if container_exists? container_name
|
19
25
|
start_container container_name # Start for Parity with the below logic (`lxc launch` auto starts)
|
@@ -109,7 +115,7 @@ module NexusSW
|
|
109
115
|
false
|
110
116
|
end
|
111
117
|
|
112
|
-
include WaitMixin
|
118
|
+
include Helpers::WaitMixin
|
113
119
|
|
114
120
|
protected
|
115
121
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module NexusSW
|
2
|
+
module LXD
|
3
|
+
class Driver
|
4
|
+
module Mixins
|
5
|
+
module Helpers
|
6
|
+
module WaitMixin
|
7
|
+
def check_for_ip(driver, container_name)
|
8
|
+
cc = driver.container(container_name)
|
9
|
+
state = driver.container_state(container_name)
|
10
|
+
cc[:expanded_devices].each do |nic, data|
|
11
|
+
next unless data[:type] == 'nic'
|
12
|
+
state[:network][nic][:addresses].each do |address|
|
13
|
+
return address[:address] if address[:family] == 'inet' && address[:address] && !address[:address].empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def wait_for(container_name, what, timeout = 60)
|
20
|
+
Timeout.timeout timeout do
|
21
|
+
loop do
|
22
|
+
retval = nil
|
23
|
+
case what
|
24
|
+
when :ip
|
25
|
+
retval = check_for_ip(self, container_name)
|
26
|
+
else
|
27
|
+
raise 'unrecognized option'
|
28
|
+
end
|
29
|
+
return retval if retval
|
30
|
+
sleep 0.5
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'nexussw/lxd/driver/mixins/helpers/wait'
|
2
|
+
require 'nexussw/lxd/transport/rest'
|
1
3
|
require 'hyperkit'
|
2
4
|
|
3
5
|
module NexusSW
|
@@ -17,19 +19,25 @@ module NexusSW
|
|
17
19
|
auto_sync: true
|
18
20
|
)
|
19
21
|
@hk = inner_driver || Hyperkit::Client.new(hkoptions)
|
20
|
-
# HACK: can't otherwise get at the request timeout because sawyer is in the way
|
21
|
-
# Beware of unused function in hyperkit: reset_agent If that gets used it'll undo this timeout
|
22
|
-
# unneeded while default valued: @hk.agent.instance_variable_get(:@conn).options[:timeout] = REQUEST_TIMEOUT
|
23
22
|
end
|
24
23
|
|
25
24
|
attr_reader :hk, :rest_endpoint, :driver_options
|
26
25
|
|
26
|
+
include Helpers::WaitMixin
|
27
|
+
|
28
|
+
def server_info
|
29
|
+
@server_info ||= hk.get('/1.0')[:metadata]
|
30
|
+
end
|
31
|
+
|
32
|
+
def transport_for(container_name)
|
33
|
+
Transport::Rest.new container_name, info: server_info, connection: hk, driver_options: driver_options, rest_endpoint: rest_endpoint
|
34
|
+
end
|
35
|
+
|
27
36
|
def create_container(container_name, container_options = {})
|
28
37
|
if container_exists?(container_name)
|
29
38
|
start_container container_name # Start the container for Parity with the CLI
|
30
39
|
return container_name
|
31
40
|
end
|
32
|
-
# we'll break this apart and time it out for those with slow net (and this was my 3 minute stress test case with good net)
|
33
41
|
# parity note: CLI will run indefinitely rather than timeout hence the 0 timeout
|
34
42
|
retry_forever do
|
35
43
|
@hk.create_container(container_name, container_options.merge(sync: false))
|
@@ -48,25 +56,29 @@ module NexusSW
|
|
48
56
|
|
49
57
|
def stop_container(container_id, options = {})
|
50
58
|
return if container_status(container_id) == 'stopped'
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
if options[:force]
|
60
|
+
@hk.stop_container(container_id, force: true)
|
61
|
+
else
|
62
|
+
last_id = nil
|
63
|
+
use_last = false
|
64
|
+
LXD.with_timeout_and_retries({ timeout: 0 }.merge(options)) do # timeout: 0 to enable retry functionality
|
65
|
+
return if container_status(container_id) == 'stopped'
|
66
|
+
begin
|
67
|
+
unless use_last
|
68
|
+
# Keep resubmitting until the server complains (Stops will be ignored/hang if init is not yet listening for SIGPWR i.e. recently started)
|
69
|
+
begin
|
70
|
+
last_id = @hk.stop_container(container_id, sync: false)[:id]
|
71
|
+
rescue Hyperkit::BadRequest # Happens if a stop command has previously been accepted as well as other reasons. handle that on next line
|
72
|
+
# if we have a last_id then a prior stop command has successfully initiated so we'll just wait on that one
|
73
|
+
raise unless last_id # rubocop:disable Metrics/BlockNesting
|
74
|
+
use_last = true
|
75
|
+
end
|
64
76
|
end
|
77
|
+
@hk.wait_for_operation last_id # , options[:retry_interval]
|
78
|
+
rescue Faraday::TimeoutError => e
|
79
|
+
return if container_status(container_id) == 'stopped'
|
80
|
+
raise Timeout::Retry.new e # if options[:retry_interval] # rubocop:disable Style/RaiseArgs
|
65
81
|
end
|
66
|
-
@hk.wait_for_operation last_id # , options[:retry_interval]
|
67
|
-
rescue Faraday::TimeoutError => e
|
68
|
-
return if container_status(container_id) == 'stopped'
|
69
|
-
raise Timeout::Retry.new e # if options[:retry_interval] # rubocop:disable Style/RaiseArgs
|
70
82
|
end
|
71
83
|
end
|
72
84
|
wait_for_status container_id, 'stopped'
|
@@ -74,8 +86,14 @@ module NexusSW
|
|
74
86
|
|
75
87
|
def delete_container(container_id)
|
76
88
|
return unless container_exists? container_id
|
77
|
-
stop_container container_id,
|
78
|
-
|
89
|
+
stop_container container_id, force: true
|
90
|
+
|
91
|
+
# overcome a race condition where the host is busy doing 'something' async causing the delete command to pop an error
|
92
|
+
# https://github.com/lxc/lxd/issues/4063
|
93
|
+
# sleep 1
|
94
|
+
|
95
|
+
id = @hk.delete_container(container_id, sync: false)[:id]
|
96
|
+
@hk.wait_for_operation id
|
79
97
|
end
|
80
98
|
|
81
99
|
def container_status(container_id)
|
@@ -98,8 +116,6 @@ module NexusSW
|
|
98
116
|
false
|
99
117
|
end
|
100
118
|
|
101
|
-
include WaitMixin
|
102
|
-
|
103
119
|
protected
|
104
120
|
|
105
121
|
def wait_for_status(container_id, newstatus)
|
data/lib/nexussw/lxd/driver.rb
CHANGED
@@ -22,67 +22,39 @@ module NexusSW
|
|
22
22
|
}.freeze
|
23
23
|
|
24
24
|
def create_container(_container_name, _container_options)
|
25
|
-
raise
|
25
|
+
raise "#{self.class}#create_container not implemented"
|
26
26
|
end
|
27
27
|
|
28
28
|
def start_container(_container_id)
|
29
|
-
raise
|
29
|
+
raise "#{self.class}#start_container not implemented"
|
30
30
|
end
|
31
31
|
|
32
32
|
def stop_container(_container_id, _options = {})
|
33
|
-
raise
|
33
|
+
raise "#{self.class}#stop_container not implemented"
|
34
34
|
end
|
35
35
|
|
36
36
|
def delete_container(_container_id)
|
37
|
-
raise
|
37
|
+
raise "#{self.class}#delete_container not implemented"
|
38
38
|
end
|
39
39
|
|
40
40
|
def container_status(_container_id)
|
41
|
-
raise
|
42
|
-
end
|
43
|
-
|
44
|
-
def ensure_profiles(_profiles)
|
45
|
-
raise 'NexusSW::LXD::Driver.ensure_profiles not implemented'
|
41
|
+
raise "#{self.class}#container_status not implemented"
|
46
42
|
end
|
47
43
|
|
48
44
|
def container(_container_id)
|
49
|
-
raise
|
45
|
+
raise "#{self.class}#container not implemented"
|
50
46
|
end
|
51
47
|
|
52
48
|
def container_state(_container_id)
|
53
|
-
raise
|
49
|
+
raise "#{self.class}#container_state not implemented"
|
54
50
|
end
|
55
51
|
|
56
52
|
def wait_for(_what)
|
57
|
-
raise
|
53
|
+
raise "#{self.class}#wait_for not implemented"
|
58
54
|
end
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
cc = driver.container(container_name)
|
63
|
-
state = driver.container_state(container_name)
|
64
|
-
cc[:expanded_devices].each do |nic, data|
|
65
|
-
next unless data[:type] == 'nic'
|
66
|
-
state[:network][nic][:addresses].each do |address|
|
67
|
-
return address[:address] if address[:family] == 'inet' && address[:address] && !address[:address].empty?
|
68
|
-
end
|
69
|
-
end
|
70
|
-
nil
|
71
|
-
end
|
72
|
-
|
73
|
-
def wait_for(container_name, what, timeout = 60)
|
74
|
-
Timeout.timeout timeout do
|
75
|
-
loop do
|
76
|
-
retval = nil
|
77
|
-
case what
|
78
|
-
when :ip
|
79
|
-
retval = check_for_ip(self, container_name)
|
80
|
-
end
|
81
|
-
return retval if retval
|
82
|
-
sleep 0.5
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
56
|
+
def transport_for(_container_name)
|
57
|
+
raise "#{self.class}#transport_for not implemented"
|
86
58
|
end
|
87
59
|
end
|
88
60
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'nexussw/lxd/transport/mixins/local'
|
2
|
+
require 'nexussw/lxd/transport/mixins/helpers/upload_folder'
|
2
3
|
require 'tempfile'
|
3
4
|
require 'pp'
|
4
5
|
|
@@ -13,8 +14,11 @@ module NexusSW
|
|
13
14
|
@inner_transport = remote_transport
|
14
15
|
@punt = !inner_transport.is_a?(::NexusSW::LXD::Transport::Mixins::Local)
|
15
16
|
end
|
17
|
+
|
16
18
|
attr_reader :inner_transport, :punt, :container_name, :config
|
17
19
|
|
20
|
+
include Helpers::UploadFolder
|
21
|
+
|
18
22
|
def execute(command, options = {})
|
19
23
|
mycommand = command.is_a?(Array) ? command.join(' ') : command
|
20
24
|
subcommand = options[:subcommand] || "exec #{container_name} --"
|
@@ -62,6 +66,11 @@ module NexusSW
|
|
62
66
|
inner_transport.execute("rm -rf #{tfile}", capture: false) if tfile
|
63
67
|
end
|
64
68
|
|
69
|
+
def upload_folder(local_path, path)
|
70
|
+
return super unless config[:info] && config[:info][:api_extensions] && config[:info][:api_extensions].include?('directory_manipulation')
|
71
|
+
execute("-r #{localname} #{container_name}#{path}", subcommand: 'file push', capture: false).error!
|
72
|
+
end
|
73
|
+
|
65
74
|
def add_remote(host_name)
|
66
75
|
execute("add #{host_name} --accept-certificate", subcommand: 'remote').error! unless remote? host_name
|
67
76
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module NexusSW
|
2
|
+
module LXD
|
3
|
+
class Transport
|
4
|
+
module Mixins
|
5
|
+
module Helpers
|
6
|
+
module ExecuteMixin
|
7
|
+
class ExecuteResult
|
8
|
+
def initialize(command, options, exitstatus)
|
9
|
+
@command = command
|
10
|
+
@options = options || {}
|
11
|
+
@exitstatus = exitstatus
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :exitstatus, :options, :command
|
15
|
+
|
16
|
+
def stdout
|
17
|
+
options[:capture_options][:stdout] if options.key? :capture_options
|
18
|
+
end
|
19
|
+
|
20
|
+
def stderr
|
21
|
+
options[:capture_options][:stderr] if options.key? :capture_options
|
22
|
+
end
|
23
|
+
|
24
|
+
def error!
|
25
|
+
return self if exitstatus == 0
|
26
|
+
msg = "Error: '#{command}' failed with exit code #{exitstatus}.\n"
|
27
|
+
msg += "STDOUT: #{stdout}" if stdout && !stdout.empty?
|
28
|
+
msg += "STDERR: #{stderr}" if stderr && !stderr.empty?
|
29
|
+
raise msg
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute(command, options = {}, &block)
|
34
|
+
options ||= {}
|
35
|
+
return execute_chunked(command, options) if options[:capture] == false && !block_given?
|
36
|
+
|
37
|
+
capture_options = { stdout: '', stderr: '' }
|
38
|
+
capture_options[:capture] = block if block_given?
|
39
|
+
capture_options[:capture] ||= options[:capture] if options[:capture].respond_to? :call
|
40
|
+
# capture_options[:capture] ||= options[:stream] if options[:stream].respond_to? :call
|
41
|
+
capture_options[:capture] ||= proc do |stdout_chunk, stderr_chunk|
|
42
|
+
capture_options[:stdout] += stdout_chunk if stdout_chunk
|
43
|
+
capture_options[:stderr] += stderr_chunk if stderr_chunk
|
44
|
+
end
|
45
|
+
|
46
|
+
execute_chunked(command, options.merge(capture_options: capture_options), &capture_options[:capture])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module NexusSW
|
2
|
+
module LXD
|
3
|
+
class Transport
|
4
|
+
module Mixins
|
5
|
+
module Helpers
|
6
|
+
module UploadFolder
|
7
|
+
def upload_folder(local_path, path)
|
8
|
+
upload_using_tarball(local_path, path) || upload_files_individually(local_path, path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def upload_files_individually(local_path, path)
|
12
|
+
Dir.entries(local_path).map { |f| (f == '.' || f == '..') ? nil : File.join(local_path, f) }.compact.each do |f|
|
13
|
+
dest = File.join(path, File.basename(local_path))
|
14
|
+
upload_files_individually f, dest if File.directory? f
|
15
|
+
upload_file f, File.join(dest, File.basename(f)) if File.file? f
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def upload_using_tarball(local_path, path)
|
20
|
+
return false unless can_archive?
|
21
|
+
# TODO: should I return false upon error? i.e. retry with individual file uploads if this fails?
|
22
|
+
# lets see how this does in the wild before deciding
|
23
|
+
flag, ext = compression
|
24
|
+
begin
|
25
|
+
tfile = Tempfile.new(container_name)
|
26
|
+
tfile.close
|
27
|
+
`tar -c#{flag}f #{tfile.path} -C #{File.dirname local_path} ./#{File.basename local_path}`
|
28
|
+
# on that above note we'll do this at least
|
29
|
+
# raise "Unable to create archive #{tfile.path}" if File.zero? tfile.path
|
30
|
+
if File.zero? tfile.path
|
31
|
+
@can_archive = false
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
fname = '/tmp/' + File.basename(tfile.path) + ".tar#{ext}"
|
35
|
+
upload_file tfile.path, fname
|
36
|
+
# TODO: serious: make sure the tar extract does an overwrite of existing files
|
37
|
+
# multiple converge support as well as CI cycle/dev updated files get updated instead of .1 suffixed (?)
|
38
|
+
# I think I need a flag (it's been a while)
|
39
|
+
execute("bash -c 'mkdir -p #{path} && cd #{path} && tar -xf #{fname} && rm -rf #{fname}'", capture: false).error!
|
40
|
+
ensure
|
41
|
+
tfile.unlink
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def can_archive?
|
48
|
+
return false if @can_archive == false
|
49
|
+
@can_archive ||= begin
|
50
|
+
# I don't want to code tarball logic into the mock transport
|
51
|
+
return false if respond_to?(:hk) && hk.respond_to?(:mock)
|
52
|
+
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:mock)
|
53
|
+
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:inner_transport) && inner_transport.inner_transport.respond_to?(:mock)
|
54
|
+
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:hk) && inner_transport.hk.respond_to?(:mock)
|
55
|
+
`tar --version`
|
56
|
+
true
|
57
|
+
rescue
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# gzip(-z) or bzip2(-j) (these are the only 2 on trusty atm)
|
63
|
+
def compression
|
64
|
+
@compression ||= begin
|
65
|
+
which = execute('bash -c "which gzip || which bzip2 || true"').stdout.strip
|
66
|
+
which = File.basename(which) if which
|
67
|
+
case which
|
68
|
+
when 'gzip' then ['z', '.gz']
|
69
|
+
when 'bzip2' then ['j', '.bzip2']
|
70
|
+
else ['', '']
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'nexussw/lxd/transport/mixins/helpers/execute'
|
1
2
|
require 'open3'
|
2
3
|
require 'nio/websocket'
|
3
4
|
|
@@ -12,7 +13,7 @@ module NexusSW
|
|
12
13
|
|
13
14
|
attr_reader :config
|
14
15
|
|
15
|
-
include ExecuteMixin
|
16
|
+
include Helpers::ExecuteMixin
|
16
17
|
|
17
18
|
def execute_chunked(command, options)
|
18
19
|
NIO::WebSocket::Reactor.start
|
@@ -36,7 +37,7 @@ module NexusSW
|
|
36
37
|
end
|
37
38
|
th.join
|
38
39
|
loop do
|
39
|
-
return
|
40
|
+
return Helpers::ExecuteMixin::ExecuteResult.new(command, options, th.value.exitstatus) if th.value.exited? && mon_out && mon_err && mon_out.closed? && mon_err.closed?
|
40
41
|
Thread.pass
|
41
42
|
end
|
42
43
|
end
|
@@ -1,22 +1,26 @@
|
|
1
|
+
require 'nexussw/lxd/transport/mixins/helpers/execute'
|
2
|
+
require 'nexussw/lxd/transport/mixins/helpers/upload_folder'
|
1
3
|
require 'nio/websocket'
|
4
|
+
require 'tempfile'
|
2
5
|
|
3
6
|
module NexusSW
|
4
7
|
module LXD
|
5
8
|
class Transport
|
6
9
|
module Mixins
|
7
10
|
module Rest
|
8
|
-
def initialize(
|
11
|
+
def initialize(container_name, config = {})
|
9
12
|
@container_name = container_name
|
10
13
|
@config = config
|
11
|
-
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@hk
|
14
|
+
@rest_endpoint = config[:rest_endpoint]
|
15
|
+
@driver_options = config[:driver_options]
|
16
|
+
@hk = config[:connection]
|
17
|
+
raise 'The rest transport requires the following keys: { :connection, :driver_options, :rest_endpoint }' unless @rest_endpoint && @hk && @driver_options
|
15
18
|
end
|
16
19
|
|
17
20
|
attr_reader :hk, :rest_endpoint, :container_name, :config
|
18
21
|
|
19
|
-
include ExecuteMixin
|
22
|
+
include Helpers::ExecuteMixin
|
23
|
+
include Helpers::UploadFolder
|
20
24
|
|
21
25
|
def execute_chunked(command, options = {}, &block)
|
22
26
|
opid = nil
|
@@ -32,7 +36,7 @@ module NexusSW
|
|
32
36
|
begin
|
33
37
|
retval = hk.wait_for_operation opid
|
34
38
|
backchannel.exit if backchannel.respond_to? :exit
|
35
|
-
return
|
39
|
+
return Helpers::ExecuteMixin::ExecuteResult.new command, options, retval[:metadata][:return].to_i
|
36
40
|
rescue Faraday::TimeoutError => e
|
37
41
|
raise Timeout::Retry.new e # rubocop:disable Style/RaiseArgs
|
38
42
|
end
|
@@ -54,7 +58,8 @@ module NexusSW
|
|
54
58
|
end
|
55
59
|
|
56
60
|
def upload_file(local_path, path)
|
57
|
-
hk.push_file
|
61
|
+
# return hk.push_file(local_path, container_name, path)
|
62
|
+
write_file(path, IO.binread(local_path))
|
58
63
|
end
|
59
64
|
|
60
65
|
protected
|
@@ -3,71 +3,29 @@ require 'nexussw/lxd'
|
|
3
3
|
module NexusSW
|
4
4
|
module LXD
|
5
5
|
class Transport
|
6
|
-
class LXDExecuteResult
|
7
|
-
def initialize(command, options, exitstatus)
|
8
|
-
@command = command
|
9
|
-
@options = options || {}
|
10
|
-
@exitstatus = exitstatus
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_reader :exitstatus, :options, :command
|
14
|
-
|
15
|
-
def stdout
|
16
|
-
options[:capture_options][:stdout] if options.key? :capture_options
|
17
|
-
end
|
18
|
-
|
19
|
-
def stderr
|
20
|
-
options[:capture_options][:stderr] if options.key? :capture_options
|
21
|
-
end
|
22
|
-
|
23
|
-
def error!
|
24
|
-
return self if exitstatus == 0
|
25
|
-
msg = "Error: '#{command}' failed with exit code #{exitstatus}.\n"
|
26
|
-
msg += "STDOUT: #{stdout}" if stdout && !stdout.empty?
|
27
|
-
msg += "STDERR: #{stderr}" if stderr && !stderr.empty?
|
28
|
-
raise msg
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
module ExecuteMixin
|
33
|
-
def execute(command, options = {}, &block)
|
34
|
-
options ||= {}
|
35
|
-
return execute_chunked(command, options) if options[:capture] == false && !block_given?
|
36
|
-
|
37
|
-
capture_options = { stdout: '', stderr: '' }
|
38
|
-
capture_options[:capture] = block if block_given?
|
39
|
-
capture_options[:capture] ||= options[:capture] if options[:capture].respond_to? :call
|
40
|
-
# capture_options[:capture] ||= options[:stream] if options[:stream].respond_to? :call
|
41
|
-
capture_options[:capture] ||= proc do |stdout_chunk, stderr_chunk|
|
42
|
-
capture_options[:stdout] += stdout_chunk if stdout_chunk
|
43
|
-
capture_options[:stderr] += stderr_chunk if stderr_chunk
|
44
|
-
end
|
45
|
-
|
46
|
-
execute_chunked(command, options.merge(capture_options: capture_options), &capture_options[:capture])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
6
|
def execute(_command, _options = {})
|
51
|
-
raise
|
7
|
+
raise "#{self.class}#execute not implemented"
|
52
8
|
end
|
53
9
|
|
54
10
|
def read_file(_path)
|
55
|
-
raise
|
11
|
+
raise "#{self.class}#read_file not implemented"
|
56
12
|
end
|
57
13
|
|
58
14
|
def write_file(_path, _content)
|
59
|
-
raise
|
15
|
+
raise "#{self.class}#write_file not implemented"
|
60
16
|
end
|
61
17
|
|
62
18
|
def download_file(_path, _local_path)
|
63
|
-
raise
|
19
|
+
raise "#{self.class}#download_file not implemented"
|
64
20
|
end
|
65
21
|
|
66
22
|
def upload_file(_local_path, _path)
|
67
|
-
raise
|
23
|
+
raise "#{self.class}#upload_file not implemented"
|
24
|
+
end
|
25
|
+
|
26
|
+
def upload_folder(_local_path, _path)
|
27
|
+
raise "#{self.class}#upload_folder not implemented"
|
68
28
|
end
|
69
|
-
# protected
|
70
|
-
# def execute_chunked(_command, _options = {})
|
71
29
|
end
|
72
30
|
end
|
73
31
|
end
|
data/lib/nexussw/lxd/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lxd-common
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Zachariasen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hyperkit
|
@@ -115,12 +115,15 @@ files:
|
|
115
115
|
- lib/nexussw/lxd/driver.rb
|
116
116
|
- lib/nexussw/lxd/driver/cli.rb
|
117
117
|
- lib/nexussw/lxd/driver/mixins/cli.rb
|
118
|
+
- lib/nexussw/lxd/driver/mixins/helpers/wait.rb
|
118
119
|
- lib/nexussw/lxd/driver/mixins/rest.rb
|
119
120
|
- lib/nexussw/lxd/driver/rest.rb
|
120
121
|
- lib/nexussw/lxd/transport.rb
|
121
122
|
- lib/nexussw/lxd/transport/cli.rb
|
122
123
|
- lib/nexussw/lxd/transport/local.rb
|
123
124
|
- lib/nexussw/lxd/transport/mixins/cli.rb
|
125
|
+
- lib/nexussw/lxd/transport/mixins/helpers/execute.rb
|
126
|
+
- lib/nexussw/lxd/transport/mixins/helpers/upload_folder.rb
|
124
127
|
- lib/nexussw/lxd/transport/mixins/local.rb
|
125
128
|
- lib/nexussw/lxd/transport/mixins/rest.rb
|
126
129
|
- lib/nexussw/lxd/transport/rest.rb
|