Module: NexusSW::LXD::Driver::Mixins::CLI
Instance Attribute Summary collapse
-
#driver_options ⇒ Object
readonly
Returns the value of attribute driver_options.
-
#inner_transport ⇒ Object
readonly
Returns the value of attribute inner_transport.
Instance Method Summary collapse
- #container(container_id) ⇒ Object
- #container_exists?(container_id) ⇒ Boolean
-
#container_state(container_id) ⇒ Object
YAML is not supported until somewhere in the feature branch the YAML return has :state and :container at the root level the JSON return has no :container (:container is root) and has :state underneath that (CLI Only) and :state is only available if the container is running.
- #container_status(container_id) ⇒ Object
- #create_container(container_name, container_options = {}) ⇒ Object
- #delete_container(container_id) ⇒ Object
- #initialize(inner_transport, driver_options = {}) ⇒ Object
- #start_container(container_id) ⇒ Object
- #stop_container(container_id, options = {}) ⇒ Object
- #transport_for(container_name) ⇒ Object
- #update_container(container_name, container_options) ⇒ Object
Methods included from Helpers::WaitMixin
Instance Attribute Details
#driver_options ⇒ Object (readonly)
Returns the value of attribute driver_options.
17 18 19 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 17 def end |
#inner_transport ⇒ Object (readonly)
Returns the value of attribute inner_transport.
17 18 19 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 17 def inner_transport @inner_transport end |
Instance Method Details
#container(container_id) ⇒ Object
154 155 156 157 158 159 160 161 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 154 def container(container_id) res = inner_transport.execute("lxc list #{container_id} --format=json") res.error! JSON.parse(res.stdout).each do |c| return Driver.convert_bools(LXD.symbolize_keys(c.reject { |k, _| k == "state" })) if c["name"] == container_id end nil end |
#container_exists?(container_id) ⇒ Boolean
163 164 165 166 167 168 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 163 def container_exists?(container_id) return true if container_status(container_id) false rescue false end |
#container_state(container_id) ⇒ Object
YAML is not supported until somewhere in the feature branch
the YAML return has :state and :container at the root level
the JSON return has no :container (:container is root)
and has :state underneath that
(CLI Only) and :state is only available if the container is running
145 146 147 148 149 150 151 152 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 145 def container_state(container_id) res = inner_transport.execute("lxc list #{container_id} --format=json") res.error! JSON.parse(res.stdout).each do |c| return LXD.symbolize_keys(c["state"]) if c["name"] == container_id end nil end |
#container_status(container_id) ⇒ Object
136 137 138 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 136 def container_status(container_id) STATUS_CODES[container(container_id)[:status_code].to_i] end |
#create_container(container_name, container_options = {}) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 23 def create_container(container_name, = {}) autostart = (.delete(:autostart) != false) if container_exists? container_name start_container(container_name) if autostart return container_name end cline = "lxc launch #{image_alias(container_options)} #{container_name}" profiles = [:profiles] || [] profiles.each { |p| cline += " -p #{p}" } configs = [:config] || {} configs.each { |k, v| cline += " -c #{k}=#{v}" } if !autostart || [:devices] # append to the cline to avoid potential lag between create & stop cline += " && lxc stop -f #{container_name}" cline = ["sh", "-c", cline] # There's no guarantee that inner_transport is running a shell for the && operator end inner_transport.execute(cline).error! if [:devices] update_container(container_name, devices: [:devices]) start_container(container_name) if autostart else wait_for_status container_name, "running" if autostart end container_name end |
#delete_container(container_id) ⇒ Object
131 132 133 134 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 131 def delete_container(container_id) return unless container_exists? container_id inner_transport.execute("lxc delete #{container_id} --force", capture: false).error! end |
#initialize(inner_transport, driver_options = {}) ⇒ Object
12 13 14 15 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 12 def initialize(inner_transport, = {}) @inner_transport = inner_transport = || {} end |
#start_container(container_id) ⇒ Object
104 105 106 107 108 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 104 def start_container(container_id) return if container_status(container_id) == "running" inner_transport.execute("lxc start #{container_id}").error! wait_for_status container_id, "running" end |
#stop_container(container_id, options = {}) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 110 def stop_container(container_id, = {}) ||= {} # default behavior: no timeout or retries. These functions are up to the consumer's context and not really 'sane' defaults return if container_status(container_id) == "stopped" return inner_transport.execute("lxc stop #{container_id} --force", capture: false).error! if [:force] LXD.with_timeout_and_retries() do return if container_status(container_id) == "stopped" timeout = " --timeout=#{options[:retry_interval]}" if [:retry_interval] retval = inner_transport.execute("lxc stop #{container_id}#{timeout || ''}", capture: false) begin retval.error! rescue => e return if container_status(container_id) == "stopped" # can't distinguish between timeout, or other error. # but if the status call is not popping a 404, and we're not stopped, then a retry is worth it raise Timeout::Retry.new(e) if timeout # rubocop:disable Style/RaiseArgs raise end end wait_for_status container_id, "stopped" end |
#transport_for(container_name) ⇒ Object
19 20 21 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 19 def transport_for(container_name) Transport::CLI.new inner_transport, container_name, info: YAML.load(inner_transport.execute("lxc info").error!.stdout) end |
#update_container(container_name, container_options) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/nexussw/lxd/driver/mixins/cli.rb', line 48 def update_container(container_name, ) raise NexusSW::LXD::RestAPI::Error::NotFound, "Container (#{container_name}) does not exist" unless container_exists? container_name configs = [:config] devices = [:devices] profiles = [:profiles] existing = container(container_name) if configs configs.each do |k, v| if v.nil? next unless existing[:config][k] inner_transport.execute("lxc config unset #{container_name} #{k}").error! else next if existing[:config][k] == v inner_transport.execute("lxc config set #{container_name} #{k} #{v}").error! end end end if devices devices.each do |name, device| cmd = "add" if device.nil? next unless existing[:devices].include? name inner_transport.execute("lxc config device remove #{container_name} #{name}").error! next elsif existing[:devices].include?(name) cmd = "set" if existing[:devices][name][:type] != device[:type] inner_transport.execute("lxc config device remove #{container_name} #{name}").error! cmd = "add" end end if cmd == "add" cline = "lxc config device add #{container_name} #{name} #{device[:type]}" device.each do |k, v| cline << " #{k}=#{v}" end inner_transport.execute(cline).error! else device.each do |k, v| next if k == :type next if v == existing[:devices][name][k] inner_transport.execute("lxc config device set #{container_name} #{name} #{k} #{v}").error! end end end end if profiles inner_transport.execute("lxc profile assign #{container_name} #{profiles.join(",")}").error! unless profiles == existing[:profiles] end container container_name end |