Class: OsCtld::Assets::Dataset

Inherits:
Base
  • Object
show all
Defined in:
lib/osctld/assets/dataset.rb

Instance Attribute Summary

Attributes inherited from Base

#errors, #opts, #path

Instance Method Summary collapse

Methods inherited from Base

#add_error, register, #run_validation, #state, #type, #valid?, #validate?, #validate_block

Constructor Details

#initialize(path, opts) ⇒ Dataset

Returns a new instance of Dataset.

Parameters:

  • opts (Hash)

    options

Options Hash (opts):

  • uidmap (Array, nil)
  • gidmap (Array, nil)
  • properties (Hash, nil)
  • user (Integer, nil)
  • group (Integer, nil)
  • mode (Integer, nil)
  • mode_bit_and (Integer, nil)


16
17
18
# File 'lib/osctld/assets/dataset.rb', line 16

def initialize(path, opts) # rubocop:disable all
  super
end

Instance Method Details

#get_modeObject (protected)



100
101
102
103
104
105
# File 'lib/osctld/assets/dataset.rb', line 100

def get_mode
  st = get_stat

  # Extract permission bits, see man inode(7)
  st ? st.mode & 0o7777 : nil
end

#get_statObject (protected)



94
95
96
97
98
# File 'lib/osctld/assets/dataset.rb', line 94

def get_stat
  @stat ||= File.stat(@mountpoint)
rescue Errno::ENOENT
  @stat = nil
end

#make_ugid_map(arr) ⇒ Object (protected)



107
108
109
110
111
# File 'lib/osctld/assets/dataset.rb', line 107

def make_ugid_map(arr)
  arr.map do |entry|
    entry.join(':')
  end.join(',')
end

#prefetch_zfsObject



20
21
22
23
24
25
26
# File 'lib/osctld/assets/dataset.rb', line 20

def prefetch_zfs
  prefetch_props = %w[mountpoint uidmap gidmap]
  prefetch_props.concat(opts[:properties].keys) if opts[:properties]
  prefetch_props.uniq!

  [[path], prefetch_props]
end

#validate(run) ⇒ Object (protected)



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/osctld/assets/dataset.rb', line 30

def validate(run)
  ds = run.dataset_tree[path]

  if ds.nil?
    add_error('does not exist')
    return super
  end

  @mountpoint = ds.properties['mountpoint']
  uidmap = ds.properties['uidmap']
  gidmap = ds.properties['gidmap']

  stat = get_stat
  mode = get_mode

  if stat && mode
    if opts[:user] && stat.uid != opts[:user]
      add_error("invalid owner: expected #{opts[:user]}, got #{stat.uid}")
    end

    if opts[:group] && stat.gid != opts[:group]
      add_error("invalid group: expected #{opts[:group]}, got #{stat.gid}")
    end

    if opts[:mode] && mode != opts[:mode]
      add_error("invalid mode: expected #{opts[:mode].to_s(8)}, got #{mode.to_s(8)}")
    end

    if opts[:mode_bit_and] && (mode & opts[:mode_bit_and]) != opts[:mode_bit_and]
      add_error("invalid mode: bitwise and with #{opts[:mode_bit_and].to_s(8)} does not match")
    end
  else
    add_error("mountpoint not found at #{@mountpoint.inspect}")
  end

  if opts[:uidmap]
    expected_uidmap = make_ugid_map(opts[:uidmap])

    if expected_uidmap != uidmap
      add_error("invalid uidmap: expected #{expected_uidmap}, got #{uidmap}")
    end
  end

  if opts[:gidmap]
    expected_gidmap = make_ugid_map(opts[:gidmap])

    if expected_gidmap != gidmap
      add_error("invalid gidmap: expected #{expected_gidmap}, got #{gidmap}")
    end
  end

  if opts[:properties]
    opts[:properties].each do |prop, expected_v|
      v = ds.properties[prop]

      if v != expected_v
        add_error("invalid ZFS property #{prop}: expected #{expected_v}, got #{v}")
      end
    end
  end

  super
end