Class: LxDev::Main
- Inherits:
-
Object
- Object
- LxDev::Main
- Defined in:
- lib/lxdev/main.rb
Constant Summary collapse
- WHITELISTED_SUDO_COMMANDS =
["lxc", "redir", "kill"]
- SHELLS =
["bash", "zsh", "sh", "csh", "tcsh", "ash"]
- BOOT_TIMEOUT =
30- VERSION =
'0.1.8'
Class Method Summary collapse
Instance Method Summary collapse
- #destroy ⇒ Object
- #execute(command, interactive: false) ⇒ Object
- #halt ⇒ Object
-
#initialize(config_file, state_file) ⇒ 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) ⇒ Main
Returns a new instance of Main.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/lxdev/main.rb', line 14 def initialize(config_file, state_file) @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'] || {} 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
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/lxdev/main.rb', line 34 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 lxdev = Main.new(config_file, state_file) 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 |
Instance Method Details
#destroy ⇒ Object
122 123 124 125 |
# File 'lib/lxdev/main.rb', line 122 def destroy ensure_container_created System.exec("sudo lxc delete #{@name}") end |
#execute(command, interactive: false) ⇒ Object
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/lxdev/main.rb', line 138 def execute(command, interactive: false) if interactive exec("sudo lxc exec #{@name} #{command}") # execution stops here and gives control to exec end IO.popen("sudo lxc exec #{@name} -- /bin/sh -c '#{command}'", err: [:child, :out]) do |cmd_output| cmd_output.each do |line| puts line end end end |
#halt ⇒ Object
115 116 117 118 119 120 |
# File 'lib/lxdev/main.rb', line 115 def halt ensure_container_created System.exec("sudo lxc stop #{@name}") cleanup_forwarded_ports remove_state end |
#provision ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/lxdev/main.rb', line 149 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
177 178 179 180 181 |
# File 'lib/lxdev/main.rb', line 177 def restore(snapshot_name) puts "Restoring snapshot #{snapshot_name}" exitstatus = System.exec("sudo lxc restore #{@name} #{snapshot_name}").exitstatus exitstatus == 0 end |
#revert ⇒ Object
189 190 191 192 193 194 195 196 197 |
# File 'lib/lxdev/main.rb', line 189 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
183 184 185 186 187 |
# File 'lib/lxdev/main.rb', line 183 def rmsnapshot(snapshot_name) puts "Deleting snapshot #{snapshot_name}" exitstatus = System.exec("sudo lxc delete #{@name}/#{snapshot_name}").exitstatus exitstatus == 0 end |
#save_state ⇒ Object
48 49 50 |
# File 'lib/lxdev/main.rb', line 48 def save_state File.open(@state_file, 'w') {|f| f.write @state.to_yaml} unless @state.empty? end |
#set_ssh_keys ⇒ Object
52 53 54 55 56 57 58 59 |
# File 'lib/lxdev/main.rb', line 52 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
172 173 174 175 |
# File 'lib/lxdev/main.rb', line 172 def snapshot(snapshot_name) puts "Creating snapshot #{snapshot_name}" System.exec("sudo lxc snapshot #{@name} #{snapshot_name}") end |
#ssh(args) ⇒ Object
127 128 129 130 131 132 133 134 135 136 |
# File 'lib/lxdev/main.rb', line 127 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
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/lxdev/main.rb', line 61 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
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/lxdev/main.rb', line 90 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 |