Class: OsCtl::Lib::Zfs::Dataset
- Inherits:
-
Object
- Object
- OsCtl::Lib::Zfs::Dataset
- Includes:
- Utils::Log, Utils::System
- Defined in:
- lib/libosctl/zfs/dataset.rb
Overview
Class representing a single ZFS dataset
Instance Attribute Summary collapse
-
#base ⇒ String
readonly
Base name, i.e.
-
#name ⇒ String
readonly
Full dataset name.
-
#pool ⇒ String
readonly
Zpool name.
-
#properties ⇒ Hash<String, String>
readonly
Dataset properties, only loaded properties are present.
Instance Method Summary collapse
-
#base_name ⇒ String
Return the last component of the dataset name.
-
#children ⇒ Array<Zfs::Dataset>
Return all direct children.
- #create!(**opts) ⇒ Object
- #create_private!(**opts) ⇒ Object
-
#descendants ⇒ Array<Zfs::Dataset>
Return all direct and indirect children.
- #destroy!(**opts) ⇒ Object
- #exist? ⇒ Boolean
-
#export ⇒ Hash
Export to client.
-
#initialize(name, base: '', properties: {}, cache: nil) ⇒ Dataset
constructor
A new instance of Dataset.
- #is_pool? ⇒ Boolean
-
#list(**opts) ⇒ Array<Zfs::Dataset>
List descendant datasets and read selected properties.
-
#mount(recursive: false) ⇒ Object
Ensure the dataset is mounted.
-
#mounted?(recursive: false) ⇒ Boolean
Check if the dataset is mounted.
- #mountpoint ⇒ String
- #on_pool?(pool) ⇒ Boolean
-
#parent ⇒ Zfs::Dataset
Return the direct parent.
-
#parents ⇒ Array<Zfs::Dataset>
Return all parent datasets, up to the root.
- #private_path ⇒ String
-
#relative_name ⇒ String
Return the dataset name relative to the base.
-
#relative_parent ⇒ Zfs::Dataset?
Return the dataset's parent relative to the base.
-
#relative_parents ⇒ Array<Zfs::Dataset>
Return the parents up to the base.
- #root? ⇒ Boolean
- #snapshots ⇒ Array<Zfs::Snapshot>
- #subdataset_of?(dataset) ⇒ Boolean
- #to_s ⇒ Object
-
#unmount(recursive: false) ⇒ Object
Ensure the dataset is unmounted.
Methods included from Utils::System
#repeat_on_failure, #syscmd, #zfs
Methods included from Utils::Log
Constructor Details
#initialize(name, base: '', properties: {}, cache: nil) ⇒ Dataset
Returns a new instance of Dataset.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/libosctl/zfs/dataset.rb', line 29 def initialize(name, base: '', properties: {}, cache: nil) @name = name @pool = name.split('/').first @base = base @properties = properties if properties[:mountpoint] @mountpoint = properties[:mountpoint] elsif cache ds = cache[name] if ds && ds.properties[:mountpoint] @mountpoint = ds.properties[:mountpoint] end end end |
Instance Attribute Details
#base ⇒ String (readonly)
Base name, i.e. path that this dataset is relative to
21 22 23 |
# File 'lib/libosctl/zfs/dataset.rb', line 21 def base @base end |
#name ⇒ String (readonly)
Full dataset name
9 10 11 |
# File 'lib/libosctl/zfs/dataset.rb', line 9 def name @name end |
#pool ⇒ String (readonly)
Zpool name
13 14 15 |
# File 'lib/libosctl/zfs/dataset.rb', line 13 def pool @pool end |
#properties ⇒ Hash<String, String> (readonly)
Dataset properties, only loaded properties are present
17 18 19 |
# File 'lib/libosctl/zfs/dataset.rb', line 17 def properties @properties end |
Instance Method Details
#base_name ⇒ String
Return the last component of the dataset name
256 257 258 |
# File 'lib/libosctl/zfs/dataset.rb', line 256 def base_name name.split('/').last end |
#children ⇒ Array<Zfs::Dataset>
Return all direct children
240 241 242 243 244 |
# File 'lib/libosctl/zfs/dataset.rb', line 240 def children ret = list(depth: 1) ret.shift # remove the current dataset ret end |
#create!(**opts) ⇒ Object
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/libosctl/zfs/dataset.rb', line 67 def create!(**opts) zfs_opts = [] zfs_opts << '-p' if opts[:parents] (opts[:properties] || {}).each do |k, v| zfs_opts << '-o' << "#{k}=#{v}" end zfs(:create, zfs_opts.join(' '), name) end |
#create_private!(**opts) ⇒ Object
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/libosctl/zfs/dataset.rb', line 81 def create_private!(**opts) if opts[:parents] parents.each do |ds| break if Dir.exist?(ds.private_path) ds.create_private! end end Dir.mkdir(private_path, 0750) end |
#descendants ⇒ Array<Zfs::Dataset>
Return all direct and indirect children
248 249 250 251 252 |
# File 'lib/libosctl/zfs/dataset.rb', line 248 def descendants ret = list ret.shift # remove the current dataset ret end |
#destroy!(**opts) ⇒ Object
94 95 96 |
# File 'lib/libosctl/zfs/dataset.rb', line 94 def destroy!(**opts) zfs(:destroy, opts[:recursive] ? '-r' : nil, name) end |
#exist? ⇒ Boolean
99 100 101 |
# File 'lib/libosctl/zfs/dataset.rb', line 99 def exist? zfs(:get, '-o value name', name, valid_rcs: [1]).success? end |
#export ⇒ Hash
Export to client
310 311 312 313 314 |
# File 'lib/libosctl/zfs/dataset.rb', line 310 def export ret = {name: relative_name, dataset: name} ret.update(properties) ret end |
#is_pool? ⇒ Boolean
55 56 57 |
# File 'lib/libosctl/zfs/dataset.rb', line 55 def is_pool? !@name.include?('/') end |
#list(**opts) ⇒ Array<Zfs::Dataset>
List descendant datasets and read selected properties
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/libosctl/zfs/dataset.rb', line 116 def list(**opts) include_self = opts.fetch(:include_self, true) zfs_opts = [ '-r', '-H', '-p', '-o', 'name,property,value', '-t', opts[:type] || 'filesystem' ] zfs_opts << '-d' << opts[:depth] if opts[:depth] properties = [] properties.concat(opts[:properties]) if opts[:properties] properties << 'name' if properties.empty? properties.uniq! zfs_opts << properties.map(&:to_s).join(',') ret = [] last = nil zfs(:get, zfs_opts.join(' '), name).output.strip.split("\n").each do |line| name, property, value = line.split next if !include_self && name == self.name if !last || last.name != name ret << last unless last.nil? if opts[:create] last = opts[:create].call(name) else last = self.class.new(name, base: base) end end next if property == 'name' last.properties[property.to_sym] = value end ret << last unless last.nil? ret end |
#mount(recursive: false) ⇒ Object
Ensure the dataset is mounted
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/libosctl/zfs/dataset.rb', line 174 def mount(recursive: false) zfs( :list, "-H -o name,mounted -t filesystem #{recursive ? '-r' : ''}", name, ).output.split("\n").each do |line| ds, mounted = line.split next if mounted == 'yes' zfs(:mount, nil, ds) end end |
#mounted?(recursive: false) ⇒ Boolean
Check if the dataset is mounted
204 205 206 207 208 209 210 |
# File 'lib/libosctl/zfs/dataset.rb', line 204 def mounted?(recursive: false) zfs( :get, "-H #{recursive ? '-r' : ''} -t filesystem -o value mounted", name ).output.split("\n").all? { |v| v == 'yes' } end |
#mountpoint ⇒ String
160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/libosctl/zfs/dataset.rb', line 160 def mountpoint if @mountpoint return @mountpoint elsif properties[:mountpoint] @mountpoint = properties[:mountpoint] else @mountpoint = zfs(:get, '-H -o value mountpoint', name).output.strip end end |
#on_pool?(pool) ⇒ Boolean
51 52 53 |
# File 'lib/libosctl/zfs/dataset.rb', line 51 def on_pool?(pool) @pool == pool end |
#parent ⇒ Zfs::Dataset
Return the direct parent
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/libosctl/zfs/dataset.rb', line 214 def parent parts = name.split('/') if parts.count == 1 nil else self.class.new(parts[0..-2].join('/'), base: base) end end |
#parents ⇒ Array<Zfs::Dataset>
Return all parent datasets, up to the root
227 228 229 230 231 232 233 234 235 236 |
# File 'lib/libosctl/zfs/dataset.rb', line 227 def parents ret = [] parts = name.split('/')[0..-2] parts.each_with_index do |v, i| ret << self.class.new(parts[0..i].join('/'), base: base) end ret.reverse! end |
#private_path ⇒ String
104 105 106 |
# File 'lib/libosctl/zfs/dataset.rb', line 104 def private_path File.join(mountpoint, 'private') end |
#relative_name ⇒ String
Return the dataset name relative to the base
262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/libosctl/zfs/dataset.rb', line 262 def relative_name return @relative_name if @relative_name @relative_name = if base == name '/' elsif !name.start_with?("#{base}/") fail "invalid base '#{base}' for '#{name}'" else name[(base.length+1)..-1] end end |
#relative_parent ⇒ Zfs::Dataset?
Return the dataset's parent relative to the base
278 279 280 281 282 283 284 285 286 |
# File 'lib/libosctl/zfs/dataset.rb', line 278 def relative_parent ret = parent @relative_parent = if ret.name.length < @base.length nil else ret end end |
#relative_parents ⇒ Array<Zfs::Dataset>
Return the parents up to the base
290 291 292 |
# File 'lib/libosctl/zfs/dataset.rb', line 290 def relative_parents parents.take_while { |ds| ds.name.length >= @base.length } end |
#root? ⇒ Boolean
295 296 297 |
# File 'lib/libosctl/zfs/dataset.rb', line 295 def root? name == base || !name.index('/') end |
#snapshots ⇒ Array<Zfs::Snapshot>
300 301 302 303 304 305 306 |
# File 'lib/libosctl/zfs/dataset.rb', line 300 def snapshots list( type: 'snapshot', depth: 1, create: ->(name) { Zfs::Snapshot.new(self, name.split('@')[1]) } ) end |
#subdataset_of?(dataset) ⇒ Boolean
60 61 62 |
# File 'lib/libosctl/zfs/dataset.rb', line 60 def subdataset_of?(dataset) name.start_with?("#{dataset.name}/") end |
#to_s ⇒ Object
46 47 48 |
# File 'lib/libosctl/zfs/dataset.rb', line 46 def to_s name end |
#unmount(recursive: false) ⇒ Object
Ensure the dataset is unmounted
189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/libosctl/zfs/dataset.rb', line 189 def unmount(recursive: false) zfs( :list, "-H -o name,mounted -t filesystem #{recursive ? '-r' : ''}", name, ).output.split("\n").reverse_each do |line| ds, mounted = line.split next if mounted != 'yes' zfs(:unmount, nil, ds) end end |