Class: OsCtld::Commands::Dataset::Create

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

Instance Attribute Summary

Attributes inherited from Base

#client, #client_handler, #id, #opts

Instance Method Summary collapse

Methods inherited from Base

#base_execute, #call_cmd, #call_cmd!, #error, #error!, handle, #handled, #indirect?, #initialize, #manipulate, #manipulation_holder, #ok, #progress, #request_stop, run, run!

Constructor Details

This class inherits a constructor from OsCtld::Commands::Base

Instance Method Details

#executeObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
# File 'lib/osctld/commands/dataset/create.rb', line 7

def execute
  ct = DB::Containers.find(opts[:id], opts[:pool])
  return error('container not found') unless ct

  manipulate(ct) do
    wanted_ds = OsCtl::Lib::Zfs::Dataset.new(
      File.join(ct.dataset.name, opts[:name]),
      base: ct.dataset.name
    )
    parents = wanted_ds.relative_parents.reverse! # top-level to deepest level
    created = []

    begin
      (parents + [wanted_ds]).each do |ds|
        next if ds.exist?

        ds.create!(
          properties: {
            uidmap: ct.uid_map.map(&:to_s).join(','),
            gidmap: ct.gid_map.map(&:to_s).join(','),
            canmount: 'noauto'
          }
        )
        ds.mount
        ds.create_private!

        created << ds
      end
    rescue SystemCommandFailed
      error!('unable to create dataset, perhaps a parent dataset is missing?')
    end

    next ok if created.empty? || !opts[:mount]

    # Mount newly created parents
    created[0..-2].each do |ds|
      parent_mnt = parent_mountpoint(ct, ds)
      next unless parent_mnt

      mount(ct, ds, File.join(parent_mnt, ds.base_name))
    end

    # Mount target dataset
    parent_mnt = parent_mountpoint(ct, wanted_ds)

    if opts[:mountpoint]
      mount(ct, wanted_ds, opts[:mountpoint])

    elsif parent_mnt
      mount(ct, wanted_ds, File.join(parent_mnt, wanted_ds.base_name))
    end

    ok
  end
end

#mount(ct, ds, mountpoint) ⇒ Object (protected)



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/osctld/commands/dataset/create.rb', line 65

def mount(ct, ds, mountpoint)
  call_cmd!(
    Commands::Container::MountDataset,
    id: ct.id,
    pool: ct.pool.name,
    name: ds.relative_name,
    mountpoint:,
    mode: 'rw',
    automount: opts[:mount]
  )
end

#parent_mountpoint(ct, ds) ⇒ Object (protected)



77
78
79
80
81
82
83
84
85
86
# File 'lib/osctld/commands/dataset/create.rb', line 77

def parent_mountpoint(ct, ds)
  parent = ds.parent

  if parent.root?
    '/'
  else
    mnt = ct.mounts.detect { |m| m.dataset.name == parent.name }
    mnt && mnt.mountpoint
  end
end