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 +4 -4
- data/.rubocop.yml +5 -0
- data/README.md +44 -41
- data/cloudkeeper.gemspec +2 -2
- data/config/cloudkeeper.yml +5 -3
- data/lib/cloudkeeper/backend_connector.rb +5 -4
- data/lib/cloudkeeper/cli.rb +7 -2
- data/lib/cloudkeeper/command_executioner.rb +1 -1
- data/lib/cloudkeeper/entities/appliance.rb +2 -2
- data/lib/cloudkeeper/entities/convertables/convertable.rb +21 -10
- data/lib/cloudkeeper/entities/convertables/ova.rb +11 -10
- data/lib/cloudkeeper/managers/appliance_manager.rb +6 -1
- data/lib/cloudkeeper/version.rb +1 -1
- metadata +22 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 627d7ad80b5656af87fef1d88bdaa35fae85cda3
|
4
|
+
data.tar.gz: c4f5fa24ab19bf98e727e9a36be4cf1581b12005
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feaefd01329102a82e8739c481c828f4b18df12b572bed7b4f2cde0bf4f864b1cdc5a6215db65a4434530bad569cede8ba04e6f34f5d6e4ad04d0e3394c3d8c6
|
7
|
+
data.tar.gz: 7a6c49eb1bbf1db0ffd46f855db2693cd02b292d03dfd5996429b22631bfec0db367d349fd7b5eb60af30ac91d9815ef9d1e2c483c3b562f64b7c69e42fc0448
|
data/.rubocop.yml
CHANGED
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
|
78
|
-
[--ca-dir=CA-DIR]
|
79
|
-
|
80
|
-
[--authentication], [--no-authentication]
|
81
|
-
[--certificate=CERTIFICATE]
|
82
|
-
|
83
|
-
[--key=KEY]
|
84
|
-
|
85
|
-
--image-dir=IMAGE-DIR
|
86
|
-
|
87
|
-
--qemu-img-binary=QEMU-IMG-BINARY
|
88
|
-
|
89
|
-
[--nginx-binary=NGINX-BINARY]
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
[--nginx-
|
95
|
-
|
96
|
-
[--nginx-
|
97
|
-
|
98
|
-
[--nginx-
|
99
|
-
|
100
|
-
[--nginx-
|
101
|
-
|
102
|
-
[--nginx-
|
103
|
-
|
104
|
-
--
|
105
|
-
|
106
|
-
[--
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
|
112
|
-
|
113
|
-
[--logging-file=LOGGING-FILE]
|
114
|
-
|
115
|
-
--lock-file=LOCK-FILE
|
116
|
-
|
117
|
-
[--debug], [--no-debug]
|
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
|
data/cloudkeeper.gemspec
CHANGED
@@ -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', '
|
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', '
|
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'
|
data/config/cloudkeeper.yml
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
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
|
data/lib/cloudkeeper/cli.rb
CHANGED
@@ -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[:'
|
58
|
-
appliance_hash[:'
|
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(
|
24
|
-
|
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 =~
|
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
|
19
|
-
|
14
|
+
def convert_output_formats
|
15
|
+
CONVERT_OUTPUT_FORMATS
|
20
16
|
end
|
21
17
|
|
22
|
-
def
|
23
|
-
|
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
|
-
|
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
|
-
|
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]
|
data/lib/cloudkeeper/version.rb
CHANGED
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.
|
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-
|
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:
|
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:
|
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:
|
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:
|
248
|
+
version: 1.2.5
|
237
249
|
- !ruby/object:Gem::Dependency
|
238
250
|
name: settingslogic
|
239
251
|
requirement: !ruby/object:Gem::Requirement
|