cloudkeeper 1.3.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a7b923d81dc5b5f94d50e099e7775f7994d0e8f
4
- data.tar.gz: 551167065e752bbc83ff8c0d4402903a5f70f418
3
+ metadata.gz: 627d7ad80b5656af87fef1d88bdaa35fae85cda3
4
+ data.tar.gz: c4f5fa24ab19bf98e727e9a36be4cf1581b12005
5
5
  SHA512:
6
- metadata.gz: 17d9205bdac272454f9936230096e44058568f94998ff692ca6c6d3a3d5f1c3eb7c27cc785525bc19b0245e36e0bdded83f24dcc07c4551c55110d1d3177815a
7
- data.tar.gz: 9d8ea1adf2e5dccfaf5f55b673d4a494d80269d4536fd64e7c72d79851f900f8abb1b1593b356d72a5d9d442d249162c4ce065d73ca396d8a6a30a50427a6ad9
6
+ metadata.gz: feaefd01329102a82e8739c481c828f4b18df12b572bed7b4f2cde0bf4f864b1cdc5a6215db65a4434530bad569cede8ba04e6f34f5d6e4ad04d0e3394c3d8c6
7
+ data.tar.gz: 7a6c49eb1bbf1db0ffd46f855db2693cd02b292d03dfd5996429b22631bfec0db367d349fd7b5eb60af30ac91d9815ef9d1e2c483c3b562f64b7c69e42fc0448
@@ -28,6 +28,11 @@ Metrics/ClassLength:
28
28
  Exclude:
29
29
  - 'lib/cloudkeeper/cli.rb'
30
30
 
31
+ Metrics/ClassLength:
32
+ Max: 125
33
+ Include:
34
+ - 'lib/cloudkeeper/managers/appliance_manager.rb'
35
+
31
36
  RSpec/MultipleExpectations:
32
37
  Enabled: false
33
38
 
data/README.md CHANGED
@@ -71,50 +71,53 @@ cloudkeeper is run with executable `cloudkeeper`. For further assistance run `cl
71
71
  $ cloudkeeper help sync
72
72
 
73
73
  Usage:
74
- cloudkeeper sync --backend-endpoint=BACKEND-ENDPOINT --formats=one two three --image-dir=IMAGE-DIR --image-lists=one two three --qemu-img-binary=QEMU-IMG-BINARY
74
+ cloudkeeper sync --backend-endpoint=BACKEND-ENDPOINT --external-tools-execution-timeout=N --formats=one two three --image-dir=IMAGE-DIR --image-lists=one two three --qemu-img-binary=QEMU-IMG-BINARY
75
75
 
76
76
  Options:
77
- --image-lists=one two three # List of image lists to sync against
78
- [--ca-dir=CA-DIR] # CA directory
79
- # Default: /etc/grid-security/certificates/
80
- [--authentication], [--no-authentication] # Client <-> server authentication
81
- [--certificate=CERTIFICATE] # Core's host certificate
82
- # Default: /etc/grid-security/hostcert.pem
83
- [--key=KEY] # Core's host key
84
- # Default: /etc/grid-security/hostkey.pem
85
- --image-dir=IMAGE-DIR # Directory to store images to
86
- # Default: /var/spool/cloudkeeper/images/
87
- --qemu-img-binary=QEMU-IMG-BINARY # Path to qemu-img binary (image conversion)
88
- # Default: /usr/bin/qemu-img
89
- [--nginx-binary=NGINX-BINARY] # Path to nginx binary (HTTP server)
90
- # Default: /usr/bin/nginx
91
- [--remote-mode], [--no-remote-mode] # Remote mode starts HTTP server (NGINX) and serves images to backend via HTTP
92
- [--nginx-error-log-file=NGINX-ERROR-LOG-FILE] # NGINX error log file
93
- # Default: /var/log/cloudkeeper/nginx-error.log
94
- [--nginx-access-log-file=NGINX-ACCESS-LOG-FILE] # NGINX access log file
95
- # Default: /var/log/cloudkeeper/nginx-access.log
96
- [--nginx-pid-file=NGINX-PID-FILE] # NGINX pid file
97
- # Default: /var/run/cloudkeeper/nginx.pid
98
- [--nginx-ip-address=NGINX-IP-ADDRESS] # IP address NGINX can listen on
99
- # Default: 127.0.0.1
100
- [--nginx-min-port=N] # Minimal port NGINX can listen on
101
- # Default: 7300
102
- [--nginx-max-port=N] # Maximal port NGINX can listen on
103
- # Default: 7400
104
- --backend-endpoint=BACKEND-ENDPOINT # Backend's gRPC endpoint
105
- # Default: 127.0.0.1:50051
106
- [--backend-certificate=BACKEND-CERTIFICATE] # Backend's certificate
107
- # Default: /etc/grid-security/backendcert.pem
108
- --formats=one two three # List of acceptable formats images can be converted to
109
- # Default: ["qcow2"]
77
+ --image-lists=one two three # List of image lists to sync against
78
+ [--ca-dir=CA-DIR] # CA directory
79
+ # Default: /etc/grid-security/certificates/
80
+ [--authentication], [--no-authentication] # Client <-> server authentication
81
+ [--certificate=CERTIFICATE] # Core's host certificate
82
+ # Default: /etc/grid-security/hostcert.pem
83
+ [--key=KEY] # Core's host key
84
+ # Default: /etc/grid-security/hostkey.pem
85
+ --image-dir=IMAGE-DIR # Directory to store images to
86
+ # Default: /var/spool/cloudkeeper/images/
87
+ --qemu-img-binary=QEMU-IMG-BINARY # Path to qemu-img binary (image conversion)
88
+ # Default: /usr/bin/qemu-img
89
+ [--nginx-binary=NGINX-BINARY] # Path to nginx binary (HTTP server)
90
+ # Default: /usr/bin/nginx
91
+ --external-tools-execution-timeout=N # Timeout for execution of external tools in seconds
92
+ # Default: 600
93
+ [--remote-mode], [--no-remote-mode] # Remote mode starts HTTP server (NGINX) and serves images to backend via HTTP
94
+ [--nginx-error-log-file=NGINX-ERROR-LOG-FILE] # NGINX error log file
95
+ # Default: /var/log/cloudkeeper/nginx-error.log
96
+ [--nginx-access-log-file=NGINX-ACCESS-LOG-FILE] # NGINX access log file
97
+ # Default: /var/log/cloudkeeper/nginx-access.log
98
+ [--nginx-pid-file=NGINX-PID-FILE] # NGINX pid file
99
+ # Default: /var/run/cloudkeeper/nginx.pid
100
+ [--nginx-ip-address=NGINX-IP-ADDRESS] # IP address NGINX can listen on
101
+ # Default: 127.0.0.1
102
+ [--nginx-port=N] # Port NGINX can listen on
103
+ # Default: 50505
104
+ [--nginx-proxy-ip-address=NGINX-PROXY-IP-ADDRESS] # Proxy IP address
105
+ [--nginx-proxy-port=N] # Proxy port
106
+ [--nginx-proxy-ssl], [--no-nginx-proxy-ssl] # Whether proxy will use SSL connection
107
+ --backend-endpoint=BACKEND-ENDPOINT # Backend's gRPC endpoint
108
+ # Default: 127.0.0.1:50051
109
+ [--backend-certificate=BACKEND-CERTIFICATE] # Backend's certificate
110
+ # Default: /etc/grid-security/backendcert.pem
111
+ --formats=one two three # List of acceptable formats images can be converted to
112
+ # Default: ["qcow2"]
110
113
  --logging-level=LOGGING-LEVEL
111
- # Default: ERROR
112
- # Possible values: DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN
113
- [--logging-file=LOGGING-FILE] # File to write logs to
114
- # Default: /var/log/cloudkeeper/cloudkeeper.log
115
- --lock-file=LOCK-FILE # File used to ensure only one running instance of cloudkeeper
116
- # Default: /var/lock/cloudkeeper/cloudkeeper.lock
117
- [--debug], [--no-debug] # Runs cloudkeeper in debug mode
114
+ # Default: ERROR
115
+ # Possible values: DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN
116
+ [--logging-file=LOGGING-FILE] # File to write logs to
117
+ # Default: /var/log/cloudkeeper/cloudkeeper.log
118
+ --lock-file=LOCK-FILE # File used to ensure only one running instance of cloudkeeper
119
+ # Default: /var/lock/cloudkeeper/cloudkeeper.lock
120
+ [--debug], [--no-debug] # Runs cloudkeeper in debug mode
118
121
  ```
119
122
 
120
123
  ## Contributing
@@ -42,12 +42,12 @@ Gem::Specification.new do |spec|
42
42
  spec.add_development_dependency 'vcr', '~> 3.0'
43
43
  spec.add_development_dependency 'webmock', '~> 3.0'
44
44
  spec.add_development_dependency 'diffy', '~> 3.1'
45
- spec.add_development_dependency 'grpc-tools', '~> 1.0'
45
+ spec.add_development_dependency 'grpc-tools', '>= 1.1', '<= 1.2.5'
46
46
 
47
47
  spec.add_runtime_dependency 'thor', '~> 0.19'
48
48
  spec.add_runtime_dependency 'yell', '~> 2.0'
49
49
  spec.add_runtime_dependency 'mixlib-shellout', '~> 2.2'
50
- spec.add_runtime_dependency 'grpc', '~> 1.0'
50
+ spec.add_runtime_dependency 'grpc', '>= 1.1', '<= 1.2.5'
51
51
  spec.add_runtime_dependency 'settingslogic', '~> 2.0'
52
52
  spec.add_runtime_dependency 'zaru', '~> 0.1'
53
53
  spec.add_runtime_dependency 'activesupport', '>= 4.0', '< 6.0'
@@ -5,9 +5,11 @@ cloudkeeper:
5
5
  certificate: /etc/grid-security/hostcert.pem # Core's host certificate
6
6
  key: /etc/grid-security/hostkey.pem # Core's host key
7
7
  image-dir: /var/spool/cloudkeeper/images/ # Directory to store images to
8
- binaries:
9
- qemu-img: /usr/bin/qemu-img # qemu-img binary (image conversion) location
10
- nginx: /usr/bin/nginx # nginx binary (HTTP server) location
8
+ external-tools:
9
+ binaries:
10
+ qemu-img: /usr/bin/qemu-img # qemu-img binary (image conversion) location
11
+ nginx: /usr/bin/nginx # nginx binary (HTTP server) location
12
+ execution-timeout: 600 # timeout for execution of external tools in seconds
11
13
  remote-mode: false # Remote mode starts HTTP server (NGINX) and serves images to backend via HTTP
12
14
  nginx:
13
15
  runtime-dir: /var/run/cloudkeeper/ # Runtime directory for NGINX
@@ -20,22 +20,23 @@ module Cloudkeeper
20
20
  end
21
21
 
22
22
  def add_appliance(appliance)
23
- logger.debug "'add_appliance' gRPC method call"
23
+ logger.debug "'add_appliance' gRPC method call (appliance.identifier: #{appliance.identifier})"
24
24
  manage_appliance appliance, :add_appliance
25
25
  end
26
26
 
27
27
  def update_appliance(appliance)
28
- logger.debug "'update_appliance' gRPC method call"
28
+ logger.debug "'update_appliance' gRPC method call (appliance.identifier: #{appliance.identifier})"
29
29
  manage_appliance appliance, :update_appliance
30
30
  end
31
31
 
32
32
  def remove_appliance(appliance)
33
- logger.debug "'remove_appliance' gRPC method call"
33
+ logger.debug "'remove_appliance' gRPC method call (appliance.identifier: #{appliance.identifier})"
34
+ appliance.image = nil
34
35
  manage_appliance appliance, :remove_appliance
35
36
  end
36
37
 
37
38
  def remove_image_list(image_list_identifier)
38
- logger.debug "'remove_image_list' gRPC method call"
39
+ logger.debug "'remove_image_list' gRPC method call (image_list_identifier: #{image_list_identifier})"
39
40
  handle_errors grpc_client.remove_image_list(
40
41
  CloudkeeperGrpc::ImageListIdentifier.new(image_list_identifier: image_list_identifier),
41
42
  return_op: true
@@ -53,13 +53,18 @@ module Cloudkeeper
53
53
  desc: 'Directory to store images to'
54
54
  method_option :'qemu-img-binary',
55
55
  required: true,
56
- default: Cloudkeeper::Settings['binaries']['qemu-img'],
56
+ default: Cloudkeeper::Settings['external-tools']['binaries']['qemu-img'],
57
57
  type: :string,
58
58
  desc: 'Path to qemu-img binary (image conversion)'
59
59
  method_option :'nginx-binary',
60
- default: Cloudkeeper::Settings['binaries']['nginx'],
60
+ default: Cloudkeeper::Settings['external-tools']['binaries']['nginx'],
61
61
  type: :string,
62
62
  desc: 'Path to nginx binary (HTTP server)'
63
+ method_option :'external-tools-execution-timeout',
64
+ required: true,
65
+ default: Cloudkeeper::Settings['external-tools']['execution-timeout'],
66
+ type: :numeric,
67
+ desc: 'Timeout for execution of external tools in seconds'
63
68
  method_option :'remote-mode',
64
69
  default: Cloudkeeper::Settings['remote-mode'],
65
70
  type: :boolean,
@@ -2,7 +2,7 @@ module Cloudkeeper
2
2
  class CommandExecutioner
3
3
  class << self
4
4
  def execute(*args)
5
- command = Mixlib::ShellOut.new(*args)
5
+ command = Mixlib::ShellOut.new(*args, timeout: Cloudkeeper::Settings[:'external-tools-execution-timeout'])
6
6
  logger.debug "Executing command: #{command.command.inspect}"
7
7
  command.run_command
8
8
 
@@ -54,8 +54,8 @@ module Cloudkeeper
54
54
  appliance_hash[:'dc:title'],
55
55
  appliance_hash[:'dc:description'],
56
56
  appliance_hash[:'ad:group'],
57
- appliance_hash[:'ad:ram_recommended'],
58
- appliance_hash[:'ad:core_recommended'],
57
+ appliance_hash[:'hv:ram_minimum'],
58
+ appliance_hash[:'hv:core_minimum'],
59
59
  appliance_hash[:'hv:version'],
60
60
  appliance_hash[:'sl:arch']
61
61
 
@@ -6,12 +6,6 @@ module Cloudkeeper
6
6
  module Convertable
7
7
  CONVERT_OUTPUT_FORMATS = %i[raw qcow2 vmdk vdi].freeze
8
8
 
9
- def self.convert_output_formats
10
- CONVERT_OUTPUT_FORMATS
11
- end
12
-
13
- FORMAT_REGEX = /^to_(?<format>#{convert_output_formats.join('|')})$/
14
-
15
9
  def self.included(base)
16
10
  raise Cloudkeeper::Errors::Convertables::ConvertabilityError, "#{base.inspect} cannot become a convertable" \
17
11
  unless base.method_defined?(:file) && base.method_defined?(:format)
@@ -19,27 +13,40 @@ module Cloudkeeper
19
13
  super
20
14
  end
21
15
 
16
+ def convert_output_formats
17
+ CONVERT_OUTPUT_FORMATS
18
+ end
19
+
20
+ def format_regex
21
+ /^to_(?<format>#{convert_output_formats.join('|')})$/
22
+ end
23
+
22
24
  def method_missing(method, *arguments, &block)
23
- result = method.to_s.match(FORMAT_REGEX)
24
- return convert(result[:format]) if result && result[:format]
25
+ result = method.to_s.match(format_regex)
26
+ if result && result[:format]
27
+ return self if format.to_sym == result[:format].to_sym
28
+ return convert result[:format]
29
+ end
25
30
 
26
31
  super
27
32
  end
28
33
 
29
34
  def respond_to_missing?(method, *)
30
- method =~ FORMAT_REGEX || super
35
+ method =~ format_regex || super
31
36
  end
32
37
 
33
38
  private
34
39
 
35
40
  def convert(output_format)
36
41
  logger.debug "Converting file #{file.inspect} from #{format.inspect} to #{output_format.inspect}"
37
- return self if output_format.to_sym == format.to_sym
38
42
 
39
43
  converted_file = File.join(File.dirname(file), "#{File.basename(file, '.*')}.#{output_format}")
40
44
  run_convert_command(output_format, converted_file)
41
45
 
42
46
  image_file converted_file, output_format
47
+ rescue Cloudkeeper::Errors::CommandExecutionError => ex
48
+ delete_if_exists converted_file
49
+ raise ex
43
50
  end
44
51
 
45
52
  def run_convert_command(output_format, converted_file)
@@ -57,6 +64,10 @@ module Cloudkeeper
57
64
  Cloudkeeper::Entities::ImageFile.new converted_file, output_format.to_sym,
58
65
  Cloudkeeper::Utils::Checksum.compute(converted_file), false
59
66
  end
67
+
68
+ def delete_if_exists(file)
69
+ File.delete(file) if File.exist?(file.to_s)
70
+ end
60
71
  end
61
72
  end
62
73
  end
@@ -2,11 +2,7 @@ module Cloudkeeper
2
2
  module Entities
3
3
  module Convertables
4
4
  module Ova
5
- CONVERT_OUTPUT_FORMATS = %i[raw qcow2 vdi].freeze
6
-
7
- def self.convert_output_formats
8
- CONVERT_OUTPUT_FORMATS
9
- end
5
+ CONVERT_OUTPUT_FORMATS = %i[raw qcow2 vdi ova].freeze
10
6
 
11
7
  def self.extended(base)
12
8
  raise Cloudkeeper::Errors::Convertables::ConvertabilityError, "#{base.inspect} cannot become OVA convertable" \
@@ -15,12 +11,13 @@ module Cloudkeeper
15
11
  super
16
12
  end
17
13
 
18
- def to_vmdk
19
- image_file(extract_disk, :vmdk)
14
+ def convert_output_formats
15
+ CONVERT_OUTPUT_FORMATS
20
16
  end
21
17
 
22
- def to_ova
23
- self
18
+ def to_vmdk
19
+ logger.debug "Converting file #{file.inspect} from #{format.inspect} to vmdk"
20
+ image_file(extract_disk, :vmdk)
24
21
  end
25
22
 
26
23
  private
@@ -37,8 +34,12 @@ module Cloudkeeper
37
34
  def extract_disk
38
35
  archived_disk = disk_file
39
36
  disk_directory = File.dirname(file)
37
+ extracted_file = File.join(disk_directory, archived_disk)
40
38
  Cloudkeeper::CommandExecutioner.execute('tar', '-x', '-f', file, '-C', disk_directory, archived_disk)
41
- File.join(disk_directory, archived_disk)
39
+ extracted_file
40
+ rescue Cloudkeeper::Errors::CommandExecutionError => ex
41
+ delete_if_exists extracted_file
42
+ raise ex
42
43
  end
43
44
 
44
45
  def archive_files
@@ -39,6 +39,7 @@ module Cloudkeeper
39
39
  def sync_new_image_lists(backend_image_lists)
40
40
  logger.debug 'Registering appliances from new image lists...'
41
41
  add_list = image_list_manager.image_lists.keys - backend_image_lists
42
+ logger.debug "Image lists to register: #{add_list.inspect}"
42
43
  add_list.each do |image_list_identifier|
43
44
  image_list_manager.image_lists[image_list_identifier].appliances.each_value { |appliance| add_appliance appliance }
44
45
  end
@@ -47,6 +48,7 @@ module Cloudkeeper
47
48
  def sync_old_image_lists(backend_image_lists)
48
49
  logger.debug 'Synchronizing registered appliances...'
49
50
  sync_list = image_list_manager.image_lists.keys & backend_image_lists
51
+ logger.debug "Image lists to synchronize: #{sync_list.inspect}"
50
52
  sync_list.each { |image_list_identifier| sync_image_list image_list_identifier }
51
53
  end
52
54
 
@@ -63,18 +65,21 @@ module Cloudkeeper
63
65
  def remove_appliances(backend_appliances, image_list_appliances)
64
66
  logger.debug 'Removing previously registered appliances...'
65
67
  remove_list = backend_appliances.keys - image_list_appliances.keys
66
- remove_list.each { |appliance_identifier| backend_connector.remove_appliance image_list_appliances[appliance_identifier] }
68
+ logger.debug "Appliances to remove: #{remove_list.inspect}"
69
+ remove_list.each { |appliance_identifier| backend_connector.remove_appliance backend_appliances[appliance_identifier] }
67
70
  end
68
71
 
69
72
  def add_appliances(backend_appliances, image_list_appliances)
70
73
  logger.debug 'Registering new appliances...'
71
74
  add_list = image_list_appliances.keys - backend_appliances.keys
75
+ logger.debug "Appliances to register: #{add_list.inspect}"
72
76
  add_list.each { |appliance_identifier| add_appliance image_list_appliances[appliance_identifier] }
73
77
  end
74
78
 
75
79
  def update_appliances(backend_appliances, image_list_appliances)
76
80
  logger.debug 'Updating appliances...'
77
81
  update_list = backend_appliances.keys & image_list_appliances.keys
82
+ logger.debug "Appliances for potential update: #{update_list.inspect}"
78
83
  update_list.each do |appliance_identifier|
79
84
  image_list_appliance = image_list_appliances[appliance_identifier]
80
85
  backend_appliance = backend_appliances[appliance_identifier]
@@ -1,3 +1,3 @@
1
1
  module Cloudkeeper
2
- VERSION = '1.3.1'.freeze
2
+ VERSION = '1.4.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudkeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Kimle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-26 00:00:00.000000000 Z
11
+ date: 2017-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -168,16 +168,22 @@ dependencies:
168
168
  name: grpc-tools
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
- - - "~>"
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '1.1'
174
+ - - "<="
172
175
  - !ruby/object:Gem::Version
173
- version: '1.0'
176
+ version: 1.2.5
174
177
  type: :development
175
178
  prerelease: false
176
179
  version_requirements: !ruby/object:Gem::Requirement
177
180
  requirements:
178
- - - "~>"
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '1.1'
184
+ - - "<="
179
185
  - !ruby/object:Gem::Version
180
- version: '1.0'
186
+ version: 1.2.5
181
187
  - !ruby/object:Gem::Dependency
182
188
  name: thor
183
189
  requirement: !ruby/object:Gem::Requirement
@@ -224,16 +230,22 @@ dependencies:
224
230
  name: grpc
225
231
  requirement: !ruby/object:Gem::Requirement
226
232
  requirements:
227
- - - "~>"
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '1.1'
236
+ - - "<="
228
237
  - !ruby/object:Gem::Version
229
- version: '1.0'
238
+ version: 1.2.5
230
239
  type: :runtime
231
240
  prerelease: false
232
241
  version_requirements: !ruby/object:Gem::Requirement
233
242
  requirements:
234
- - - "~>"
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ version: '1.1'
246
+ - - "<="
235
247
  - !ruby/object:Gem::Version
236
- version: '1.0'
248
+ version: 1.2.5
237
249
  - !ruby/object:Gem::Dependency
238
250
  name: settingslogic
239
251
  requirement: !ruby/object:Gem::Requirement