Class: Vagrant::LXC::Container

Inherits:
Object
  • Object
show all
Includes:
Util::Retryable
Defined in:
lib/vagrant-lxc/container.rb,
lib/vagrant-lxc/container/cli.rb

Defined Under Namespace

Classes: CLI, NotFound

Constant Summary collapse

CONTAINERS_PATH =

Root folder where containers are stored

'/var/lib/lxc'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, cli = CLI.new(name)) ⇒ Container

Returns a new instance of Container.



24
25
26
27
28
# File 'lib/vagrant-lxc/container.rb', line 24

def initialize(name, cli = CLI.new(name))
  @name   = name
  @cli    = cli
  @logger = Log4r::Logger.new("vagrant::provider::lxc::container")
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



22
23
24
# File 'lib/vagrant-lxc/container.rb', line 22

def name
  @name
end

Instance Method Details

#assigned_ipObject



122
123
124
125
126
127
128
129
130
131
# File 'lib/vagrant-lxc/container.rb', line 122

def assigned_ip
  ip = ''
  retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do
    unless ip = get_container_ip_from_ifconfig
      # retry
      raise LXC::Errors::ExecuteError, :command => "lxc-attach"
    end
  end
  ip
end

#base_pathObject



34
35
36
# File 'lib/vagrant-lxc/container.rb', line 34

def base_path
  Pathname.new("#{CONTAINERS_PATH}/#{@name}")
end

#compress_rootfsObject

TODO: This needs to be reviewed and specs needs to be written



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/vagrant-lxc/container.rb', line 97

def compress_rootfs
  # TODO: Our template should not depend on container's arch
  arch           = base_path.join('config').read.match(/^lxc\.arch\s+=\s+(.+)$/)[1]
  rootfs_dirname = File.dirname rootfs_path
  basename       = rootfs_path.to_s.gsub(/^#{Regexp.escape rootfs_dirname}\//, '')
  # TODO: Pass in tmpdir so we can clean up from outside
  target_path    = "#{Dir.mktmpdir}/rootfs.tar.gz"

  Dir.chdir base_path do
    @logger.info "Compressing '#{rootfs_path}' rootfs to #{target_path}"
    system "sudo rm -f rootfs.tar.gz && sudo bsdtar -s /#{basename}/rootfs-#{arch}/ --numeric-owner -czf #{target_path} #{basename}/* 2>/dev/null"

    @logger.info "Changing rootfs tarbal owner"
    system "sudo chown #{ENV['USER']}:#{ENV['USER']} #{target_path}"
  end

  target_path
end

#create(base_name, target_rootfs_path, metadata = {}) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/vagrant-lxc/container.rb', line 42

def create(base_name, target_rootfs_path,  = {})
  @logger.debug('Creating container using lxc-create...')

  @name      = "#{base_name}-#{SecureRandom.hex(6)}"
  public_key = Vagrant.source_root.join('keys', 'vagrant.pub').expand_path.to_s
  meta_opts  = .fetch('template-opts', {}).merge(
    '--auth-key' => public_key,
    '--cache'    => .fetch('rootfs-cache-path')
  )

  @cli.name = @name
  @cli.create(.fetch('template-name'), target_rootfs_path, meta_opts)

  @name
end

#destroyObject



92
93
94
# File 'lib/vagrant-lxc/container.rb', line 92

def destroy
  @cli.destroy
end

#get_container_ip_from_ifconfigObject



133
134
135
136
137
138
# File 'lib/vagrant-lxc/container.rb', line 133

def get_container_ip_from_ifconfig
  output = @cli.attach '/sbin/ifconfig', '-v', 'eth0', namespaces: 'network'
  if output =~ /\s+inet addr:([0-9.]+)\s+/
    return $1.to_s
  end
end

#haltObject



85
86
87
88
89
90
# File 'lib/vagrant-lxc/container.rb', line 85

def halt
  @logger.info('Shutting down container...')

  # TODO: issue an lxc-stop if a timeout gets reached
  @cli.transition_to(:stopped) { |c| c.shutdown }
end

#rootfs_pathObject



38
39
40
# File 'lib/vagrant-lxc/container.rb', line 38

def rootfs_path
  Pathname.new(base_path.join('config').read.match(/^lxc\.rootfs\s+=\s+(.+)$/)[1])
end

#share_folders(folders, config) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/vagrant-lxc/container.rb', line 58

def share_folders(folders, config)
  folders.each do |folder|
    guestpath = rootfs_path.join(folder[:guestpath].gsub(/^\//, ''))
    unless guestpath.directory?
      begin
        system "sudo mkdir -p #{guestpath.to_s}"
      rescue Errno::EACCES
        raise Vagrant::Errors::SharedFolderCreateFailed,
          :path => guestpath.to_s
      end
    end

    config.start_opts << "lxc.mount.entry=#{folder[:hostpath]} #{guestpath} none bind 0 0"
  end
end

#start(config) ⇒ Object



74
75
76
77
78
79
80
81
82
83
# File 'lib/vagrant-lxc/container.rb', line 74

def start(config)
  @logger.info('Starting container...')

  opts = config.start_opts.dup
  if ENV['LXC_START_LOG_FILE']
    extra = ['-o', ENV['LXC_START_LOG_FILE'], '-l', 'DEBUG']
  end

  @cli.transition_to(:running) { |c| c.start(opts, (extra || nil)) }
end

#stateObject



116
117
118
119
120
# File 'lib/vagrant-lxc/container.rb', line 116

def state
  if @name
    @cli.state
  end
end

#validate!Object

Raises:



30
31
32
# File 'lib/vagrant-lxc/container.rb', line 30

def validate!
  raise NotFound if @name && ! @cli.list.include?(@name)
end