Class: OsCtld::Commands::Container::LocalTransfer::Base
- Inherits:
-
Logged
- Object
- Commands::Base
- Logged
- OsCtld::Commands::Container::LocalTransfer::Base
- Includes:
- OsCtl::Lib::Utils::Log, OsCtl::Lib::Utils::System
- Defined in:
- lib/osctld/commands/container/local_transfer/base.rb
Instance Method Summary collapse
- #build_dataset_map(source_ct, target_ct) ⇒ Object protected
- #cleanup_target_container!(log) ⇒ Object protected
- #clear_failed_state_snapshot(ct, log) ⇒ Object protected
- #complete_target!(log) ⇒ Object protected
- #destroy_local_transfer_snapshots(log) ⇒ Object protected
- #ensure_target_staged_or_complete!(log) ⇒ Object protected
- #find ⇒ Object
- #force_writeout(ct) ⇒ Object protected
- #operation ⇒ Object protected
- #require_local_transfer_log!(ct) ⇒ Object protected
- #snapshot_datasets(log, snap) ⇒ Object protected
- #snapshot_name(kind) ⇒ Object protected
- #start_target!(log) ⇒ Object protected
- #target_ct(log) ⇒ Object protected
- #target_pool(log) ⇒ Object protected
- #transfer_dataset(pair, snapshot, from_snapshot: nil) ⇒ Object protected
- #validate_dataset_layout!(ct) ⇒ Object protected
Methods inherited from Logged
Instance Method Details
#build_dataset_map(source_ct, target_ct) ⇒ Object (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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.}") ct.mount(force: true) end end |
#operation ⇒ Object (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 (protected)
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 |