Module: OsCtld::ContainerControl::Utils::Runscript::Runner
- Included in:
- Commands::Exec::Runner, Commands::Runscript::Runner
- Defined in:
- lib/osctld/container_control/utils/runscript.rb
Instance Method Summary collapse
-
#osctld_wrapper_callback ⇒ Object
Callback to osctld to relocate self-process from container’s wrapper cgroup.
-
#runscript_run(opts) ⇒ Object
Execute script in a stopped container.
-
#with_configured_network(opts) ⇒ Object
Start container with lxc-init, configure network and yield.
Instance Method Details
#osctld_wrapper_callback ⇒ Object
Callback to osctld to relocate self-process from container’s wrapper cgroup
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/osctld/container_control/utils/runscript.rb', line 151 def osctld_wrapper_callback s = UNIXSocket.new("/run/osctl/user-control/#{Process.uid}.sock") payload = { cmd: :ct_wrapper_start, opts: { id: ctid, pool:, pid: Process.pid } } s.send("#{payload.to_json}\n", 0) ret = JSON.parse(s.readline, symbolize_names: true) s.close return if ret[:status] raise "Error during ct_wrapper_start callback: #{ret[:message]}" end |
#runscript_run(opts) ⇒ Object
Execute script in a stopped container
47 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 |
# File 'lib/osctld/container_control/utils/runscript.rb', line 47 def runscript_run(opts) pid = Process.fork do cur_stdin = opts.fetch(:stdin, stdin) cur_stdout = opts.fetch(:stdout, stdout) cur_stderr = opts.fetch(:stderr, stderr) if cur_stdin $stdin.reopen(cur_stdin) else $stdin.close end $stdout.reopen(cur_stdout) $stderr.reopen(cur_stderr) if cur_stderr opts[:close_fds] && opts[:close_fds].each(&:close) setup_exec_run_env osctld_wrapper_callback cmd = [ 'lxc-execute', '-P', lxc_home, '-n', ctid, '-o', log_file, '-s', "lxc.environment=PATH=#{system_path.join(':')}", '-s', 'lxc.environment=HOME=/root', '-s', 'lxc.environment=USER=root', '--', opts[:script] ] # opts[:cmd] can contain an arbitrary command with multiple arguments # and quotes, so the mapping to process arguments is not clear. We use # the shell to handle this. Process.exec("exec #{cmd.join(' ')}") end if opts[:wait] === false pid else _, status = Process.wait2(pid) ok(status.exitstatus) end end |
#with_configured_network(opts) ⇒ Object
Start container with lxc-init, configure network and yield
opts has to contain path to a script that will be executed by lxc-init. The purpose of this script is to keep the container running while the network is being configured and the user command is executed. The script has to write ‘readyn` to standard output, then block on read from standard input and exit.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/osctld/container_control/utils/runscript.rb', line 105 def with_configured_network(opts) ret = nil # Pipes for communicating with opts[:init_script] in_r, in_w = IO.pipe out_r, out_w = IO.pipe # Start the container with lxc-init init_pid = runscript_run( id: ctid, script: opts[:init_script], stdin: in_r, stdout: out_w, stderr: nil, close_fds: [in_w, out_r], wait: false ) in_r.close out_w.close # Wait for the container to be started if out_r.readline.strip == 'ready' # Configure network pid = lxc_ct.attach do setup_exec_env ENV['HOME'] = '/root' ENV['USER'] = 'root' NetConfig.import(opts[:net_config]).setup end Process.wait2(pid) # Execute user command ret = yield end # Closing in_w will bring down opts[:init_script] and stop the container in_w.close out_r.close _, status = Process.wait2(init_pid) ret || ok(status.exitstatus) end |