Class: Vagrant::LXC::Driver
- Inherits:
-
Object
- Object
- Vagrant::LXC::Driver
- Defined in:
- lib/vagrant-lxc/driver.rb,
lib/vagrant-lxc/driver/cli.rb
Defined Under Namespace
Classes: CLI, ContainerNotFound
Instance Attribute Summary collapse
-
#container_name ⇒ Object
readonly
Default root folder where container configs are stored.
-
#customizations ⇒ Object
readonly
Default root folder where container configs are stored.
Instance Method Summary collapse
- #all_containers ⇒ Object
- #attach(*command) ⇒ Object
- #base_path ⇒ Object
- #bridge_exists?(bridge_name) ⇒ Boolean
- #bridge_has_an_ip?(bridge_name) ⇒ Boolean
- #bridge_is_in_use?(bridge_name) ⇒ Boolean
-
#compress_rootfs ⇒ Object
TODO: This needs to be reviewed and specs needs to be written.
- #config_path ⇒ Object
- #config_string ⇒ Object
- #configure_private_network(bridge_name, bridge_ip, container_name, address_type, ip) ⇒ Object
-
#containers_path ⇒ Object
Root folder where container configs are stored.
- #create(name, backingstore, backingstore_options, template_path, config_file, template_options = {}) ⇒ Object
- #destroy ⇒ Object
- #forced_halt ⇒ Object
- #info(*command) ⇒ Object
-
#initialize(container_name, sudo_wrapper = nil, cli = nil, privileged: true) ⇒ Driver
constructor
A new instance of Driver.
- #mac_address ⇒ Object
- #prune_customizations ⇒ Object
- #remove_bridge(bridge_name) ⇒ Object
- #rootfs_path ⇒ Object
- #share_folder(host_path, guest_path, mount_options = nil) ⇒ Object
- #share_folders(folders) ⇒ Object
- #start(customizations) ⇒ Object
- #state ⇒ Object
- #supports_attach? ⇒ Boolean
- #supports_new_config_format ⇒ Object
- #update_config_keys(path = nil) ⇒ Object
- #validate! ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(container_name, sudo_wrapper = nil, cli = nil, privileged: true) ⇒ Driver
Returns a new instance of Driver.
23 24 25 26 27 28 29 |
# File 'lib/vagrant-lxc/driver.rb', line 23 def initialize(container_name, sudo_wrapper = nil, cli = nil, privileged: true) @container_name = container_name @sudo_wrapper = sudo_wrapper || SudoWrapper.new(privileged: privileged) @cli = cli || CLI.new(@sudo_wrapper, container_name) @logger = Log4r::Logger.new("vagrant::provider::lxc::driver") @customizations = [] end |
Instance Attribute Details
#container_name ⇒ Object (readonly)
Default root folder where container configs are stored
20 21 22 |
# File 'lib/vagrant-lxc/driver.rb', line 20 def container_name @container_name end |
#customizations ⇒ Object (readonly)
Default root folder where container configs are stored
20 21 22 |
# File 'lib/vagrant-lxc/driver.rb', line 20 def customizations @customizations end |
Instance Method Details
#all_containers ⇒ Object
40 41 42 |
# File 'lib/vagrant-lxc/driver.rb', line 40 def all_containers @cli.list end |
#attach(*command) ⇒ Object
129 130 131 |
# File 'lib/vagrant-lxc/driver.rb', line 129 def attach(*command) @cli.attach(*command) end |
#base_path ⇒ Object
44 45 46 |
# File 'lib/vagrant-lxc/driver.rb', line 44 def base_path Pathname.new("#{containers_path}/#{@container_name}") end |
#bridge_exists?(bridge_name) ⇒ Boolean
188 189 190 191 192 |
# File 'lib/vagrant-lxc/driver.rb', line 188 def bridge_exists?(bridge_name) @logger.info "Checking whether bridge #{bridge_name} exists" brctl_output = `ip link | egrep -q " #{bridge_name}:"` $?.to_i == 0 end |
#bridge_has_an_ip?(bridge_name) ⇒ Boolean
183 184 185 186 |
# File 'lib/vagrant-lxc/driver.rb', line 183 def bridge_has_an_ip?(bridge_name) @logger.info "Checking whether the bridge #{bridge_name} has an IP" `ip -4 addr show scope global #{bridge_name}` =~ /^\s+inet ([0-9.]+)\/[0-9]+\s+/ end |
#bridge_is_in_use?(bridge_name) ⇒ Boolean
194 195 196 197 198 199 |
# File 'lib/vagrant-lxc/driver.rb', line 194 def bridge_is_in_use?(bridge_name) # REFACTOR: This method is **VERY** hacky @logger.info "Checking if bridge #{bridge_name} is in use" brctl_output = `brctl show #{bridge_name} 2>/dev/null | tail -n +2 | grep -q veth` $?.to_i == 0 end |
#compress_rootfs ⇒ Object
TODO: This needs to be reviewed and specs needs to be written
223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/vagrant-lxc/driver.rb', line 223 def compress_rootfs # TODO: Pass in tmpdir so we can clean up from outside target_path = "#{Dir.mktmpdir}/rootfs.tar.gz" @logger.info "Compressing '#{rootfs_path}' rootfs to #{target_path}" @sudo_wrapper.run('tar', '--numeric-owner', '-cvzf', target_path, '-C', rootfs_path.parent.to_s, "./#{rootfs_path.basename.to_s}") @logger.info "Changing rootfs tarball owner" user_details = Etc.getpwnam(Etc.getlogin) @sudo_wrapper.run('chown', "#{user_details.uid}:#{user_details.gid}", target_path) target_path end |
#config_path ⇒ Object
48 49 50 |
# File 'lib/vagrant-lxc/driver.rb', line 48 def config_path base_path.join('config').to_s end |
#config_string ⇒ Object
78 79 80 |
# File 'lib/vagrant-lxc/driver.rb', line 78 def config_string @sudo_wrapper.run('cat', config_path) end |
#configure_private_network(bridge_name, bridge_ip, container_name, address_type, ip) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/vagrant-lxc/driver.rb', line 137 def configure_private_network(bridge_name, bridge_ip, container_name, address_type, ip) @logger.info "Configuring network interface for #{container_name} using #{ip} and bridge #{bridge_name}" if ip ip += '/24' end if ! bridge_exists?(bridge_name) if not bridge_ip raise "Bridge is missing and no IP was specified!" end @logger.info "Creating the bridge #{bridge_name}" cmd = [ 'brctl', 'addbr', bridge_name ] @sudo_wrapper.run(*cmd) end if ! bridge_has_an_ip?(bridge_name) if not bridge_ip raise "Bridge has no IP and none was specified!" end @logger.info "Adding #{bridge_ip} to the bridge #{bridge_name}" cmd = [ 'ip', 'addr', 'add', "#{bridge_ip}/24", 'dev', bridge_name ] @sudo_wrapper.run(*cmd) @sudo_wrapper.run('ip', 'link', 'set', bridge_name, 'up') end cmd = [ Vagrant::LXC.source_root.join('scripts/pipework').to_s, bridge_name, container_name, ip ||= "dhcp" ] @sudo_wrapper.run(*cmd) end |
#containers_path ⇒ Object
Root folder where container configs are stored
36 37 38 |
# File 'lib/vagrant-lxc/driver.rb', line 36 def containers_path @containers_path ||= @cli.config('lxc.lxcpath') end |
#create(name, backingstore, backingstore_options, template_path, config_file, template_options = {}) ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/vagrant-lxc/driver.rb', line 82 def create(name, backingstore, , template_path, config_file, = {}) @cli.name = @container_name = name @logger.debug "Creating container..." @cli.create template_path, backingstore, , config_file, end |
#destroy ⇒ Object
121 122 123 |
# File 'lib/vagrant-lxc/driver.rb', line 121 def destroy @cli.destroy end |
#forced_halt ⇒ Object
116 117 118 119 |
# File 'lib/vagrant-lxc/driver.rb', line 116 def forced_halt @logger.info('Shutting down container...') @cli.transition_to(:stopped) { |c| c.stop } end |
#info(*command) ⇒ Object
133 134 135 |
# File 'lib/vagrant-lxc/driver.rb', line 133 def info(*command) @cli.info(*command) end |
#mac_address ⇒ Object
70 71 72 73 74 75 76 |
# File 'lib/vagrant-lxc/driver.rb', line 70 def mac_address return @mac_address if @mac_address if config_string =~ /^lxc\.network\.hwaddr\s*+=\s*+(.+)$/ @mac_address = $1 end end |
#prune_customizations ⇒ Object
244 245 246 247 248 249 250 |
# File 'lib/vagrant-lxc/driver.rb', line 244 def prune_customizations # Use sed to just strip out the block of code which was inserted by Vagrant @logger.debug 'Prunning vagrant-lxc customizations' contents = config_string contents.gsub! /^# VAGRANT-BEGIN(.|\s)*# VAGRANT-END\n/, '' write_config(contents) end |
#remove_bridge(bridge_name) ⇒ Object
201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/vagrant-lxc/driver.rb', line 201 def remove_bridge(bridge_name) if ['lxcbr0', 'virbr0'].include? bridge_name @logger.info "Skipping removal of system bridge #{bridge_name}" return end return unless bridge_exists?(bridge_name) @logger.info "Removing bridge #{bridge_name}" @sudo_wrapper.run('ip', 'link', 'set', bridge_name, 'down') @sudo_wrapper.run('brctl', 'delbr', bridge_name) end |
#rootfs_path ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/vagrant-lxc/driver.rb', line 52 def rootfs_path config_entry = config_string.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1] case config_entry when /^overlayfs:/ # Split on colon (:), ignoring any colon escaped by an escape character ( \ ) # Pays attention to when the escape character is itself escaped. fs_type, master_path, = config_entry.split(/(?<!\\)(?:\\\\)*:/) if Pathname.new() else # Malformed: fall back to prior behaviour Pathname.new(config_entry) end else Pathname.new(config_entry) end end |
#share_folder(host_path, guest_path, mount_options = nil) ⇒ Object
96 97 98 99 100 101 |
# File 'lib/vagrant-lxc/driver.rb', line 96 def share_folder(host_path, guest_path, = nil) guest_path = guest_path.gsub(/^\//, '').gsub(' ', '\\\040') = Array( || ['bind', 'create=dir']) host_path = host_path.to_s.gsub(' ', '\\\040') @customizations << ['mount.entry', "#{host_path} #{guest_path} none #{.join(',')} 0 0"] end |
#share_folders(folders) ⇒ Object
90 91 92 93 94 |
# File 'lib/vagrant-lxc/driver.rb', line 90 def share_folders(folders) folders.each do |f| share_folder(f[:hostpath], f[:guestpath], f.fetch(:mount_options, nil)) end end |
#start(customizations) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/vagrant-lxc/driver.rb', line 103 def start(customizations) @logger.info('Starting container...') if ENV['LXC_START_LOG_FILE'] extra = ['-o', ENV['LXC_START_LOG_FILE'], '-l', 'DEBUG'] end prune_customizations write_customizations(customizations + @customizations) @cli.start(extra) end |
#state ⇒ Object
238 239 240 241 242 |
# File 'lib/vagrant-lxc/driver.rb', line 238 def state if @container_name @cli.state end end |
#supports_attach? ⇒ Boolean
125 126 127 |
# File 'lib/vagrant-lxc/driver.rb', line 125 def supports_attach? @cli.supports_attach? end |
#supports_new_config_format ⇒ Object
218 219 220 |
# File 'lib/vagrant-lxc/driver.rb', line 218 def supports_new_config_format Gem::Version.new(version) >= Gem::Version.new('2.1.0') end |
#update_config_keys(path = nil) ⇒ Object
252 253 254 255 256 257 |
# File 'lib/vagrant-lxc/driver.rb', line 252 def update_config_keys(path = nil) path = path || config_path @cli.update_config(path) rescue Errors::ExecuteError # not on LXC 2.1+. Doesn't matter, ignore. end |
#validate! ⇒ Object
31 32 33 |
# File 'lib/vagrant-lxc/driver.rb', line 31 def validate! raise ContainerNotFound if @container_name && ! @cli.list.include?(@container_name) end |
#version ⇒ Object
214 215 216 |
# File 'lib/vagrant-lxc/driver.rb', line 214 def version @version ||= @cli.version end |