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