Class: LxDev::Main
- Inherits:
-
Object
- Object
- LxDev::Main
- Defined in:
- lib/lxdev/main.rb
Constant Summary collapse
- REQUIRED_COMMANDS =
["lxc", "redir", "kill"]
- SHELLS =
["bash", "zsh", "sh", "csh", "tcsh", "ash"]
- BOOT_TIMEOUT =
30
- VERSION =
'0.2.0'
Class Method Summary collapse
Instance Method Summary collapse
- #destroy ⇒ Object
- #execute(command, interactive: false) ⇒ Object
- #halt ⇒ Object
-
#initialize(config_file, state_file, lxc_command) ⇒ Main
constructor
A new instance of Main.
- #provision ⇒ Object
- #restore(snapshot_name) ⇒ Object
- #revert ⇒ Object
- #rmsnapshot(snapshot_name) ⇒ Object
- #save_state ⇒ Object
- #set_ssh_keys ⇒ Object
- #snapshot(snapshot_name) ⇒ Object
- #ssh(args) ⇒ Object
- #status ⇒ Object
- #up ⇒ Object
Constructor Details
#initialize(config_file, state_file, lxc_command) ⇒ Main
Returns a new instance of Main.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/lxdev/main.rb', line 15 def initialize(config_file, state_file, lxc_command) @state_file = format(".lxdev/%s", state_file) @uid = System.exec("id -u").output.chomp @gid = System.exec("id -g").output.chomp @config = YAML.load_file(config_file) @name = @config['box']['name'] @image = @config['box']['image'] @user = @config['box']['user'] @ports = @config['box']['ports'] || {} @lxc_command = lxc_command Dir.mkdir('.lxdev') unless File.directory?('.lxdev') begin @state = YAML.load_file(@state_file) rescue @state = Hash.new end rescue Errno::ENOENT puts "#{config_file} not found" exit 1 end |
Class Method Details
.setup(config_file = 'lxdev.yml', state_file = 'state') ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/lxdev/main.rb', line 36 def self.setup(config_file = 'lxdev.yml', state_file = 'state') self.check_requirements unless lxd_initialized? puts "Please run 'lxd init' and configure LXD first" return false end user_in_group = Main.user_in_lxd_group? lxc_command = (user_in_group ? "lxc" : "sudo lxc") unless(user_in_group) puts "Add yourself to the 'lxd' group to avoid entering the sudo password :" puts "(You need to login again afterwards, or start a new login shell)" puts " sudo usermod -a -G lxd #{Etc.getlogin}" end lxdev = Main.new(config_file, state_file, lxc_command) unless lxdev.set_ssh_keys puts "No ssh keys detected. Make sure you have an ssh key, a running agent, and the key added to the agent, e.g. with ssh-add." return false end return lxdev end |
.user_in_lxd_group? ⇒ Boolean
57 58 59 60 61 62 63 64 |
# File 'lib/lxdev/main.rb', line 57 def self.user_in_lxd_group? begin Etc.getgrnam("lxd").mem.include?(Etc.getlogin) rescue ArgumentError puts "There seems to be no 'lxd' group. Is LXD installed?" false end end |
Instance Method Details
#destroy ⇒ Object
140 141 142 143 |
# File 'lib/lxdev/main.rb', line 140 def destroy ensure_container_created System.exec("#{@lxc_command} delete #{@name}") end |
#execute(command, interactive: false) ⇒ Object
156 157 158 159 160 161 162 163 164 165 |
# File 'lib/lxdev/main.rb', line 156 def execute(command, interactive: false) if interactive exec("#{@lxc_command} exec #{@name} #{command}") # execution stops here and gives control to exec end IO.popen("#{@lxc_command} exec #{@name} -- /bin/sh -c '#{command}'", err: [:child, :out]) do |cmd_output| cmd_output.each do |line| puts line end end end |
#halt ⇒ Object
133 134 135 136 137 138 |
# File 'lib/lxdev/main.rb', line 133 def halt ensure_container_created System.exec("#{@lxc_command} stop #{@name}") cleanup_forwarded_ports remove_state end |
#provision ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/lxdev/main.rb', line 167 def provision ensure_container_created if get_container_status.first['status'] != 'Running' puts "#{@name} is not running!" exit 1 end provisioning = @config['box']['provisioning'] if provisioning.nil? puts "Nothing to do" return end if @config['box']['auto_snapshots'] snapshot_name = "provision_#{Time.now.to_i}" snapshot(snapshot_name) end puts "Provisioning #{@name}..." STDOUT.sync = true provisioning.each do |cmd| execute cmd end STDOUT.sync = false end |
#restore(snapshot_name) ⇒ Object
195 196 197 198 199 |
# File 'lib/lxdev/main.rb', line 195 def restore(snapshot_name) puts "Restoring snapshot #{snapshot_name}" exitstatus = System.exec("#{@lxc_command} restore #{@name} #{snapshot_name}").exitstatus exitstatus == 0 end |
#revert ⇒ Object
207 208 209 210 211 212 213 214 215 |
# File 'lib/lxdev/main.rb', line 207 def revert snapshot = get_container_status.first['snapshots'].last snapshot_name = snapshot['name'].partition('/').last if restore(snapshot_name) puts "Reverted to snapshot #{snapshot_name}" puts "Deleting snapshot" rmsnapshot(snapshot_name) end end |
#rmsnapshot(snapshot_name) ⇒ Object
201 202 203 204 205 |
# File 'lib/lxdev/main.rb', line 201 def rmsnapshot(snapshot_name) puts "Deleting snapshot #{snapshot_name}" exitstatus = System.exec("#{@lxc_command} delete #{@name}/#{snapshot_name}").exitstatus exitstatus == 0 end |
#save_state ⇒ Object
66 67 68 |
# File 'lib/lxdev/main.rb', line 66 def save_state File.open(@state_file, 'w') {|f| f.write @state.to_yaml} unless @state.empty? end |
#set_ssh_keys ⇒ Object
70 71 72 73 74 75 76 77 |
# File 'lib/lxdev/main.rb', line 70 def set_ssh_keys ssh_keys = System.exec("ssh-add -L").output if ssh_keys[0..3] == 'ssh-' @ssh_keys = ssh_keys else nil end end |
#snapshot(snapshot_name) ⇒ Object
190 191 192 193 |
# File 'lib/lxdev/main.rb', line 190 def snapshot(snapshot_name) puts "Creating snapshot #{snapshot_name}" System.exec("#{@lxc_command} snapshot #{@name} #{snapshot_name}") end |
#ssh(args) ⇒ Object
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/lxdev/main.rb', line 145 def ssh(args) ensure_container_created host = get_container_ip if host.nil? puts "#{@name} doesn't seem to be running." exit 1 end ssh_command = "ssh -o StrictHostKeyChecking=no -t #{@user}@#{get_container_ip} #{args.empty? ? '' : "'#{args.join(' ')}'"}" exec ssh_command end |
#status ⇒ Object
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 |
# File 'lib/lxdev/main.rb', line 79 def status ensure_container_created container_status = get_container_status folders = container_status.first['devices'].map {|name, folders| [name, "#{folders['source']} => #{folders['path']}"] if folders['source']}.compact table = Terminal::Table.new do |t| t.add_row ['Name', container_status.first['name']] t.add_row ['Status', container_status.first['status']] t.add_row ['IP', get_container_ip] t.add_row ['Image', @image] t.add_separator folders.each do |folder| t.add_row folder end t.add_separator @ports.each do |guest, host| t.add_row ['Forwarded port', "guest: #{guest} host: #{host}"] end if container_status.first['snapshots'].any? t.add_separator t.add_row ['Snapshots', ''] end container_status.first['snapshots'].each do |snapshot| t.add_row [snapshot['name'].partition('/').last, snapshot['created_at']] end end puts table end |
#up ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/lxdev/main.rb', line 108 def up do_provision = false unless @state.empty? puts "Container state #{@state_file} exists, is it running? If not it might have stopped unexpectedly. Please remove the file before starting." exit 1 end if get_container_status.empty? create_container do_provision = true else if get_container_status.first['status'] == 'Running' puts "#{@name} is already running!" exit 1 else start_container end end puts "Waiting for boot..." wait_for_boot @state['status'] = 'running' puts "Forwarding ports..." forward_ports(@ports) provision if do_provision end |