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

16877
FILE_MODE =

0644

33188

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.



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

def base_snap
  @base_snap
end

#ctObject (readonly, protected)

Returns the value of attribute ct.



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

def ct
  @ct
end

#datasetsObject (readonly, protected)

Returns the value of attribute datasets.



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

def datasets
  @datasets
end

#optsObject (readonly, protected)

Returns the value of attribute opts.



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

def opts
  @opts
end

#tarObject (readonly, protected)

Returns the value of attribute tar.



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

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



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

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



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

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
106
107
# 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
      fail "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

  if dump.container
    tar.add_file('config/container.yml', FILE_MODE) do |tf|
      tf.write(dump.container)
    end
  else
    fail 'container config not set'
  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 { |ds| ds.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)


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/libosctl/exporter/base.rb', line 111

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
      fail "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



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

def format; nil; end