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