Class: OsCtld::Container::Builder
- Inherits:
-
Object
- Object
- OsCtld::Container::Builder
- Includes:
- OsCtl::Lib::Utils::Log, OsCtl::Lib::Utils::System, Utils::SwitchUser
- Defined in:
- lib/osctld/container/builder.rb
Constant Summary collapse
- ID_RX =
/^[a-z0-9_-]{1,100}$/i
Instance Attribute Summary collapse
-
#ctrc ⇒ Object
readonly
Returns the value of attribute ctrc.
-
#ds_builder ⇒ Object
readonly
protected
Returns the value of attribute ds_builder.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
Class Method Summary collapse
Instance Method Summary collapse
-
#cleanup(opts = {}) ⇒ Object
Remove a partially created container when the building process failed.
- #clear_snapshots(snaps) ⇒ Object
- #configure(distribution, version, arch) ⇒ Object
-
#copy_datasets(src, dst, from: nil) ⇒ String
Snapshot name.
- #create_dataset(ds, opts = {}) ⇒ Object
- #create_root_dataset(opts = {}) ⇒ Object
- #exist? ⇒ Boolean
- #from_local_archive(image, opts = {}) ⇒ Object
- #from_tar_stream(image, member, compression, ds = nil) ⇒ Object
- #get_distribution_info(image) ⇒ Object
- #group ⇒ Object
-
#initialize(ctrc, opts = {}) ⇒ Builder
constructor
A new instance of Builder.
- #monitor ⇒ Object
- #pool ⇒ Object
- #progress(msg) ⇒ Object protected
- #register ⇒ Object
- #setup_ct_dir ⇒ Object
- #setup_log_file ⇒ Object
- #setup_lxc_configs ⇒ Object
- #setup_lxc_home ⇒ Object
- #setup_rootfs ⇒ Object
- #setup_user_hook_script_dir ⇒ Object
- #shift_or_mount_dataset ⇒ Object
- #user ⇒ Object
- #valid? ⇒ Boolean
Methods included from Utils::SwitchUser
Constructor Details
#initialize(ctrc, opts = {}) ⇒ Builder
Returns a new instance of Builder.
34 35 36 37 38 39 |
# File 'lib/osctld/container/builder.rb', line 34 def initialize(ctrc, opts = {}) @ctrc = ctrc @opts = opts @errors = [] @ds_builder = Container::DatasetBuilder.new(cmd: opts[:cmd]) end |
Instance Attribute Details
#ctrc ⇒ Object (readonly)
Returns the value of attribute ctrc.
29 30 31 |
# File 'lib/osctld/container/builder.rb', line 29 def ctrc @ctrc end |
#ds_builder ⇒ Object (readonly, protected)
Returns the value of attribute ds_builder.
258 259 260 |
# File 'lib/osctld/container/builder.rb', line 258 def ds_builder @ds_builder end |
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
29 30 31 |
# File 'lib/osctld/container/builder.rb', line 29 def errors @errors end |
Class Method Details
.create(pool, id, user, group, dataset = nil, opts = {}) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/osctld/container/builder.rb', line 13 def self.create(pool, id, user, group, dataset = nil, opts = {}) ct = Container.new( pool, id, user, group, dataset || Container.default_dataset(pool, id), load: false, map_mode: opts[:map_mode] || 'native' ) ctrc = Container::RunConfiguration.new(ct) new(ctrc, opts) end |
Instance Method Details
#cleanup(opts = {}) ⇒ Object
Remove a partially created container when the building process failed
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/osctld/container/builder.rb', line 220 def cleanup(opts = {}) Console.remove(ctrc.ct) zfs(:destroy, '-r', ctrc.dataset, valid_rcs: [1]) if opts[:dataset] syscmd("rm -rf #{ctrc.lxc_dir} #{ctrc.ct.user_hook_script_dir}") FileUtils.rm_f(ctrc.log_path) FileUtils.rm_f(ctrc.config_path) DB::Containers.remove(ctrc.ct) begin if ctrc.group.has_containers?(ctrc.user) CGroup.rmpath_all(ctrc.ct.base_cgroup_path) else CGroup.rmpath_all(ctrc.ct.group.full_cgroup_path(ctrc.user)) end rescue SystemCallError # If some of the cgroups are busy, just leave them be end bashrc = File.join(ctrc.lxc_dir, '.bashrc') FileUtils.rm_f(bashrc) grp_dir = ctrc.group.userdir(ctrc.user) return unless !ctrc.group.has_containers?(ctrc.user) && Dir.exist?(grp_dir) Dir.rmdir(grp_dir) end |
#clear_snapshots(snaps) ⇒ Object
156 157 158 159 160 |
# File 'lib/osctld/container/builder.rb', line 156 def clear_snapshots(snaps) snaps.each do |snap| zfs(:destroy, nil, "#{ctrc.dataset}@#{snap}") end end |
#configure(distribution, version, arch) ⇒ Object
152 153 154 |
# File 'lib/osctld/container/builder.rb', line 152 def configure(distribution, version, arch) ctrc.ct.configure(distribution, version, arch) end |
#copy_datasets(src, dst, from: nil) ⇒ String
Returns snapshot name.
91 92 93 |
# File 'lib/osctld/container/builder.rb', line 91 def copy_datasets(src, dst, from: nil) ds_builder.copy_datasets(src, dst, from:) end |
#create_dataset(ds, opts = {}) ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/osctld/container/builder.rb', line 78 def create_dataset(ds, opts = {}) ds_builder.create_dataset( ds, parents: opts[:parents], uid_map: opts[:mapping] ? ctrc.uid_map : nil, gid_map: opts[:mapping] ? ctrc.gid_map : nil ) end |
#create_root_dataset(opts = {}) ⇒ Object
69 70 71 72 |
# File 'lib/osctld/container/builder.rb', line 69 def create_root_dataset(opts = {}) progress('Creating root dataset') create_dataset(ctrc.dataset, opts) end |
#exist? ⇒ Boolean
65 66 67 |
# File 'lib/osctld/container/builder.rb', line 65 def exist? DB::Containers.contains?(ctrc.id, ctrc.pool) end |
#from_local_archive(image, opts = {}) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/osctld/container/builder.rb', line 99 def from_local_archive(image, opts = {}) ds_builder.from_local_archive( image, ctrc.rootfs, ctrc.dataset, opts.merge({ mapping: ctrc.map_mode == 'zfs' }) ) distribution, version, arch = get_distribution_info(image) configure( opts[:distribution] || distribution, opts[:version] || version, opts[:arch] || arch ) end |
#from_tar_stream(image, member, compression, ds = nil) ⇒ Object
120 121 122 |
# File 'lib/osctld/container/builder.rb', line 120 def from_tar_stream(image, member, compression, ds = nil) ds_builder.from_tar_stream(image, member, compression, ds || ctrc.dataset) end |
#get_distribution_info(image) ⇒ Object
251 252 253 254 |
# File 'lib/osctld/container/builder.rb', line 251 def get_distribution_info(image) distribution, version, arch, = File.basename(image).split('-') [distribution, version, arch] end |
#group ⇒ Object
49 50 51 |
# File 'lib/osctld/container/builder.rb', line 49 def group ctrc.group end |
#monitor ⇒ Object
212 213 214 |
# File 'lib/osctld/container/builder.rb', line 212 def monitor Monitor::Master.monitor(ctrc.ct) end |
#pool ⇒ Object
41 42 43 |
# File 'lib/osctld/container/builder.rb', line 41 def pool ctrc.pool end |
#progress(msg) ⇒ Object (protected)
260 261 262 263 264 |
# File 'lib/osctld/container/builder.rb', line 260 def progress(msg) return unless @opts[:cmd] @opts[:cmd].send(:progress, msg) end |
#register ⇒ Object
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/osctld/container/builder.rb', line 201 def register DB::Containers.sync do if DB::Containers.contains?(ctrc.id, ctrc.pool) false else DB::Containers.add(ctrc.ct) true end end end |
#setup_ct_dir ⇒ Object
136 137 138 139 140 |
# File 'lib/osctld/container/builder.rb', line 136 def setup_ct_dir # Chown to 0:0, zfs will shift it using the mapping File.chown(0, 0, ctrc.dir) File.chmod(0o770, ctrc.dir) end |
#setup_log_file ⇒ Object
187 188 189 190 191 192 |
# File 'lib/osctld/container/builder.rb', line 187 def setup_log_file progress('Preparing log file') File.open(ctrc.log_path, 'w').close File.chmod(0o660, ctrc.log_path) File.chown(0, ctrc.user.ugid, ctrc.log_path) end |
#setup_lxc_configs ⇒ Object
182 183 184 185 |
# File 'lib/osctld/container/builder.rb', line 182 def setup_lxc_configs progress('Generating LXC configuration') ctrc.ct.lxc_config.configure end |
#setup_lxc_home ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/osctld/container/builder.rb', line 162 def setup_lxc_home progress('Configuring LXC home') unless ctrc.group.setup_for?(ctrc.user) dir = ctrc.group.userdir(ctrc.user) FileUtils.mkdir_p(dir, mode: 0o751) File.chown(0, ctrc.user.ugid, dir) end if Dir.exist?(ctrc.lxc_dir) File.chmod(0o750, ctrc.lxc_dir) else Dir.mkdir(ctrc.lxc_dir, 0o750) end File.chown(0, ctrc.user.ugid, ctrc.lxc_dir) ctrc.ct.configure_bashrc end |
#setup_rootfs ⇒ Object
142 143 144 145 146 147 148 149 150 |
# File 'lib/osctld/container/builder.rb', line 142 def setup_rootfs if Dir.exist?(ctrc.rootfs) File.chmod(0o755, ctrc.rootfs) else Dir.mkdir(ctrc.rootfs, 0o755) end File.chown(0, 0, ctrc.rootfs) end |
#setup_user_hook_script_dir ⇒ Object
194 195 196 197 198 199 |
# File 'lib/osctld/container/builder.rb', line 194 def setup_user_hook_script_dir return if Dir.exist?(ctrc.ct.user_hook_script_dir) progress('Preparing user script hook dir') Dir.mkdir(ctrc.ct.user_hook_script_dir, 0o700) end |
#shift_or_mount_dataset ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/osctld/container/builder.rb', line 124 def shift_or_mount_dataset if ctrc.map_mode == 'zfs' ds_builder.shift_dataset( ctrc.dataset, uid_map: ctrc.uid_map, gid_map: ctrc.gid_map ) else ctrc.dataset.mount end end |
#user ⇒ Object
45 46 47 |
# File 'lib/osctld/container/builder.rb', line 45 def user ctrc.user end |
#valid? ⇒ Boolean
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/osctld/container/builder.rb', line 53 def valid? if ID_RX !~ ctrc.id errors << "invalid ID, allowed characters: #{ID_RX.source}" end unless ctrc.dataset.on_pool?(ctrc.pool.name) errors << "dataset #{ctrc.dataset} does not belong to pool #{ctrc.pool.name}" end errors.empty? end |