Class: OsCtld::Commands::Container::LocalTransfer::Base
- Inherits:
-
Logged
- Object
- Base
- Logged
- OsCtld::Commands::Container::LocalTransfer::Base
show all
- Includes:
- OsCtl::Lib::Utils::Log, OsCtl::Lib::Utils::System
- Defined in:
- lib/osctld/commands/container/local_transfer/base.rb
Instance Attribute Summary
Attributes inherited from Base
#client, #client_handler, #id, #opts
Instance Method Summary
collapse
Methods inherited from Logged
#base_execute
Methods inherited from Base
#base_execute, #call_cmd, #call_cmd!, #error, #error!, #execute, handle, #handled, #indirect?, #initialize, #manipulate, #manipulation_holder, #ok, #progress, #request_stop, run, run!
Instance Method Details
#build_dataset_map(source_ct, target_ct) ⇒ Object
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 72
def build_dataset_map(source_ct, target_ct)
root = LocalTransfer::Log::Dataset.new(
relative_name: '/',
source: source_ct.dataset.name,
target: target_ct.dataset.name
)
children = source_ct.dataset.descendants.map do |src_ds|
LocalTransfer::Log::Dataset.new(
relative_name: src_ds.relative_name,
source: src_ds.name,
target: File.join(target_ct.dataset.name, src_ds.relative_name)
)
end
[root, *children]
end
|
#cleanup_target_container!(log) ⇒ Object
173
174
175
176
177
178
179
180
181
182
183
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 173
def cleanup_target_container!(log)
target = begin
target_ct(log)
rescue CommandFailed
nil
end
return unless target
builder = Container::Builder.new(target.new_run_conf, cmd: self)
builder.cleanup(dataset: !log.opts.target_dataset_custom)
end
|
#clear_failed_state_snapshot(ct, log) ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 144
def clear_failed_state_snapshot(ct, log)
snap = log.state_snapshot
return if snap.nil?
progress("Removing failed cutover snapshot #{snap}")
log.opts.datasets.each do |pair|
zfs(:destroy, nil, "#{pair.source}@#{snap}", valid_rcs: [1])
zfs(:destroy, nil, "#{pair.target}@#{snap}", valid_rcs: [1])
end
ct.exclusively do
ct.local_transfer_log.state_snapshot = nil
ct.save_config
end
end
|
#complete_target!(log) ⇒ Object
56
57
58
59
60
61
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 56
def complete_target!(log)
ct = ensure_target_staged_or_complete!(log)
ct.state = :complete if ct.state == :staged
ct
end
|
#destroy_local_transfer_snapshots(log) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 161
def destroy_local_transfer_snapshots(log)
snaps = log.snapshots.dup
snaps << log.state_snapshot if log.state_snapshot
log.opts.datasets.each do |pair|
snaps.reverse_each do |snap|
zfs(:destroy, nil, "#{pair.source}@#{snap}", valid_rcs: [1])
zfs(:destroy, nil, "#{pair.target}@#{snap}", valid_rcs: [1])
end
end
end
|
#ensure_target_staged_or_complete!(log) ⇒ Object
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 44
def ensure_target_staged_or_complete!(log)
ct = target_ct(log)
ct.exclusively do
unless %i[staged stopped].include?(ct.state)
error!('target container is not staged')
end
end
ct
end
|
#find ⇒ Object
13
14
15
16
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 13
def find
ct = DB::Containers.find(opts[:id], opts[:pool])
ct || error!('container not found')
end
|
#force_writeout(ct) ⇒ Object
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 133
def force_writeout(ct)
return unless Daemon.get.config.writeout_dirtied_pages?
begin
ct.unmount(force: true)
rescue SystemCommandFailed => e
log(:warn, ct, "Unable to unmount dataset for writeback: #{e.message}")
ct.mount(force: true)
end
end
|
#operation ⇒ Object
20
21
22
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 20
def operation
raise NotImplementedError
end
|
#require_local_transfer_log!(ct) ⇒ Object
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 24
def require_local_transfer_log!(ct)
log = ct.local_transfer_log
error!('invalid local transfer sequence') unless log
unless log.opts.operation == operation
error!("local transfer is for #{log.opts.operation}, not #{operation}")
end
log
end
|
#snapshot_datasets(log, snap) ⇒ Object
104
105
106
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 104
def snapshot_datasets(log, snap)
zfs(:snapshot, nil, log.opts.datasets.map { |ds| "#{ds.source}@#{snap}" }.join(' '))
end
|
#snapshot_name(kind) ⇒ Object
99
100
101
102
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 99
def snapshot_name(kind)
prefix = operation == :copy ? 'osctl-copy' : 'osctl-move'
"#{prefix}-#{kind}-#{Time.now.to_i}-#{SecureRandom.hex(4)}"
end
|
#start_target!(log) ⇒ Object
63
64
65
66
67
68
69
70
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 63
def start_target!(log)
call_cmd!(
Commands::Container::Start,
id: log.opts.target_id,
pool: log.opts.target_pool,
force: true
)
end
|
#target_ct(log) ⇒ Object
39
40
41
42
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 39
def target_ct(log)
pool = target_pool(log)
DB::Containers.find(log.opts.target_id, pool) || error!('target container not found')
end
|
#target_pool(log) ⇒ Object
35
36
37
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 35
def target_pool(log)
DB::Pools.find(log.opts.target_pool) || error!('target pool not found')
end
|
#transfer_dataset(pair, snapshot, from_snapshot: nil) ⇒ Object
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 108
def transfer_dataset(pair, snapshot, from_snapshot: nil)
src = OsCtl::Lib::Zfs::Dataset.new(pair.source, base: pair.source)
dst = OsCtl::Lib::Zfs::Dataset.new(pair.target, base: pair.target)
progress("Copying dataset #{pair.relative_name}")
stream = OsCtl::Lib::Zfs::Stream.new(
src,
snapshot,
from_snapshot,
intermediary: false
)
stream.progress do |total, _transfered, changed|
progress(type: :progress, data: {
time: Time.now.to_i,
size: stream.size,
transfered: total,
changed:
})
end
stream.send_recv(dst.name)
end
|
#validate_dataset_layout!(ct) ⇒ Object
90
91
92
93
94
95
96
97
|
# File 'lib/osctld/commands/container/local_transfer/base.rb', line 90
def validate_dataset_layout!(ct)
expected = ct.local_transfer_log.opts.datasets.map(&:source).sort
actual = ct.datasets.map(&:name).sort
return if expected == actual
error!('container dataset layout changed since transfer was prepared; cancel and start again')
end
|