uricp 0.0.18 → 0.0.20
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.lock +3 -2
- data/Jenkinsfile +88 -58
- data/Rakefile +5 -0
- data/almalinux8/Dockerfile +26 -0
- data/bin/uricp +25 -11
- data/bionic/Dockerfile +2 -1
- data/centos7/Dockerfile +16 -9
- data/cucumber.yml +1 -0
- data/features/check_uri_path.feature +14 -0
- data/features/rbd_access.feature +226 -0
- data/features/step_definitions/rbd_steps.rb +8 -0
- data/focal/Dockerfile +10 -3
- data/lib/uricp/strategy/cache_common.rb +19 -1
- data/lib/uricp/strategy/cached_get.rb +8 -5
- data/lib/uricp/strategy/common.rb +52 -1
- data/lib/uricp/strategy/piped_cache.rb +5 -4
- data/lib/uricp/strategy/piped_rbd_get.rb +8 -24
- data/lib/uricp/strategy/rbd_cache_base_snap.rb +27 -0
- data/lib/uricp/strategy/rbd_cache_check.rb +42 -0
- data/lib/uricp/strategy/rbd_cache_clone.rb +40 -0
- data/lib/uricp/strategy/rbd_cache_upload.rb +40 -0
- data/lib/uricp/strategy/rbd_cached_get.rb +36 -0
- data/lib/uricp/strategy/rbd_cached_put.rb +33 -0
- data/lib/uricp/strategy/rbd_flattener.rb +23 -0
- data/lib/uricp/strategy/{rbd_remote_put.rb → rbd_put.rb} +7 -5
- data/lib/uricp/strategy/rbd_snap.rb +56 -0
- data/lib/uricp/strategy/rbd_sweeper.rb +2 -1
- data/lib/uricp/uri_strategy.rb +9 -1
- data/lib/uricp/version.rb +1 -1
- data/lib/uricp.rb +27 -19
- data/uricp.gemspec +2 -1
- data/xenial/Dockerfile +2 -1
- metadata +34 -5
@@ -0,0 +1,8 @@
|
|
1
|
+
Then(/^a ceph entry named "(.*?)" should exist$/) do |arg1|
|
2
|
+
pending # express the regexp above with the code you wish you had
|
3
|
+
end
|
4
|
+
|
5
|
+
Then(/^a ceph snapshot named "(.*?)" should exist$/) do |arg1|
|
6
|
+
pending # express the regexp above with the code you wish you had
|
7
|
+
end
|
8
|
+
|
data/focal/Dockerfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
FROM ubuntu:focal
|
2
2
|
MAINTAINER support@brightbox.co.uk
|
3
3
|
|
4
|
+
RUN echo "gem: --no-ri --no-rdoc" >> "$HOME/.gemrc"
|
5
|
+
|
4
6
|
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq software-properties-common
|
5
7
|
|
6
8
|
#RUN apt-add-repository ppa:brightbox/ruby-ng
|
@@ -14,8 +16,13 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
|
|
14
16
|
ruby \
|
15
17
|
ruby-dev \
|
16
18
|
python3-swiftclient \
|
17
|
-
ruby-bundler
|
18
|
-
|
19
|
-
RUN echo "gem: --no-ri --no-rdoc" >> "$HOME/.gemrc"
|
19
|
+
ruby-bundler \
|
20
|
+
ceph-common
|
20
21
|
|
21
22
|
RUN gem install bundler -v '~> 1.7'
|
23
|
+
RUN mkdir -p /etc/ceph
|
24
|
+
ARG RBD_USR=libvirt
|
25
|
+
ARG RBD_PSW
|
26
|
+
ARG CEPH_MON
|
27
|
+
RUN /bin/echo -e "[client.$RBD_USR]\nkey = $RBD_PSW\n" > /etc/ceph/ceph.client.$RBD_USR.keyring
|
28
|
+
RUN /bin/echo -e "[global]\nmon_host = $CEPH_MON\n" > /etc/ceph/ceph.conf
|
@@ -15,8 +15,26 @@ module Uricp::Strategy
|
|
15
15
|
'no cache name found'
|
16
16
|
end
|
17
17
|
|
18
|
+
def with_active_cache
|
19
|
+
if cache_root
|
20
|
+
yield
|
21
|
+
else
|
22
|
+
debug "#{self.class.name}: no cacheing requested"
|
23
|
+
false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def without_active_cache
|
28
|
+
unless cache_root
|
29
|
+
yield
|
30
|
+
else
|
31
|
+
debug "#{self.class.name}: cache active - not appropriate"
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
18
36
|
def in_cache?
|
19
|
-
File.readable?
|
37
|
+
File.readable?(cache_file) || options['dry-cache']
|
20
38
|
end
|
21
39
|
|
22
40
|
def cache_root
|
@@ -6,15 +6,13 @@ module Uricp::Strategy
|
|
6
6
|
include Uricp::Strategy::CacheCommon
|
7
7
|
|
8
8
|
def appropriate?
|
9
|
-
|
9
|
+
with_active_cache do
|
10
10
|
validate_cache!
|
11
11
|
return proposal if in_cache? || file_source?
|
12
12
|
|
13
13
|
debug "#{self.class.name}: no cache entry for #{options['from_uri']}"
|
14
|
-
|
15
|
-
debug "#{self.class.name}: not appropriate"
|
14
|
+
false
|
16
15
|
end
|
17
|
-
false
|
18
16
|
end
|
19
17
|
|
20
18
|
def command
|
@@ -24,10 +22,15 @@ module Uricp::Strategy
|
|
24
22
|
def proposal
|
25
23
|
@proposed_options = options.dup
|
26
24
|
@proposed_options['from_uri'] = URI.join('file:///', cache_file) unless file_source?
|
25
|
+
if to.scheme == 'rbd'
|
26
|
+
@proposed_options['rbd_cache_name'] = rbd_cache_image_spec(to)
|
27
|
+
end
|
27
28
|
@proposed_options.delete('cache')
|
28
29
|
@proposed_options.delete('cache_name')
|
29
30
|
if conversion_required?
|
30
|
-
|
31
|
+
if dry_run?
|
32
|
+
@proposed_options['source-format'] = @proposed_options['target-format']
|
33
|
+
else
|
31
34
|
@proposed_options['source-format'] =
|
32
35
|
File.open(@proposed_options['from_uri'].path) { |f| encoding(f) }
|
33
36
|
end
|
@@ -91,6 +91,13 @@ module Uricp::Strategy
|
|
91
91
|
end
|
92
92
|
|
93
93
|
PIPE_URI = URI('pipe:/')
|
94
|
+
def rbd_base_name
|
95
|
+
'base'.freeze
|
96
|
+
end
|
97
|
+
|
98
|
+
def rbd_snapshot_name
|
99
|
+
'uricp_snap'.freeze
|
100
|
+
end
|
94
101
|
|
95
102
|
def get_temp_filename(base_dir)
|
96
103
|
t = Time.now.strftime('%Y%m%d')
|
@@ -109,12 +116,56 @@ module Uricp::Strategy
|
|
109
116
|
options['source-format'] && !lz4_source?
|
110
117
|
end
|
111
118
|
|
112
|
-
def
|
119
|
+
def rbd_image_spec(uri)
|
113
120
|
uri.path[1..-1]
|
114
121
|
end
|
115
122
|
|
123
|
+
def rbd_cache_image_spec(uri)
|
124
|
+
File.join(File.dirname(uri.path)[1..-1], options['cache_name'])
|
125
|
+
end
|
126
|
+
|
127
|
+
def rbd_cache_name
|
128
|
+
options['rbd_cache_name']
|
129
|
+
end
|
130
|
+
|
131
|
+
def rbd_clone_snapshot(cache=rbd_cache_name)
|
132
|
+
"#{cache}@#{rbd_base_name}"
|
133
|
+
end
|
134
|
+
|
135
|
+
def rbd_uri(image_spec)
|
136
|
+
URI.join('rbd:///', image_spec)
|
137
|
+
end
|
138
|
+
|
139
|
+
def rbd_sequence_complete?
|
140
|
+
from.path.include?(to.path)
|
141
|
+
end
|
142
|
+
|
116
143
|
def rbd_id
|
117
144
|
'libvirt'
|
118
145
|
end
|
146
|
+
|
147
|
+
def in_rbd_cache?
|
148
|
+
options['in_rbd_cache']
|
149
|
+
end
|
150
|
+
|
151
|
+
def not_in_rbd_cache?
|
152
|
+
options['in_rbd_cache'] == false
|
153
|
+
end
|
154
|
+
|
155
|
+
def rbd_snapshot_spec?(uri)
|
156
|
+
uri.scheme == 'rbd' && uri.path.include?('@')
|
157
|
+
end
|
158
|
+
|
159
|
+
def in_rbd_cache(target)
|
160
|
+
result = false
|
161
|
+
if dry_run?
|
162
|
+
result = options['dry-cache'] && options['cache_name'] !~ /srv-...../
|
163
|
+
else
|
164
|
+
sh "rbd snap ls --id #{rbd_id} --format json #{target}" do |stdout|
|
165
|
+
result = JSON.parse(stdout).any? { |x| x['name'] == rbd_base_name }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
result && rbd_clone_snapshot(target)
|
169
|
+
end
|
119
170
|
end
|
120
171
|
end
|
@@ -6,17 +6,15 @@ module Uricp::Strategy
|
|
6
6
|
include Uricp::Strategy::CacheCommon
|
7
7
|
|
8
8
|
def appropriate?
|
9
|
-
|
9
|
+
with_active_cache do
|
10
10
|
case from.scheme
|
11
11
|
when 'pipe'
|
12
12
|
validate_cache!
|
13
13
|
return proposal
|
14
14
|
end
|
15
15
|
debug "#{self.class.name}: not appropriate"
|
16
|
-
|
17
|
-
debug "#{self.class.name}: no cacheing requested"
|
16
|
+
false
|
18
17
|
end
|
19
|
-
false
|
20
18
|
end
|
21
19
|
|
22
20
|
def command
|
@@ -26,6 +24,9 @@ module Uricp::Strategy
|
|
26
24
|
def proposal
|
27
25
|
@proposed_options = options.dup
|
28
26
|
@proposed_options['sweep'] = [temp_cache_file, cache_file]
|
27
|
+
if to.scheme == 'rbd'
|
28
|
+
@proposed_options['rbd_cache_name'] = rbd_cache_image_spec(to)
|
29
|
+
end
|
29
30
|
@proposed_options.delete('cache')
|
30
31
|
@proposed_options.delete('cache_name')
|
31
32
|
self
|
@@ -2,45 +2,29 @@ require 'json'
|
|
2
2
|
module Uricp::Strategy
|
3
3
|
class PipedRbdGet
|
4
4
|
include Uricp::Strategy::Common
|
5
|
+
include Uricp::Strategy::CacheCommon
|
5
6
|
include Methadone::SH
|
6
7
|
|
7
8
|
def appropriate?
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
without_active_cache do
|
10
|
+
if from.scheme == 'rbd' &&
|
11
|
+
rbd_snapshot_spec?(from) &&
|
12
|
+
to.scheme != 'rbd'
|
13
|
+
return proposal unless sequence_complete?
|
14
|
+
end
|
11
15
|
end
|
12
16
|
debug "#{self.class.name}: not appropriate"
|
13
17
|
false
|
14
18
|
end
|
15
19
|
|
16
20
|
def command
|
17
|
-
"rbd
|
18
|
-
"rbd export --no-progress --id #{rbd_id} '#{rbd_snap_target(from)}' - |"
|
21
|
+
"rbd export --no-progress --id #{rbd_id} '#{rbd_image_spec(from)}' - |"
|
19
22
|
end
|
20
23
|
|
21
24
|
def proposal
|
22
25
|
@proposed_options = options.dup
|
23
|
-
@proposed_options['rbd_snapshot'] = rbd_snap_target(from)
|
24
26
|
@proposed_options['from_uri'] = PIPE_URI
|
25
|
-
@proposed_options.delete('cache')
|
26
|
-
@proposed_options.delete('cache_name')
|
27
27
|
self
|
28
28
|
end
|
29
|
-
|
30
|
-
RBD_SNAPSHOT = 'uricp_snap'.freeze
|
31
|
-
|
32
|
-
def rbd_snap_target(uri)
|
33
|
-
"#{rbd_target(uri)}@#{RBD_SNAPSHOT}"
|
34
|
-
end
|
35
|
-
|
36
|
-
def snap_in_progress?
|
37
|
-
return false if dry_run?
|
38
|
-
|
39
|
-
result = false
|
40
|
-
sh "rbd snap ls --id #{rbd_id} --format json #{rbd_target(from)}" do |stdout|
|
41
|
-
result = JSON.parse(stdout).any? { |x| x['name'] == RBD_SNAPSHOT }
|
42
|
-
end
|
43
|
-
result
|
44
|
-
end
|
45
29
|
end
|
46
30
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Uricp::Strategy
|
2
|
+
class RbdCacheBaseSnap
|
3
|
+
include Uricp::Strategy::Common
|
4
|
+
include Methadone::SH
|
5
|
+
|
6
|
+
def appropriate?
|
7
|
+
if rbd_cache_name &&
|
8
|
+
rbd_image_spec(from) == rbd_cache_name
|
9
|
+
return proposal
|
10
|
+
end
|
11
|
+
debug "#{self.class.name}: not appropriate"
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
"rbd snap create --id #{rbd_id} '#{rbd_clone_snapshot(rbd_cache_name)}' && "\
|
17
|
+
"rbd snap protect --id #{rbd_id} '#{rbd_clone_snapshot(rbd_cache_name)}';"
|
18
|
+
end
|
19
|
+
|
20
|
+
def proposal
|
21
|
+
@proposed_options = options.dup
|
22
|
+
@proposed_options['from_uri'] = rbd_uri(rbd_clone_snapshot(rbd_cache_name))
|
23
|
+
@proposed_options.delete('rbd_cache_name')
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Uricp::Strategy
|
4
|
+
class RbdCacheCheck
|
5
|
+
include Uricp::Strategy::Common
|
6
|
+
include Uricp::Strategy::CacheCommon
|
7
|
+
include Methadone::SH
|
8
|
+
|
9
|
+
def appropriate?
|
10
|
+
unless (from.scheme == 'rbd') != (to.scheme == 'rbd')
|
11
|
+
debug "#{self.class.name}: not appropriate"
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
with_active_cache do
|
16
|
+
if from.scheme == 'rbd'
|
17
|
+
cache_check = in_rbd_cache(rbd_cache_image_spec(from))
|
18
|
+
return proposal(cache_check) if cache_check
|
19
|
+
debug "#{self.class.name}: no rbd cache entry for #{options['from_uri']}"
|
20
|
+
elsif to.scheme == 'rbd'
|
21
|
+
cache_check = in_rbd_cache(rbd_cache_image_spec(to))
|
22
|
+
return proposal(cache_check) if cache_check
|
23
|
+
debug "#{self.class.name}: no rbd cache entry for #{options['to_uri']}"
|
24
|
+
end
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def command
|
30
|
+
':;'
|
31
|
+
end
|
32
|
+
|
33
|
+
def proposal(cache_check)
|
34
|
+
@proposed_options = options.dup
|
35
|
+
@proposed_options['from_uri'] = rbd_uri(cache_check)
|
36
|
+
@proposed_options.delete('cache')
|
37
|
+
@proposed_options.delete('cache_name')
|
38
|
+
@proposed_options.delete('dry-cache')
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Uricp::Strategy
|
4
|
+
class RbdCacheClone
|
5
|
+
include Uricp::Strategy::Common
|
6
|
+
include Uricp::Strategy::CacheCommon
|
7
|
+
include Methadone::SH
|
8
|
+
|
9
|
+
def appropriate?
|
10
|
+
unless from.scheme == 'rbd'
|
11
|
+
debug "#{self.class.name}: not appropriate"
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
with_active_cache do
|
16
|
+
options['cache_name'] = File.basename(options['to_uri'].path)
|
17
|
+
cache_target = rbd_cache_image_spec(from)
|
18
|
+
cache_check = in_rbd_cache(rbd_cache_image_spec(from))
|
19
|
+
if cache_check
|
20
|
+
debug "#{self.class.name}: Unexpected existing cache entry for #{options['to_uri']}"
|
21
|
+
unsupported_transfer
|
22
|
+
end
|
23
|
+
proposal(cache_target)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def command
|
28
|
+
':;'
|
29
|
+
end
|
30
|
+
|
31
|
+
def proposal(cache_check)
|
32
|
+
@proposed_options = options.dup
|
33
|
+
@proposed_options['rbd_cache_target'] = rbd_uri(cache_check)
|
34
|
+
@proposed_options.delete('cache')
|
35
|
+
@proposed_options.delete('cache_name')
|
36
|
+
@proposed_options.delete('dry-cache')
|
37
|
+
self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Uricp::Strategy
|
2
|
+
class RbdCacheUpload
|
3
|
+
include Uricp::Strategy::Common
|
4
|
+
include Methadone::SH
|
5
|
+
|
6
|
+
def appropriate?
|
7
|
+
if compression_required? || conversion_required?
|
8
|
+
debug "#{self.class.name}: not ready to upload"
|
9
|
+
return false
|
10
|
+
end
|
11
|
+
if rbd_cache_name
|
12
|
+
case from.scheme
|
13
|
+
when 'pipe', 'file'
|
14
|
+
return proposal if to.scheme == 'rbd'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
debug "#{self.class.name}: not appropriate"
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def command
|
22
|
+
"rbd import --no-progress --id #{rbd_id} #{data_source} '#{rbd_cache_name}' && "
|
23
|
+
end
|
24
|
+
|
25
|
+
def proposal
|
26
|
+
@proposed_options = options.dup
|
27
|
+
@proposed_options['from_uri'] = rbd_uri(rbd_cache_name)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def data_source
|
32
|
+
if from.scheme == 'pipe'
|
33
|
+
'-'
|
34
|
+
else
|
35
|
+
"'#{from.path}'"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Uricp::Strategy
|
4
|
+
class RbdCachedGet
|
5
|
+
include Uricp::Strategy::Common
|
6
|
+
include Uricp::Strategy::CacheCommon
|
7
|
+
include Methadone::SH
|
8
|
+
|
9
|
+
def appropriate?
|
10
|
+
if from.scheme != 'rbd' || rbd_snapshot_spec?(from)
|
11
|
+
debug "#{self.class.name}: not appropriate"
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
with_active_cache do
|
16
|
+
cache_check = in_rbd_cache(rbd_image_spec(from))
|
17
|
+
return proposal(cache_check) if cache_check
|
18
|
+
debug "#{self.class.name}: no rbd cache entry for #{options['from_uri']}"
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def command
|
24
|
+
':;'
|
25
|
+
end
|
26
|
+
|
27
|
+
def proposal(cache_check)
|
28
|
+
@proposed_options = options.dup
|
29
|
+
@proposed_options['from_uri'] = rbd_uri(cache_check)
|
30
|
+
@proposed_options.delete('cache')
|
31
|
+
@proposed_options.delete('cache_name')
|
32
|
+
@proposed_options.delete('dry-cache')
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|