Class: OsCtl::Lib::Exporter::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/libosctl/exporter/base.rb

Overview

Handles dumping containers into tar archives

This base class can dump only archive metadata and config files. To export the container’s rootfs, use either Zfs or Tar.

Direct Known Subclasses

Tar, Zfs

Defined Under Namespace

Classes: ConfigDump

Constant Summary collapse

BLOCK_SIZE =
32 * 1024
DIR_MODE =

0755

16_877
FILE_MODE =

0644

33_188

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ct, io, opts = {}) ⇒ Base

Returns a new instance of Base.

Parameters:

  • ct (Container)
  • io (IO)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • compression (Symbol)

    auto/off/gzip

  • compressed_send (Boolean)


35
36
37
38
39
40
# File 'lib/libosctl/exporter/base.rb', line 35

def initialize(ct, io, opts = {})
  @ct = ct
  @tar = Gem::Package::TarWriter.new(io)
  @opts = opts
  @datasets = []
end

Instance Attribute Details

#base_snapObject (readonly, protected)

Returns the value of attribute base_snap.



141
142
143
# File 'lib/libosctl/exporter/base.rb', line 141

def base_snap
  @base_snap
end

#ctObject (readonly, protected)

Returns the value of attribute ct.



141
142
143
# File 'lib/libosctl/exporter/base.rb', line 141

def ct
  @ct
end

#datasetsObject (readonly, protected)

Returns the value of attribute datasets.



141
142
143
# File 'lib/libosctl/exporter/base.rb', line 141

def datasets
  @datasets
end

#optsObject (readonly, protected)

Returns the value of attribute opts.



141
142
143
# File 'lib/libosctl/exporter/base.rb', line 141

def opts
  @opts
end

#tarObject (readonly, protected)

Returns the value of attribute tar.



141
142
143
# File 'lib/libosctl/exporter/base.rb', line 141

def tar
  @tar
end

Instance Method Details

#add_file_from_disk(src, dst) ⇒ Object (protected)

Add file from disk to the created tar archive

Parameters:

  • src (String)

    path on disk

  • dst (String)

    path in tar



146
147
148
149
150
151
152
# File 'lib/libosctl/exporter/base.rb', line 146

def add_file_from_disk(src, dst)
  st = File.stat(src)

  tar.add_file(dst, st.mode) do |tf|
    File.open(src, 'r') { |df| IO.copy_stream(df, tf) }
  end
end

#closeObject



133
134
135
# File 'lib/libosctl/exporter/base.rb', line 133

def close
  tar.close
end

#dump_configs {|dump| ... } ⇒ Object

Dump configuration of the container, its user and group

If no block is given, user/group/container configs are dumped as they are. Configs can be altered by passing a block, which will get ConfigDump as an argument.

Yield Parameters:



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/libosctl/exporter/base.rb', line 69

def dump_configs
  dump = ConfigDump.new
  tar.mkdir('config', DIR_MODE)

  if block_given?
    yield(dump)
  else
    dump.user(File.read(ct.user.config_path)) if ct.user
    dump.group(File.read(ct.group.config_path)) if ct.group

    if ct.respond_to?(:dump_config)
      dump.container(ConfigFile.dump_yaml(ct.dump_config))
    elsif ct.respond_to?(:config_path)
      dump.container(File.read(ct.config_path))
    else
      raise "don't know how to dump container config"
    end
  end

  if dump.user
    tar.add_file('config/user.yml', FILE_MODE) do |tf|
      tf.write(dump.user)
    end
  end

  if dump.group
    tar.add_file('config/group.yml', FILE_MODE) do |tf|
      tf.write(dump.group)
    end
  end

  raise 'container config not set' unless dump.container

  tar.add_file('config/container.yml', FILE_MODE) do |tf|
    tf.write(dump.container)
  end
end

#dump_metadata(type, opts = {}) ⇒ Object

Dump important metadata describing the archive

Parameters:

  • type ('skel', 'full')
  • opts (Hash) (defaults to: {})

    options

Options Hash (opts):

  • :id (String)

    custom container id

  • :user (String)

    custom user name

  • :group (String)

    custom group name



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/libosctl/exporter/base.rb', line 48

def (type, opts = {})
  tar.add_file('metadata.yml', FILE_MODE) do |tf|
    tf.write(ConfigFile.dump_yaml(
               'type' => type,
               'format' => format.to_s,
               'user' => opts[:user] || (ct.user && ct.user.name),
               'group' => opts[:group] || (ct.group && ct.group.name),
               'container' => opts[:id] || ct.id,
               'datasets' => datasets.map(&:relative_name),
               'exported_at' => Time.now.to_i
             ))
  end
end

#dump_user_hook_scripts(hook_scripts) ⇒ Object

Dump user script hooks, if there is at least one present

Parameters:

  • hook_scripts (#abs_path, #rel_path)


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/libosctl/exporter/base.rb', line 109

def dump_user_hook_scripts(hook_scripts)
  return if hook_scripts.empty?

  tar.mkdir('hooks', DIR_MODE)
  subdirs = []

  hook_scripts.each do |hs|
    slashes = hs.rel_path.count('/')

    if slashes > 1
      raise "unable to export hook at '#{hs.rel_path}': too many sublevels"
    elsif slashes == 1
      dir = File.dirname(hs.rel_path)

      unless subdirs.include?(dir)
        tar.mkdir(File.join('hooks', dir), DIR_MODE)
        subdirs << dir
      end
    end

    add_file_from_disk(hs.abs_path, File.join('hooks', hs.rel_path))
  end
end

#formatObject



137
# File 'lib/libosctl/exporter/base.rb', line 137

def format = nil