uricp 0.0.18 → 0.0.23
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 +26 -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 +248 -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 +69 -1
- data/lib/uricp/strategy/piped_cache.rb +7 -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 +39 -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 +32 -0
- data/lib/uricp/strategy/{rbd_remote_put.rb → rbd_put.rb} +7 -5
- data/lib/uricp/strategy/rbd_snap.rb +57 -0
- data/lib/uricp/strategy/rbd_sweeper.rb +2 -1
- data/lib/uricp/uri_strategy.rb +8 -1
- data/lib/uricp/version.rb +1 -1
- data/lib/uricp.rb +26 -19
- data/uricp.gemspec +2 -1
- data/xenial/Dockerfile +2 -1
- metadata +33 -5
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'] == :rbd
|
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,15 @@ module Uricp::Strategy
|
|
91
91
|
end
|
92
92
|
|
93
93
|
PIPE_URI = URI('pipe:/')
|
94
|
+
DRY_SNAP = 'uricp_snap'.freeze
|
95
|
+
|
96
|
+
def rbd_base_name
|
97
|
+
'base'.freeze
|
98
|
+
end
|
99
|
+
|
100
|
+
def rbd_snapshot_name
|
101
|
+
@rbd_snapshot_name ||= dry_run? ? DRY_SNAP : SecureRandom.uuid
|
102
|
+
end
|
94
103
|
|
95
104
|
def get_temp_filename(base_dir)
|
96
105
|
t = Time.now.strftime('%Y%m%d')
|
@@ -109,12 +118,71 @@ module Uricp::Strategy
|
|
109
118
|
options['source-format'] && !lz4_source?
|
110
119
|
end
|
111
120
|
|
112
|
-
def
|
121
|
+
def rbd_image_spec(uri)
|
113
122
|
uri.path[1..-1]
|
114
123
|
end
|
115
124
|
|
125
|
+
def rbd_cache_image_spec(uri)
|
126
|
+
File.join(File.dirname(uri.path)[1..-1], options['cache_name'])
|
127
|
+
end
|
128
|
+
|
129
|
+
def rbd_cache_name
|
130
|
+
options['rbd_cache_name']
|
131
|
+
end
|
132
|
+
|
133
|
+
def rbd_clone_snapshot(cache=rbd_cache_name)
|
134
|
+
"#{cache}@#{rbd_base_name}"
|
135
|
+
end
|
136
|
+
|
137
|
+
def rbd_uri(image_spec)
|
138
|
+
URI.join('rbd:///', image_spec)
|
139
|
+
end
|
140
|
+
|
141
|
+
def rbd_sequence_complete?
|
142
|
+
from.path.include?(to.path)
|
143
|
+
end
|
144
|
+
|
116
145
|
def rbd_id
|
117
146
|
'libvirt'
|
118
147
|
end
|
148
|
+
|
149
|
+
def in_rbd_cache?
|
150
|
+
options['in_rbd_cache']
|
151
|
+
end
|
152
|
+
|
153
|
+
def not_in_rbd_cache?
|
154
|
+
options['in_rbd_cache'] == false
|
155
|
+
end
|
156
|
+
|
157
|
+
def rbd_snapshot_spec?(uri)
|
158
|
+
uri.scheme == 'rbd' && uri.path.include?('@')
|
159
|
+
end
|
160
|
+
|
161
|
+
def rbd_cache_image_exists?(target)
|
162
|
+
command = "rbd status --id #{rbd_id} --format json #{target} 2>/dev/null"
|
163
|
+
if dry_run?
|
164
|
+
if options['dry-cache'] == :partial_rbd && options['cache_name'] !~ /srv-...../
|
165
|
+
command = "exit 0"
|
166
|
+
else
|
167
|
+
command = "exit 2"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
sh!(command)
|
171
|
+
true
|
172
|
+
rescue Methadone::FailedCommandError
|
173
|
+
false
|
174
|
+
end
|
175
|
+
|
176
|
+
def in_rbd_cache(target)
|
177
|
+
result = false
|
178
|
+
if dry_run?
|
179
|
+
result = options['dry-cache'] == :rbd && options['cache_name'] !~ /srv-...../
|
180
|
+
else
|
181
|
+
sh "rbd snap ls --id #{rbd_id} --format json #{target} 2>/dev/null" do |stdout|
|
182
|
+
result = JSON.parse(stdout).any? { |x| x['name'] == rbd_base_name }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
result && rbd_clone_snapshot(target)
|
186
|
+
end
|
119
187
|
end
|
120
188
|
end
|
@@ -4,19 +4,18 @@ module Uricp::Strategy
|
|
4
4
|
class PipedCache
|
5
5
|
include Uricp::Strategy::Common
|
6
6
|
include Uricp::Strategy::CacheCommon
|
7
|
+
include Methadone::SH
|
7
8
|
|
8
9
|
def appropriate?
|
9
|
-
|
10
|
+
with_active_cache do
|
10
11
|
case from.scheme
|
11
12
|
when 'pipe'
|
12
13
|
validate_cache!
|
13
14
|
return proposal
|
14
15
|
end
|
15
16
|
debug "#{self.class.name}: not appropriate"
|
16
|
-
|
17
|
-
debug "#{self.class.name}: no cacheing requested"
|
17
|
+
false
|
18
18
|
end
|
19
|
-
false
|
20
19
|
end
|
21
20
|
|
22
21
|
def command
|
@@ -26,6 +25,10 @@ module Uricp::Strategy
|
|
26
25
|
def proposal
|
27
26
|
@proposed_options = options.dup
|
28
27
|
@proposed_options['sweep'] = [temp_cache_file, cache_file]
|
28
|
+
image_spec_to_check = rbd_cache_image_spec(to)
|
29
|
+
if to.scheme == 'rbd' && !rbd_cache_image_exists?(image_spec_to_check)
|
30
|
+
@proposed_options['rbd_cache_name'] = image_spec_to_check
|
31
|
+
end
|
29
32
|
@proposed_options.delete('cache')
|
30
33
|
@proposed_options.delete('cache_name')
|
31
34
|
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,39 @@
|
|
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
|
+
if rbd_cache_image_exists?(cache_target) || in_rbd_cache(cache_target)
|
19
|
+
debug "#{self.class.name}: Unexpected existing cache entry for #{options['to_uri']}"
|
20
|
+
unsupported_transfer
|
21
|
+
end
|
22
|
+
proposal(cache_target)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def command
|
27
|
+
':;'
|
28
|
+
end
|
29
|
+
|
30
|
+
def proposal(cache_check)
|
31
|
+
@proposed_options = options.dup
|
32
|
+
@proposed_options['rbd_cache_target'] = rbd_uri(cache_check)
|
33
|
+
@proposed_options.delete('cache')
|
34
|
+
@proposed_options.delete('cache_name')
|
35
|
+
@proposed_options.delete('dry-cache')
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
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
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Uricp::Strategy
|
2
|
+
class RbdCachedPut
|
3
|
+
include Uricp::Strategy::Common
|
4
|
+
include Uricp::Strategy::CacheCommon
|
5
|
+
|
6
|
+
def appropriate?
|
7
|
+
return proposal if to.scheme == 'rbd' &&
|
8
|
+
rbd_snapshot_spec?(from) &&
|
9
|
+
rbd_cache_name.nil? &&
|
10
|
+
!rbd_sequence_complete?
|
11
|
+
|
12
|
+
debug "#{self.class.name}: not appropriate"
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def command
|
17
|
+
"rbd clone --id #{rbd_id} '#{rbd_image_spec(from)}' '#{rbd_image_spec(to)}';"
|
18
|
+
end
|
19
|
+
|
20
|
+
def proposal
|
21
|
+
@proposed_options = options.dup
|
22
|
+
@proposed_options['from_uri'] = to
|
23
|
+
if options['rbd_cache_target']
|
24
|
+
@proposed_options['to_uri'] = options['rbd_cache_target']
|
25
|
+
@proposed_options['rbd_cache_name'] = rbd_image_spec(to)
|
26
|
+
@proposed_options.delete('rbd_cache_target')
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Uricp::Strategy
|
2
|
-
class
|
2
|
+
class RbdPut
|
3
3
|
include Uricp::Strategy::Common
|
4
4
|
|
5
5
|
def appropriate?
|
@@ -7,16 +7,18 @@ module Uricp::Strategy
|
|
7
7
|
debug "#{self.class.name}: not ready to upload"
|
8
8
|
return false
|
9
9
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
unless rbd_cache_name
|
11
|
+
case from.scheme
|
12
|
+
when 'pipe', 'file'
|
13
|
+
return proposal if to.scheme == 'rbd'
|
14
|
+
end
|
13
15
|
end
|
14
16
|
debug "#{self.class.name}: not appropriate"
|
15
17
|
false
|
16
18
|
end
|
17
19
|
|
18
20
|
def command
|
19
|
-
"rbd import --no-progress --id #{rbd_id} #{data_source} '#{
|
21
|
+
"rbd import --no-progress --id #{rbd_id} #{data_source} '#{rbd_image_spec(to)}';"
|
20
22
|
end
|
21
23
|
|
22
24
|
def proposal
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'json'
|
2
|
+
module Uricp::Strategy
|
3
|
+
class RbdSnap
|
4
|
+
include Uricp::Strategy::Common
|
5
|
+
include Uricp::Strategy::CacheCommon
|
6
|
+
include Methadone::SH
|
7
|
+
|
8
|
+
def appropriate?
|
9
|
+
without_active_cache do
|
10
|
+
if from.scheme == 'rbd' &&
|
11
|
+
options['rbd_snapshot'].nil? &&
|
12
|
+
!rbd_snapshot_spec?(from) &&
|
13
|
+
(rbd_cache_name.nil? ||
|
14
|
+
!from.path.include?(rbd_cache_name))
|
15
|
+
if snap_in_progress?
|
16
|
+
debug "#{self.class.name}: detected snapshot in progress"
|
17
|
+
else
|
18
|
+
return proposal unless sequence_complete?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
debug "#{self.class.name}: not appropriate"
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def command
|
27
|
+
"rbd snap create --id #{rbd_id} '#{rbd_upload_snapshot(from)}';" \
|
28
|
+
"rbd snap protect --id #{rbd_id} '#{rbd_upload_snapshot(from)}';" \
|
29
|
+
end
|
30
|
+
|
31
|
+
def proposal
|
32
|
+
@proposed_options = options.dup
|
33
|
+
@proposed_options['from_uri'] = rbd_uri(rbd_upload_snapshot(from))
|
34
|
+
if options['rbd_cache_target']
|
35
|
+
@proposed_options['to_uri'] = options['rbd_cache_target']
|
36
|
+
@proposed_options['rbd_cache_target'] = to
|
37
|
+
else
|
38
|
+
@proposed_options['rbd_snapshot'] = rbd_upload_snapshot(from) unless to.scheme == 'rbd'
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def rbd_upload_snapshot(uri)
|
44
|
+
"#{rbd_image_spec(uri)}@#{rbd_snapshot_name}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def snap_in_progress?
|
48
|
+
return false if dry_run?
|
49
|
+
|
50
|
+
result = false
|
51
|
+
sh "rbd snap ls --id #{rbd_id} --format json #{rbd_image_spec(from)} 2>/dev/null" do |stdout|
|
52
|
+
result = JSON.parse(stdout).any? { |x| x['name'] == rbd_snapshot_name }
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -3,13 +3,14 @@ module Uricp::Strategy
|
|
3
3
|
include Uricp::Strategy::Common
|
4
4
|
|
5
5
|
def appropriate?
|
6
|
-
return proposal if options['rbd_snapshot'] &&
|
6
|
+
return proposal if options['rbd_snapshot'] && rbd_sequence_complete?
|
7
7
|
|
8
8
|
debug "#{self.class.name}: not appropriate"
|
9
9
|
false
|
10
10
|
end
|
11
11
|
|
12
12
|
def command
|
13
|
+
"rbd snap unprotect --id #{rbd_id} '#{options['rbd_snapshot']}';" \
|
13
14
|
"rbd snap rm --id #{rbd_id} '#{options['rbd_snapshot']}';"
|
14
15
|
end
|
15
16
|
|
data/lib/uricp/uri_strategy.rb
CHANGED
@@ -25,6 +25,10 @@ module Uricp
|
|
25
25
|
|
26
26
|
# This is an ordered list from the most specific to the most general
|
27
27
|
STRATEGIES = [
|
28
|
+
Strategy::RbdCachedGet,
|
29
|
+
Strategy::RbdCacheClone,
|
30
|
+
Strategy::RbdCacheCheck,
|
31
|
+
Strategy::RbdSnap,
|
28
32
|
Strategy::CachedGet,
|
29
33
|
Strategy::PipedRemoteGet,
|
30
34
|
Strategy::PipedRbdGet,
|
@@ -35,7 +39,10 @@ module Uricp
|
|
35
39
|
Strategy::LocalConvert,
|
36
40
|
Strategy::LocalLink,
|
37
41
|
Strategy::PipedCompress,
|
38
|
-
Strategy::
|
42
|
+
Strategy::RbdCacheUpload,
|
43
|
+
Strategy::RbdCachedPut,
|
44
|
+
Strategy::RbdPut,
|
45
|
+
Strategy::RbdCacheBaseSnap,
|
39
46
|
Strategy::SegmentedRemotePut,
|
40
47
|
Strategy::RemotePut,
|
41
48
|
Strategy::PipedLocalCompress,
|
data/lib/uricp/version.rb
CHANGED
data/lib/uricp.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
|
-
|
1
|
+
module Uricp
|
2
|
+
UnsupportedURLtype = Class.new(ArgumentError)
|
3
|
+
MissingCache = Class.new(ArgumentError)
|
4
|
+
UnsupportedConversion = Class.new(ArgumentError)
|
5
|
+
ConversionRequired = Class.new(ArgumentError)
|
6
|
+
end
|
7
|
+
|
2
8
|
require 'uricp/curl_primitives'
|
9
|
+
require 'uricp/orbit_auth'
|
3
10
|
require 'uricp/strategy/common'
|
4
11
|
require 'uricp/strategy/cache_common'
|
12
|
+
require 'uricp/strategy/cached_get'
|
13
|
+
require 'uricp/strategy/cleaner'
|
5
14
|
require 'uricp/strategy/local_convert'
|
6
15
|
require 'uricp/strategy/local_link'
|
7
16
|
require 'uricp/strategy/piped_cache'
|
8
17
|
require 'uricp/strategy/piped_cache_convert'
|
9
|
-
require 'uricp/strategy/piped_local_get'
|
10
|
-
require 'uricp/strategy/piped_rbd_get'
|
11
|
-
require 'uricp/strategy/piped_local_put'
|
12
|
-
require 'uricp/strategy/piped_remote_get'
|
13
18
|
require 'uricp/strategy/piped_compress'
|
14
19
|
require 'uricp/strategy/piped_decompress'
|
15
|
-
require 'uricp/strategy/piped_local_decompress'
|
16
20
|
require 'uricp/strategy/piped_local_compress'
|
17
|
-
require 'uricp/strategy/
|
18
|
-
require 'uricp/strategy/
|
19
|
-
require 'uricp/strategy/
|
20
|
-
require 'uricp/strategy/
|
21
|
+
require 'uricp/strategy/piped_local_decompress'
|
22
|
+
require 'uricp/strategy/piped_local_get'
|
23
|
+
require 'uricp/strategy/piped_local_put'
|
24
|
+
require 'uricp/strategy/piped_rbd_get'
|
25
|
+
require 'uricp/strategy/piped_remote_get'
|
26
|
+
require 'uricp/strategy/rbd_cache_base_snap'
|
27
|
+
require 'uricp/strategy/rbd_cache_check'
|
28
|
+
require 'uricp/strategy/rbd_cache_clone'
|
29
|
+
require 'uricp/strategy/rbd_cached_get'
|
30
|
+
require 'uricp/strategy/rbd_cached_put'
|
31
|
+
require 'uricp/strategy/rbd_cache_upload'
|
32
|
+
require 'uricp/strategy/rbd_put'
|
33
|
+
require 'uricp/strategy/rbd_snap'
|
21
34
|
require 'uricp/strategy/rbd_sweeper'
|
35
|
+
require 'uricp/strategy/remote_put'
|
36
|
+
require 'uricp/strategy/segmented_remote_put'
|
22
37
|
require 'uricp/strategy/sweeper'
|
23
|
-
require 'uricp/strategy/cleaner'
|
24
38
|
require 'uricp/uri_strategy'
|
25
|
-
require 'uricp/
|
26
|
-
|
27
|
-
module Uricp
|
28
|
-
UnsupportedURLtype = Class.new(ArgumentError)
|
29
|
-
MissingCache = Class.new(ArgumentError)
|
30
|
-
UnsupportedConversion = Class.new(ArgumentError)
|
31
|
-
ConversionRequired = Class.new(ArgumentError)
|
32
|
-
end
|
39
|
+
require 'uricp/version'
|