class LXC::Container
Main Container
Class
@author Zachary Patten <zachary AT jovelabs DOT com>
Constants
- REGEX_PID
RegEx pattern for extracting the container PID from the “lxc-info” command output.
- REGEX_STATE
RegEx pattern for extracting the container state from the “lxc-info” command output.
- STATES
An array containing the valid container states extracted from the
LXC
c-source code.
Attributes
Returns the container name
@return [String] Container
name
Public Class Methods
@param [Hash] options Options hash. @option options [LXC] :lxc Our parent LXC
class instance. @option options [String] :name The name of the container.
# File lib/lxc/container.rb, line 75 def initialize(options={}) @lxc = options[:lxc] @name = options[:name] raise ContainerError, "You must supply a LXC object!" if @lxc.nil? raise ContainerError, "You must supply a container name!" if (@name.nil? || @name.empty?) end
Public Instance Methods
Run an application inside a container
Executes the supplied application inside a container. The container must already be running.
@see lxc-attach
# File lib/lxc/container.rb, line 243 def attach(*args) self.exec("lxc-attach", *args) end
Bootstrap a container
Renders the supplied text blob inside a container as a script and executes it via lxc-attach. The container must already be running.
@see lxc-attach
@param [String] content The content to render in the container and
execute. This is generally a bash script of some sort for example.
@return [String] The output of lxc-attach.
# File lib/lxc/container.rb, line 257 def bootstrap(content) output = nil ZTK::RescueRetry.try(:tries => 5, :on => ContainerError) do tempfile = Tempfile.new("bootstrap") lxc_tempfile = File.join("", "tmp", File.basename(tempfile.path)) host_tempfile = File.join(self.fs_root, lxc_tempfile) self.lxc.runner.file(:target => host_tempfile, :chmod => '0755', :chown => 'root:root') do |file| file.puts(content) end output = self.attach(%(-- /bin/bash #{lxc_tempfile})) if !(output =~ /#{lxc_tempfile}: No such file or directory/).nil? raise ContainerError, "We could not find the bootstrap file!" end end output end
Clone the container
Runs the “lxc-clone” command.
@return [Array<String>] Lines of output from the executed command. @see lxc-clone
# File lib/lxc/container.rb, line 140 def clone(*args) self.lxc.exec("lxc-clone", *args) end
Launch a console for the container
@see lxc-console
# File lib/lxc/container.rb, line 282 def console self.exec("lxc-console") end
Directory for the container
@return [String] The directory for the container.
# File lib/lxc/container.rb, line 378 def container_root File.join('/', 'var', 'lib', 'lxc', self.name) end
CPU Time in Seconds
# File lib/lxc/container.rb, line 323 def cpu_usage result = self.exec(%(lxc-cgroup), %(cpuacct.usage)) (result.empty? ? 0 : (result.to_i / 1E9).to_i) end
Create the container
Runs the “lxc-create” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 98 def create(*args) self.exec("lxc-create", *args) end
Destroy the container
Runs the “lxc-destroy” command. If the container has not been stopped first then this will fail unless '-f' is passed as an argument. See the 'lxc-destroy' man page for more details.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 110 def destroy(*args) self.exec("lxc-destroy", *args) end
Current Disk Usage
# File lib/lxc/container.rb, line 329 def disk_usage(ephemeral=false) result = (@lxc.exec(%(du -sb #{self.fs_root(ephemeral)})).split.first rescue nil) ((result.nil? || result.empty?) ? 0 : result.to_i) end
Linux container command execution wrapper
Executes the supplied command by injecting the container name into the argument list and then passes to the arguments to the top-level LXC
class exec method.
@param [Array] args Additional command-line arguments. @return [Array<String>] Stripped output text of the executed command.
@see LXC#exec
# File lib/lxc/container.rb, line 344 def exec(*args) arguments = Array.new arguments << args.shift arguments << %(-n #{self.name}) arguments << args arguments.flatten!.compact! @lxc.exec(*arguments) end
Run an application inside a container
Launches the container, executing the supplied application inside it.
@see lxc-execute
# File lib/lxc/container.rb, line 233 def execute(*args) self.exec("lxc-execute", "-f", self.config.filename, "--", *args) end
Does the container exist?
@return [Boolean] Returns true if the container exists, false otherwise.
# File lib/lxc/container.rb, line 224 def exists? @lxc.exists?(self.name) end
Freeze the container
Runs the “lxc-freeze” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 167 def freeze(*args) self.exec("lxc-freeze", *args) end
Root directory for the containers file system
@param [Boolean] ephemeral True if we should construct a path to the
union filesystem used by ephemeral containers. False if we should construct a traditional path.
@return [String] The root directory for the container.
# File lib/lxc/container.rb, line 360 def fs_root(ephemeral=false) if (ephemeral == true) File.join(self.container_root, 'delta0') else File.join(self.container_root, 'rootfs') end end
Static information about the containers filesystems
@return [String] The path to the containers fstab.
# File lib/lxc/container.rb, line 371 def fs_tab File.join(self.container_root, 'fstab') end
Information on the container
Runs the “lxc-info” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 187 def info(*args) self.exec("lxc-info", *args).split("\n").uniq.flatten end
Provides a concise string representation of the class @return [String]
# File lib/lxc/container.rb, line 384 def inspect tags = Array.new tags << "name=#{self.name.inspect}" tags = tags.join(' ') "#<LXC::Container #{tags}>" end
Current Memory Usage
# File lib/lxc/container.rb, line 317 def memory_usage result = self.exec(%(lxc-cgroup), %(memory.usage_in_bytes)) (result.empty? ? 0 : result.to_i) end
PID of the container
Runs the “lxc-info” command with the “–pid” flag.
@param [Array] args Additional command-line arguments. @return [Integer] Current PID of the container.
# File lib/lxc/container.rb, line 214 def pid(*args) result = self.info("--pid", *args).collect{ |str| str.scan(REGEX_PID) } result.flatten!.compact! (result.first.strip.to_i rescue -1) end
Restart the container
# File lib/lxc/container.rb, line 155 def restart(options={}) self.stop self.start end
Start the container
Runs the “lxc-start” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 120 def start(*args) self.exec("lxc-start", *args) end
Start an ephemeral copy of the container
Runs the “lxc-start-ephemeral” command.
@return [Array<String>] Lines of output from the executed command. @see lxc-start-ephemeral
# File lib/lxc/container.rb, line 130 def start_ephemeral(*args) self.lxc.exec("lxc-start-ephemeral", *args) end
State of the container
Runs the “lxc-info” command with the “–state” flag.
@param [Array] args Additional command-line arguments. @return [Symbol] Current state of the container.
# File lib/lxc/container.rb, line 197 def state(*args) if self.exists? result = self.info("--state", *args).collect{ |str| str.scan(REGEX_STATE) } result.flatten!.compact! (result.first.strip.downcase.to_sym rescue :unknown) else :not_created end end
Stop the container
Runs the “lxc-stop” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 150 def stop(*args) self.exec("lxc-stop", *args) end
Unfreeze (thaw) the container
Runs the “lxc-unfreeze” command.
@param [Array] args Additional command-line arguments. @return [Array<String>] Lines of output from the executed command.
# File lib/lxc/container.rb, line 177 def unfreeze(*args) self.exec("lxc-unfreeze", *args) end
Wait for a specific container state
Runs the “lxc-wait” command.
The timeout only works when using remote control via SSH and will orphan the process ('lxc-wait') on the remote host.
@param [Symbol,Array] states A single symbol or an array of symbols
representing container states for which we will wait for the container to change state to.
@param [Integer] timeout How long in seconds we will wait before the
operation times out.
@return [Boolean] Returns true of the state change happened, false
otherwise.
# File lib/lxc/container.rb, line 300 def wait(states, timeout=60) state_arg = [states].flatten.map do |state| state.to_s.upcase.strip end.join('|') begin Timeout.timeout(timeout) do self.exec("lxc-wait", "-s", %('#{state_arg}')) end rescue Timeout::Error => e return false end true end