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
258 259 260 |
# File 'lib/libosctl/zfs/dataset.rb', line 258 def base_name name.split('/').last end |
#children ⇒ Array<Zfs::Dataset>
Return all direct children
242 243 244 245 246 |
# File 'lib/libosctl/zfs/dataset.rb', line 242 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 91 |
# 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, 0o750) end |
#descendants ⇒ Array<Zfs::Dataset>
Return all direct and indirect children
250 251 252 253 254 |
# File 'lib/libosctl/zfs/dataset.rb', line 250 def descendants ret = list ret.shift # remove the current dataset ret end |
#destroy!(**opts) ⇒ Object
95 96 97 |
# File 'lib/libosctl/zfs/dataset.rb', line 95 def destroy!(**opts) zfs(:destroy, opts[:recursive] ? '-r' : nil, name) end |
#exist? ⇒ Boolean
100 101 102 |
# File 'lib/libosctl/zfs/dataset.rb', line 100 def exist? zfs(:get, '-o value name', name, valid_rcs: [1]).success? end |
#export ⇒ Hash
Export to client
312 313 314 315 316 |
# File 'lib/libosctl/zfs/dataset.rb', line 312 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
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 158 159 |
# File 'lib/libosctl/zfs/dataset.rb', line 117 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? last = if opts[:create] opts[:create].call(name) else self.class.new(name, 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
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/libosctl/zfs/dataset.rb', line 176 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
206 207 208 209 210 211 212 |
# File 'lib/libosctl/zfs/dataset.rb', line 206 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
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/libosctl/zfs/dataset.rb', line 162 def mountpoint if @mountpoint @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
216 217 218 219 220 221 222 223 224 225 |
# File 'lib/libosctl/zfs/dataset.rb', line 216 def parent parts = name.split('/') if parts.count == 1 nil else self.class.new(parts[0..-2].join('/'), base:) end end |
#parents ⇒ Array<Zfs::Dataset>
Return all parent datasets, up to the root
229 230 231 232 233 234 235 236 237 238 |
# File 'lib/libosctl/zfs/dataset.rb', line 229 def parents ret = [] parts = name.split('/')[0..-2] parts.each_with_index do |_v, i| ret << self.class.new(parts[0..i].join('/'), base:) end ret.reverse! end |
#private_path ⇒ String
105 106 107 |
# File 'lib/libosctl/zfs/dataset.rb', line 105 def private_path File.join(mountpoint, 'private') end |
#relative_name ⇒ String
Return the dataset name relative to the base
264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/libosctl/zfs/dataset.rb', line 264 def relative_name return @relative_name if @relative_name @relative_name = if base == name '/' elsif !name.start_with?("#{base}/") raise "invalid base '#{base}' for '#{name}'" else name[(base.length + 1)..] end end |
#relative_parent ⇒ Zfs::Dataset?
Return the dataset’s parent relative to the base
280 281 282 283 284 285 286 287 288 |
# File 'lib/libosctl/zfs/dataset.rb', line 280 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
292 293 294 |
# File 'lib/libosctl/zfs/dataset.rb', line 292 def relative_parents parents.take_while { |ds| ds.name.length >= @base.length } end |
#root? ⇒ Boolean
297 298 299 |
# File 'lib/libosctl/zfs/dataset.rb', line 297 def root? name == base || !name.index('/') end |
#snapshots ⇒ Array<Zfs::Snapshot>
302 303 304 305 306 307 308 |
# File 'lib/libosctl/zfs/dataset.rb', line 302 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
191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/libosctl/zfs/dataset.rb', line 191 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 |