lxd-common 0.8.1 → 0.9.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/Gemfile +3 -4
- data/Rakefile +10 -9
- data/lib/nexussw/lxd/rest_api.rb +1 -3
- data/lib/nexussw/lxd/rest_api/connection.rb +9 -7
- data/lib/nexussw/lxd/transport.rb +20 -0
- data/lib/nexussw/lxd/transport/mixins/cli.rb +14 -16
- data/lib/nexussw/lxd/transport/mixins/helpers/{upload_folder.rb → folder_txfr.rb} +43 -29
- data/lib/nexussw/lxd/transport/mixins/rest.rb +2 -2
- data/lib/nexussw/lxd/version.rb +1 -1
- data/lxd-common.gemspec +1 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 032aa7f8a09b027c6254b6e42c5c36328a0325804780ed7a6db13ec4f905d197
|
4
|
+
data.tar.gz: b52cf26ede270ceb806dfd552d97a6ef0b5693e10a98943d2d6f4e708ed0ca2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae77de9d2025c2cdba5cd71740fec1766486520844b29f4dc11ebb786f69da90310033c2c722bdfb0db0234c19737b4c7c868cc3000b05a824caf12500ba9f15
|
7
|
+
data.tar.gz: 99dbeed1e5731e1050197a244c16c91215ba41b11c78d555d2ed16cb368b1cde11ff4f63975b6aedb83e38bb345df66c41f0b88fdd3e58687e63effb69868097
|
data/Gemfile
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
|
4
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
data/Rakefile
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
RSpec::Core::RakeTask.new(:mock) do |task|
|
7
|
+
task.pattern = 'spec/**{,/*/**}/*_mock.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
task default: :spec
|
data/lib/nexussw/lxd/rest_api.rb
CHANGED
@@ -35,8 +35,8 @@ module NexusSW
|
|
35
35
|
url: baseurl,
|
36
36
|
ssl: {
|
37
37
|
verify: verify_ssl,
|
38
|
-
client_cert:
|
39
|
-
client_key:
|
38
|
+
client_cert: client_cert,
|
39
|
+
client_key: client_key,
|
40
40
|
},
|
41
41
|
}
|
42
42
|
|
@@ -51,12 +51,12 @@ module NexusSW
|
|
51
51
|
api_options[:ssl] || {}
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
File.read(ssl_opts[:client_cert] || "#{ENV['HOME']}/.config/lxc/client.crt")
|
54
|
+
def client_cert
|
55
|
+
@client_cert ||= OpenSSL::X509::Certificate.new(File.read(ssl_opts[:client_cert] || "#{ENV['HOME']}/.config/lxc/client.crt"))
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
File.read(ssl_opts[:client_key] || "#{ENV['HOME']}/.config/lxc/client.key")
|
58
|
+
def client_key
|
59
|
+
@client_key ||= OpenSSL::PKey::RSA.new(File.read(ssl_opts[:client_key] || "#{ENV['HOME']}/.config/lxc/client.key"))
|
60
60
|
end
|
61
61
|
|
62
62
|
def verify_ssl
|
@@ -69,6 +69,7 @@ module NexusSW
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def send_request(verb, relative_url, content = nil)
|
72
|
+
fileop = false
|
72
73
|
response = connection.send(verb) do |req|
|
73
74
|
req.url relative_url
|
74
75
|
if content.is_a? Hash
|
@@ -77,6 +78,7 @@ module NexusSW
|
|
77
78
|
elsif content # Only upon file upload at this time
|
78
79
|
yield req if block_given?
|
79
80
|
req.body = content.to_s
|
81
|
+
fileop = true
|
80
82
|
end
|
81
83
|
end
|
82
84
|
if response.status >= 400
|
@@ -87,7 +89,7 @@ module NexusSW
|
|
87
89
|
else raise RestAPI::Error, "Error #{err['error_code']}: #{err['error']}"
|
88
90
|
end
|
89
91
|
end
|
90
|
-
block_given? ? yield(response) : parse_response(response)
|
92
|
+
block_given? && !fileop ? yield(response) : parse_response(response)
|
91
93
|
end
|
92
94
|
end
|
93
95
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'nexussw/lxd'
|
2
|
+
require 'tempfile'
|
2
3
|
|
3
4
|
module NexusSW
|
4
5
|
module LXD
|
@@ -23,6 +24,10 @@ module NexusSW
|
|
23
24
|
raise "#{self.class}#download_file not implemented"
|
24
25
|
end
|
25
26
|
|
27
|
+
def download_folder(_path, _local_path)
|
28
|
+
raise "#{self.class}#download_folder not implemented"
|
29
|
+
end
|
30
|
+
|
26
31
|
def upload_file(_local_path, _path, _options = {})
|
27
32
|
raise "#{self.class}#upload_file not implemented"
|
28
33
|
end
|
@@ -30,6 +35,21 @@ module NexusSW
|
|
30
35
|
def upload_folder(_local_path, _path, _options = {})
|
31
36
|
raise "#{self.class}#upload_folder not implemented"
|
32
37
|
end
|
38
|
+
|
39
|
+
# kludge for windows environment
|
40
|
+
def self.remote_tempname(basename)
|
41
|
+
tfile = Tempfile.new(basename)
|
42
|
+
"/tmp/#{File.basename tfile.path}"
|
43
|
+
ensure
|
44
|
+
tfile.unlink
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.local_tempdir
|
48
|
+
return ENV['TEMP'] unless !ENV['TEMP'] || ENV['TEMP'].empty?
|
49
|
+
return ENV['TMP'] unless !ENV['TMP'] || ENV['TMP'].empty?
|
50
|
+
return ENV['TMPDIR'] unless !ENV['TMPDIR'] || ENV['TMPDIR'].empty?
|
51
|
+
'/tmp'
|
52
|
+
end
|
33
53
|
end
|
34
54
|
end
|
35
55
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'nexussw/lxd/transport/mixins/local'
|
2
2
|
require 'nexussw/lxd/transport/mixins/helpers/users'
|
3
|
-
require 'nexussw/lxd/transport/mixins/helpers/
|
3
|
+
require 'nexussw/lxd/transport/mixins/helpers/folder_txfr'
|
4
4
|
require 'tempfile'
|
5
5
|
require 'shellwords'
|
6
6
|
|
@@ -18,7 +18,7 @@ module NexusSW
|
|
18
18
|
|
19
19
|
attr_reader :inner_transport, :punt, :container_name, :config
|
20
20
|
|
21
|
-
include Helpers::
|
21
|
+
include Helpers::FolderTxfr
|
22
22
|
include Helpers::UsersMixin
|
23
23
|
|
24
24
|
def execute(command, options = {}, &block)
|
@@ -33,7 +33,7 @@ module NexusSW
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def read_file(path)
|
36
|
-
tfile =
|
36
|
+
tfile = Transport.remote_tempname(container_name)
|
37
37
|
retval = execute("#{@container_name}#{path} #{tfile}", subcommand: 'file pull', capture: false)
|
38
38
|
# return '' if retval.exitstatus == 1
|
39
39
|
retval.error!
|
@@ -45,7 +45,7 @@ module NexusSW
|
|
45
45
|
def write_file(path, content, options = {})
|
46
46
|
perms = file_perms(options)
|
47
47
|
|
48
|
-
tfile =
|
48
|
+
tfile = Transport.remote_tempname(container_name)
|
49
49
|
inner_transport.write_file tfile, content
|
50
50
|
execute("#{tfile} #{container_name}#{path}", subcommand: "file push#{perms}", capture: false).error!
|
51
51
|
ensure
|
@@ -53,9 +53,9 @@ module NexusSW
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def download_file(path, local_path)
|
56
|
-
tfile =
|
56
|
+
tfile = Transport.remote_tempname(container_name) if punt
|
57
57
|
localname = tfile || local_path
|
58
|
-
execute("#{container_name}#{path} #{localname}", subcommand: 'file pull'
|
58
|
+
execute("#{container_name}#{path} #{localname}", subcommand: 'file pull').error!
|
59
59
|
inner_transport.download_file tfile, local_path if tfile
|
60
60
|
ensure
|
61
61
|
inner_transport.execute("rm -rf #{tfile}", capture: false) if tfile
|
@@ -64,10 +64,10 @@ module NexusSW
|
|
64
64
|
def upload_file(local_path, path, options = {})
|
65
65
|
perms = file_perms(options)
|
66
66
|
|
67
|
-
tfile =
|
67
|
+
tfile = Transport.remote_tempname(container_name) if punt
|
68
68
|
localname = tfile || local_path
|
69
69
|
inner_transport.upload_file local_path, tfile if tfile
|
70
|
-
execute("#{localname} #{container_name}#{path}", subcommand: "file push#{perms}"
|
70
|
+
execute("#{localname} #{container_name}#{path}", subcommand: "file push#{perms}").error!
|
71
71
|
ensure
|
72
72
|
inner_transport.execute("rm -rf #{tfile}", capture: false) if tfile
|
73
73
|
end
|
@@ -79,6 +79,12 @@ module NexusSW
|
|
79
79
|
execute("-r #{local_path} #{container_name}#{path}", subcommand: "file push#{perms}", capture: false).error!
|
80
80
|
end
|
81
81
|
|
82
|
+
def download_folder(path, local_path)
|
83
|
+
return super unless config[:info] && config[:info]['api_extensions'] && config[:info]['api_extensions'].include?('directory_manipulation')
|
84
|
+
|
85
|
+
execute("-r #{container_name}#{path} #{local_path}", subcommand: 'file pull', capture: false).error!
|
86
|
+
end
|
87
|
+
|
82
88
|
def add_remote(host_name)
|
83
89
|
execute("add #{host_name} --accept-certificate", subcommand: 'remote').error! unless remote? host_name
|
84
90
|
end
|
@@ -101,14 +107,6 @@ module NexusSW
|
|
101
107
|
|
102
108
|
private
|
103
109
|
|
104
|
-
# kludge for windows environment
|
105
|
-
def inner_mktmp
|
106
|
-
tfile = Tempfile.new(container_name)
|
107
|
-
"/tmp/#{File.basename tfile.path}"
|
108
|
-
ensure
|
109
|
-
tfile.unlink
|
110
|
-
end
|
111
|
-
|
112
110
|
def file_perms(options = {})
|
113
111
|
perms = ''
|
114
112
|
perms += " --uid=#{options[:uid] || uid || 0}"
|
@@ -1,41 +1,69 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'archive/tar/minitar'
|
3
|
+
|
1
4
|
module NexusSW
|
2
5
|
module LXD
|
3
6
|
class Transport
|
4
7
|
module Mixins
|
5
8
|
module Helpers
|
6
|
-
module
|
9
|
+
module FolderTxfr
|
7
10
|
def upload_folder(local_path, path, options = {})
|
8
11
|
upload_using_tarball(local_path, path, options) || upload_files_individually(local_path, path, options)
|
9
12
|
end
|
10
13
|
|
14
|
+
def download_folder(path, local_path)
|
15
|
+
download_using_tarball(path, local_path) || download_files_individually(path, local_path)
|
16
|
+
end
|
17
|
+
|
11
18
|
def upload_files_individually(local_path, path, options = {})
|
19
|
+
dest = File.join(path, File.basename(local_path))
|
20
|
+
execute('mkdir -p ' + dest).error! # for parity with tarball extract
|
12
21
|
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
22
|
upload_files_individually f, dest, options if File.directory? f
|
15
23
|
upload_file f, File.join(dest, File.basename(f)), options if File.file? f
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
27
|
+
def download_files_individually(path, local_path)
|
28
|
+
dest = File.join(local_path, File.basename(path))
|
29
|
+
execute("bash -c 'cd #{path} && find -type d'").error!.stdout.each_line do |line|
|
30
|
+
newdir = line.strip.sub(/^\./, dest)
|
31
|
+
Dir.mkdir newdir unless Dir.exist? newdir
|
32
|
+
end
|
33
|
+
execute("bash -c 'cd #{path} && find ! -type d'").error!.stdout.each_line do |line|
|
34
|
+
download_file line.strip.sub(/^\./, path), line.strip.sub(/^\./, dest)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# gzip(-z) or bzip2(-j) (these are the only 2 on trusty atm)
|
39
|
+
def download_using_tarball(path, local_path)
|
40
|
+
return false unless can_archive?
|
41
|
+
tfile = Transport.remote_tempname(container_name)
|
42
|
+
tarball_name = File.join Transport.local_tempdir, File.basename(tfile) + '.tgz'
|
43
|
+
execute("tar -czf #{tfile} -C #{File.dirname path} #{File.basename path}").error!
|
44
|
+
|
45
|
+
download_file tfile, tarball_name
|
46
|
+
|
47
|
+
Archive::Tar::Minitar.unpack Zlib::GzipReader.new(File.open(tarball_name, 'rb')), local_path
|
48
|
+
ensure
|
49
|
+
if tarball_name
|
50
|
+
File.delete tarball_name if File.exist? tarball_name
|
51
|
+
execute "rm -rf #{tfile}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
19
55
|
def upload_using_tarball(local_path, path, options = {})
|
20
56
|
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
57
|
begin
|
25
58
|
tfile = Tempfile.new(container_name)
|
26
59
|
tfile.close
|
27
|
-
|
28
|
-
|
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
|
60
|
+
Dir.chdir File.dirname(local_path) do
|
61
|
+
Archive::Tar::Minitar.pack File.basename(local_path), Zlib::GzipWriter.new(File.open(tfile.path, 'wb'))
|
33
62
|
end
|
34
|
-
|
63
|
+
# `tar -c#{flag}f #{tfile.path} -C #{File.dirname local_path} ./#{File.basename local_path}`
|
64
|
+
fname = '/tmp/' + File.basename(tfile.path) + '.tgz'
|
35
65
|
upload_file tfile.path, fname, options
|
36
|
-
|
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)
|
66
|
+
|
39
67
|
myuid = options[:uid] || uid || (0 if is_a?(Mixins::CLI))
|
40
68
|
mygid = options[:gid] || gid || (0 if is_a?(Mixins::CLI))
|
41
69
|
mymode = options[:file_mode] || file_mode
|
@@ -57,25 +85,11 @@ module NexusSW
|
|
57
85
|
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:mock)
|
58
86
|
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:inner_transport) && inner_transport.inner_transport.respond_to?(:mock)
|
59
87
|
return false if respond_to?(:inner_transport) && inner_transport.respond_to?(:api) && inner_transport.api.respond_to?(:mock)
|
60
|
-
`tar --version`
|
61
88
|
true
|
62
89
|
rescue
|
63
90
|
false
|
64
91
|
end
|
65
92
|
end
|
66
|
-
|
67
|
-
# gzip(-z) or bzip2(-j) (these are the only 2 on trusty atm)
|
68
|
-
def compression
|
69
|
-
@compression ||= begin
|
70
|
-
which = execute('bash -c "which gzip || which bzip2 || true"').stdout.strip
|
71
|
-
which = File.basename(which) if which
|
72
|
-
case which
|
73
|
-
when 'gzip' then ['z', '.gz']
|
74
|
-
when 'bzip2' then ['j', '.bzip2']
|
75
|
-
else ['', '']
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
93
|
end
|
80
94
|
end
|
81
95
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'nexussw/lxd/transport/mixins/helpers/execute'
|
2
2
|
require 'nexussw/lxd/transport/mixins/helpers/users'
|
3
|
-
require 'nexussw/lxd/transport/mixins/helpers/
|
3
|
+
require 'nexussw/lxd/transport/mixins/helpers/folder_txfr'
|
4
4
|
require 'nio/websocket'
|
5
5
|
require 'tempfile'
|
6
6
|
require 'json'
|
@@ -23,7 +23,7 @@ module NexusSW
|
|
23
23
|
attr_reader :api, :rest_endpoint, :container_name, :config
|
24
24
|
|
25
25
|
include Helpers::ExecuteMixin
|
26
|
-
include Helpers::
|
26
|
+
include Helpers::FolderTxfr
|
27
27
|
include Helpers::UsersMixin
|
28
28
|
|
29
29
|
class StdinStub
|
data/lib/nexussw/lxd/version.rb
CHANGED
data/lxd-common.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'faraday', '~> 0.13'
|
23
23
|
spec.add_dependency 'nio4r-websocket', '~> 0.6'
|
24
|
+
spec.add_dependency 'minitar', '~> 0.5'
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler'
|
26
27
|
spec.add_development_dependency 'rake'
|
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.9.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: 2018-01-
|
11
|
+
date: 2018-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitar
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.5'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,7 +140,7 @@ files:
|
|
126
140
|
- lib/nexussw/lxd/transport/local.rb
|
127
141
|
- lib/nexussw/lxd/transport/mixins/cli.rb
|
128
142
|
- lib/nexussw/lxd/transport/mixins/helpers/execute.rb
|
129
|
-
- lib/nexussw/lxd/transport/mixins/helpers/
|
143
|
+
- lib/nexussw/lxd/transport/mixins/helpers/folder_txfr.rb
|
130
144
|
- lib/nexussw/lxd/transport/mixins/helpers/users.rb
|
131
145
|
- lib/nexussw/lxd/transport/mixins/local.rb
|
132
146
|
- lib/nexussw/lxd/transport/mixins/rest.rb
|