podman 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/podman.rb +1 -0
- data/lib/vagrant/podman/action/build.rb +99 -0
- data/lib/vagrant/podman/action/compare_synced_folders.rb +65 -0
- data/lib/vagrant/podman/action/connect_networks.rb +80 -0
- data/lib/vagrant/podman/action/create.rb +165 -0
- data/lib/vagrant/podman/action/destroy.rb +34 -0
- data/lib/vagrant/podman/action/destroy_build_image.rb +51 -0
- data/lib/vagrant/podman/action/destroy_network.rb +53 -0
- data/lib/vagrant/podman/action/forwarded_ports.rb +36 -0
- data/lib/vagrant/podman/action/has_ssh.rb +21 -0
- data/lib/vagrant/podman/action/host_machine.rb +75 -0
- data/lib/vagrant/podman/action/host_machine_build_dir.rb +49 -0
- data/lib/vagrant/podman/action/host_machine_port_checker.rb +34 -0
- data/lib/vagrant/podman/action/host_machine_port_warning.rb +40 -0
- data/lib/vagrant/podman/action/host_machine_required.rb +20 -0
- data/lib/vagrant/podman/action/host_machine_sync_folders.rb +176 -0
- data/lib/vagrant/podman/action/host_machine_sync_folders_disable.rb +91 -0
- data/lib/vagrant/podman/action/init_state.rb +23 -0
- data/lib/vagrant/podman/action/is_build.rb +19 -0
- data/lib/vagrant/podman/action/is_host_machine_created.rb +32 -0
- data/lib/vagrant/podman/action/login.rb +51 -0
- data/lib/vagrant/podman/action/prepare_forwarded_port_collision_params.rb +64 -0
- data/lib/vagrant/podman/action/prepare_networks.rb +397 -0
- data/lib/vagrant/podman/action/prepare_nfs_settings.rb +60 -0
- data/lib/vagrant/podman/action/prepare_nfs_valid_ids.rb +22 -0
- data/lib/vagrant/podman/action/prepare_ssh.rb +48 -0
- data/lib/vagrant/podman/action/pull.rb +30 -0
- data/lib/vagrant/podman/action/start.rb +24 -0
- data/lib/vagrant/podman/action/stop.rb +24 -0
- data/lib/vagrant/podman/action/wait_for_running.rb +71 -0
- data/lib/vagrant/podman/action.rb +319 -0
- data/lib/vagrant/podman/cap/has_communicator.rb +14 -0
- data/lib/vagrant/podman/cap/proxy_machine.rb +15 -0
- data/lib/vagrant/podman/cap/public_address.rb +26 -0
- data/lib/vagrant/podman/command/exec.rb +112 -0
- data/lib/vagrant/podman/command/logs.rb +111 -0
- data/lib/vagrant/podman/command/run.rb +76 -0
- data/lib/vagrant/podman/communicator.rb +199 -0
- data/lib/vagrant/podman/config.rb +368 -0
- data/lib/vagrant/podman/driver/compose.rb +315 -0
- data/lib/vagrant/podman/driver.rb +417 -0
- data/lib/vagrant/podman/errors.rb +108 -0
- data/lib/vagrant/podman/executor/local.rb +48 -0
- data/lib/vagrant/podman/executor/vagrant.rb +88 -0
- data/lib/vagrant/podman/hostmachine/Vagrantfile +3 -0
- data/lib/vagrant/podman/plugin.rb +89 -0
- data/lib/vagrant/podman/provider.rb +216 -0
- data/lib/vagrant/podman/synced_folder.rb +35 -0
- data/templates/locales/providers_podman.yml +321 -0
- metadata +103 -0
@@ -0,0 +1,319 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Action
|
7
|
+
# Include the built-in modules so we can use them as top-level things.
|
8
|
+
include Vagrant::Action::Builtin
|
9
|
+
|
10
|
+
# This action starts another container just like the real one running
|
11
|
+
# but only for the purpose of running a single command rather than
|
12
|
+
# to exist long-running.
|
13
|
+
def self.action_run_command
|
14
|
+
Vagrant::Action::Builder.new.tap do |b|
|
15
|
+
# We just call the "up" action. We create a separate action
|
16
|
+
# to hold this though in case we modify it in the future, and
|
17
|
+
# so that we can switch on the "machine_action" env var.
|
18
|
+
b.use action_up
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# This action brings the "machine" up from nothing, including creating the
|
23
|
+
# container, configuring metadata, and booting.
|
24
|
+
def self.action_up
|
25
|
+
Vagrant::Action::Builder.new.tap do |b|
|
26
|
+
b.use Call, IsState, :not_created do |env, b2|
|
27
|
+
if env[:result]
|
28
|
+
b2.use HandleBox
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
b.use ConfigValidate
|
33
|
+
b.use HostMachine
|
34
|
+
|
35
|
+
# Yeah, this is supposed to be here twice (once more above). This
|
36
|
+
# catches the case when the container was supposed to be created,
|
37
|
+
# but the host state was unknown, and now we know its not actually
|
38
|
+
# created.
|
39
|
+
b.use Call, IsState, :not_created do |env, b2|
|
40
|
+
if env[:result]
|
41
|
+
b2.use HandleBox
|
42
|
+
b2.use DestroyBuildImage
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
b.use action_start
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.action_package
|
51
|
+
lambda do |env|
|
52
|
+
raise Errors::PackageNotSupported
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# This action just runs the provisioners on the machine.
|
57
|
+
def self.action_provision
|
58
|
+
Vagrant::Action::Builder.new.tap do |b|
|
59
|
+
b.use ConfigValidate
|
60
|
+
b.use Call, IsState, :not_created do |env, b2|
|
61
|
+
if env[:result]
|
62
|
+
b2.use Message, I18n.t("podman_provider.messages.not_created")
|
63
|
+
next
|
64
|
+
end
|
65
|
+
|
66
|
+
b2.use Call, IsState, :running do |env2, b3|
|
67
|
+
if !env2[:result]
|
68
|
+
b3.use Message, I18n.t("podman_provider.messages.not_running")
|
69
|
+
next
|
70
|
+
end
|
71
|
+
|
72
|
+
b3.use Call, HasProvisioner do |env3, b4|
|
73
|
+
b4.use Provision
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# This is the action that is primarily responsible for halting
|
81
|
+
# the virtual machine, gracefully or by force.
|
82
|
+
def self.action_halt
|
83
|
+
Vagrant::Action::Builder.new.tap do |b|
|
84
|
+
b.use Call, IsState, :host_state_unknown do |env, b2|
|
85
|
+
if env[:result]
|
86
|
+
b2.use HostMachine
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
b.use Call, IsState, :not_created do |env, b2|
|
91
|
+
if env[:result]
|
92
|
+
b2.use Message, I18n.t("podman_provider.messages.not_created")
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
96
|
+
b2.use Stop
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# This action is responsible for reloading the machine, which
|
102
|
+
# brings it down, sucks in new configuration, and brings the
|
103
|
+
# machine back up with the new configuration.
|
104
|
+
def self.action_reload
|
105
|
+
Vagrant::Action::Builder.new.tap do |b|
|
106
|
+
b.use ConfigValidate
|
107
|
+
b.use Call, IsState, :not_created do |env, b2|
|
108
|
+
if env[:result]
|
109
|
+
b2.use Message, I18n.t("podman_provider.messages.not_created")
|
110
|
+
next
|
111
|
+
end
|
112
|
+
|
113
|
+
b2.use action_halt
|
114
|
+
|
115
|
+
b2.use Call, IsBuild do |env2, b3|
|
116
|
+
if env2[:result]
|
117
|
+
b3.use EnvSet, force_halt: true
|
118
|
+
b3.use action_halt
|
119
|
+
b3.use HostMachineSyncFoldersDisable
|
120
|
+
b3.use Destroy
|
121
|
+
b3.use ProvisionerCleanup
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
b2.use action_start
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# This is the action that is primarily responsible for completely
|
131
|
+
# freeing the resources of the underlying virtual machine.
|
132
|
+
def self.action_destroy
|
133
|
+
Vagrant::Action::Builder.new.tap do |b|
|
134
|
+
b.use Call, IsHostMachineCreated do |env, b2|
|
135
|
+
if !env[:result]
|
136
|
+
b2.use Message, I18n.t("podman_provider.messages.not_created")
|
137
|
+
next
|
138
|
+
end
|
139
|
+
|
140
|
+
b2.use Call, IsState, :host_state_unknown do |env2, b3|
|
141
|
+
if env2[:result]
|
142
|
+
b3.use HostMachine
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
b2.use Call, IsState, :not_created do |env2, b3|
|
147
|
+
if env2[:result]
|
148
|
+
b3.use Message,
|
149
|
+
I18n.t("podman_provider.messages.not_created")
|
150
|
+
next
|
151
|
+
end
|
152
|
+
|
153
|
+
b3.use Call, DestroyConfirm do |env3, b4|
|
154
|
+
if env3[:result]
|
155
|
+
b4.use ConfigValidate
|
156
|
+
b4.use ProvisionerCleanup, :before
|
157
|
+
b4.use EnvSet, force_halt: true
|
158
|
+
b4.use action_halt
|
159
|
+
b4.use HostMachineSyncFoldersDisable
|
160
|
+
b4.use Destroy
|
161
|
+
b4.use DestroyNetwork
|
162
|
+
b4.use DestroyBuildImage
|
163
|
+
else
|
164
|
+
b4.use Message,
|
165
|
+
I18n.t("podman_provider.messages.will_not_destroy")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# This is the action that will exec into an SSH shell.
|
174
|
+
def self.action_ssh
|
175
|
+
Vagrant::Action::Builder.new.tap do |b|
|
176
|
+
b.use Call, IsState, :not_created do |env, b2|
|
177
|
+
if env[:result]
|
178
|
+
raise Errors::ContainerNotCreatedError
|
179
|
+
end
|
180
|
+
|
181
|
+
b2.use Call, IsState, :running do |env2, b3|
|
182
|
+
if !env2[:result]
|
183
|
+
raise Errors::ContainerNotRunningError
|
184
|
+
end
|
185
|
+
|
186
|
+
b3.use PrepareSSH
|
187
|
+
b3.use SSHExec
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# This is the action that will run a single SSH command.
|
194
|
+
def self.action_ssh_run
|
195
|
+
Vagrant::Action::Builder.new.tap do |b|
|
196
|
+
b.use Call, IsState, :not_created do |env, b2|
|
197
|
+
if env[:result]
|
198
|
+
raise Errors::ContainerNotCreatedError
|
199
|
+
end
|
200
|
+
|
201
|
+
b2.use Call, IsState, :running do |env2, b3|
|
202
|
+
if !env2[:result]
|
203
|
+
raise Errors::ContainerNotRunningError
|
204
|
+
end
|
205
|
+
|
206
|
+
b3.use SSHRun
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.action_start
|
213
|
+
Vagrant::Action::Builder.new.tap do |b|
|
214
|
+
b.use Call, IsState, :running do |env, b2|
|
215
|
+
if env[:machine_action] != :run_command
|
216
|
+
b2.use Call, HasProvisioner do |env2, b3|
|
217
|
+
b3.use Provision
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# If the container is running and we're doing a run, we're done
|
222
|
+
next if env[:result] && env[:machine_action] != :run_command
|
223
|
+
|
224
|
+
b2.use Call, IsState, :not_created do |env2, b3|
|
225
|
+
if env2[:result]
|
226
|
+
# First time making this thing, set to the "preparing" state
|
227
|
+
b3.use InitState
|
228
|
+
else
|
229
|
+
b3.use EnvSet, host_machine_sync_folders: false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
b2.use HostMachineBuildDir
|
234
|
+
b2.use HostMachineSyncFolders
|
235
|
+
b2.use PrepareNFSValidIds
|
236
|
+
b2.use SyncedFolderCleanup
|
237
|
+
b2.use SyncedFolders
|
238
|
+
b2.use PrepareNFSSettings
|
239
|
+
b2.use PrepareNetworks
|
240
|
+
b2.use Login
|
241
|
+
b2.use Build
|
242
|
+
|
243
|
+
if env[:machine_action] != :run_command
|
244
|
+
# If the container is NOT created yet, then do some setup steps
|
245
|
+
# necessary for creating it.
|
246
|
+
|
247
|
+
b2.use Call, IsState, :preparing do |env2, b3|
|
248
|
+
if env2[:result]
|
249
|
+
b3.use EnvSet, port_collision_repair: true
|
250
|
+
b3.use HostMachinePortWarning
|
251
|
+
b3.use HostMachinePortChecker
|
252
|
+
b3.use ForwardedPorts # This action converts the `ports` param into proper network configs
|
253
|
+
b3.use PrepareForwardedPortCollisionParams
|
254
|
+
b3.use HandleForwardedPortCollisions
|
255
|
+
b3.use Pull
|
256
|
+
b3.use Create
|
257
|
+
b3.use WaitForRunning
|
258
|
+
else
|
259
|
+
b3.use CompareSyncedFolders
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
b2.use ConnectNetworks
|
264
|
+
b2.use Start
|
265
|
+
b2.use WaitForRunning
|
266
|
+
|
267
|
+
b2.use Call, HasSSH do |env2, b3|
|
268
|
+
if env2[:result]
|
269
|
+
b3.use WaitForCommunicator
|
270
|
+
end
|
271
|
+
end
|
272
|
+
else
|
273
|
+
# We're in a run command, so we do things a bit differently.
|
274
|
+
b2.use Create
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.action_suspend
|
281
|
+
lambda do |env|
|
282
|
+
raise Errors::SuspendNotSupported
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
# The autoload farm
|
287
|
+
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
288
|
+
autoload :Build, action_root.join("build")
|
289
|
+
autoload :CompareSyncedFolders, action_root.join("compare_synced_folders")
|
290
|
+
autoload :ConnectNetworks, action_root.join("connect_networks")
|
291
|
+
autoload :Create, action_root.join("create")
|
292
|
+
autoload :Destroy, action_root.join("destroy")
|
293
|
+
autoload :DestroyBuildImage, action_root.join("destroy_build_image")
|
294
|
+
autoload :DestroyNetwork, action_root.join("destroy_network")
|
295
|
+
autoload :ForwardedPorts, action_root.join("forwarded_ports")
|
296
|
+
autoload :HasSSH, action_root.join("has_ssh")
|
297
|
+
autoload :HostMachine, action_root.join("host_machine")
|
298
|
+
autoload :HostMachineBuildDir, action_root.join("host_machine_build_dir")
|
299
|
+
autoload :HostMachinePortChecker, action_root.join("host_machine_port_checker")
|
300
|
+
autoload :HostMachinePortWarning, action_root.join("host_machine_port_warning")
|
301
|
+
autoload :HostMachineRequired, action_root.join("host_machine_required")
|
302
|
+
autoload :HostMachineSyncFolders, action_root.join("host_machine_sync_folders")
|
303
|
+
autoload :HostMachineSyncFoldersDisable, action_root.join("host_machine_sync_folders_disable")
|
304
|
+
autoload :InitState, action_root.join("init_state")
|
305
|
+
autoload :IsBuild, action_root.join("is_build")
|
306
|
+
autoload :IsHostMachineCreated, action_root.join("is_host_machine_created")
|
307
|
+
autoload :Login, action_root.join("login")
|
308
|
+
autoload :PrepareForwardedPortCollisionParams, action_root.join("prepare_forwarded_port_collision_params")
|
309
|
+
autoload :PrepareNetworks, action_root.join("prepare_networks")
|
310
|
+
autoload :PrepareNFSValidIds, action_root.join("prepare_nfs_valid_ids")
|
311
|
+
autoload :PrepareNFSSettings, action_root.join("prepare_nfs_settings")
|
312
|
+
autoload :PrepareSSH, action_root.join("prepare_ssh")
|
313
|
+
autoload :Pull, action_root.join("pull")
|
314
|
+
autoload :Start, action_root.join("start")
|
315
|
+
autoload :Stop, action_root.join("stop")
|
316
|
+
autoload :WaitForRunning, action_root.join("wait_for_running")
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Cap
|
7
|
+
module HasCommunicator
|
8
|
+
def self.has_communicator(machine)
|
9
|
+
return machine.provider_config.has_ssh
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Cap
|
7
|
+
module ProxyMachine
|
8
|
+
def self.proxy_machine(machine)
|
9
|
+
return nil if !machine.provider.host_vm?
|
10
|
+
machine.provider.host_vm
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Cap
|
7
|
+
module PublicAddress
|
8
|
+
def self.public_address(machine)
|
9
|
+
return nil if machine.state.id != :running
|
10
|
+
|
11
|
+
# If we're using a host VM, then return the IP of that
|
12
|
+
# rather than of our own machine.
|
13
|
+
if machine.provider.host_vm?
|
14
|
+
host_machine = machine.provider.host_vm
|
15
|
+
return nil if !host_machine.provider.capability?(:public_address)
|
16
|
+
return host_machine.provider.capability(:public_address)
|
17
|
+
end
|
18
|
+
|
19
|
+
ssh_info = machine.ssh_info
|
20
|
+
return nil if !ssh_info
|
21
|
+
ssh_info[:host]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
require 'vagrant/util/safe_exec'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module PodmanProvider
|
8
|
+
module Command
|
9
|
+
class Exec < Vagrant.plugin("2", :command)
|
10
|
+
def self.synopsis
|
11
|
+
"attach to an already-running podman container"
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
options = {}
|
16
|
+
options[:detach] = false
|
17
|
+
options[:pty] = false
|
18
|
+
options[:interactive] = false
|
19
|
+
options[:prefix] = true
|
20
|
+
|
21
|
+
opts = OptionParser.new do |o|
|
22
|
+
o.banner = "Usage: vagrant podman-exec [options] [name] -- <command> [args]"
|
23
|
+
o.separator ""
|
24
|
+
o.separator "Options:"
|
25
|
+
o.separator ""
|
26
|
+
|
27
|
+
o.on("--[no-]detach", "Run in the background") do |d|
|
28
|
+
options[:detach] = d
|
29
|
+
end
|
30
|
+
|
31
|
+
o.on("-i", "--[no-]interactive", "Keep STDIN open even if not attached") do |i|
|
32
|
+
options[:interactive] = i
|
33
|
+
end
|
34
|
+
|
35
|
+
o.on("-t", "--[no-]tty", "Allocate a pty") do |t|
|
36
|
+
options[:pty] = t
|
37
|
+
end
|
38
|
+
|
39
|
+
o.on("-u", "--user USER", "User or UID") do |u|
|
40
|
+
options[:user] = u
|
41
|
+
end
|
42
|
+
|
43
|
+
o.on("--[no-]prefix", "Prefix output with machine names") do |p|
|
44
|
+
options[:prefix] = p
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Parse out the extra args to send to SSH, which is everything
|
49
|
+
# after the "--"
|
50
|
+
command = nil
|
51
|
+
split_index = @argv.index("--")
|
52
|
+
if split_index
|
53
|
+
command = @argv.drop(split_index + 1)
|
54
|
+
@argv = @argv.take(split_index)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parse the options
|
58
|
+
argv = parse_options(opts)
|
59
|
+
return if !argv
|
60
|
+
|
61
|
+
# Show the error if we don't have "--" _after_ parse_options
|
62
|
+
# so that "-h" and "--help" work properly.
|
63
|
+
if !split_index
|
64
|
+
raise Errors::ExecCommandRequired
|
65
|
+
end
|
66
|
+
|
67
|
+
target_opts = { provider: :podman }
|
68
|
+
target_opts[:single_target] = options[:pty]
|
69
|
+
|
70
|
+
with_target_vms(argv, target_opts) do |machine|
|
71
|
+
if machine.state.id != :running
|
72
|
+
@env.ui.info("#{machine.id} is not running.")
|
73
|
+
next
|
74
|
+
end
|
75
|
+
exec_command(machine, command, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
return 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def exec_command(machine, command, options)
|
82
|
+
exec_cmd = %w(podman exec)
|
83
|
+
exec_cmd << "-i" if options[:interactive]
|
84
|
+
exec_cmd << "-t" if options[:pty]
|
85
|
+
exec_cmd << "-u" << options[:user] if options[:user]
|
86
|
+
exec_cmd << machine.id
|
87
|
+
exec_cmd += options[:extra_args] if options[:extra_args]
|
88
|
+
exec_cmd += command
|
89
|
+
|
90
|
+
# Run this interactively if asked.
|
91
|
+
exec_options = options
|
92
|
+
|
93
|
+
if options[:pty]
|
94
|
+
Vagrant::Util::SafeExec.exec(exec_cmd[0], *exec_cmd[1..-1])
|
95
|
+
else
|
96
|
+
output = ""
|
97
|
+
machine.provider.driver.execute(*exec_cmd, exec_options) do |type, data|
|
98
|
+
output += data
|
99
|
+
end
|
100
|
+
|
101
|
+
output_options = {}
|
102
|
+
output_options[:prefix] = false if !options[:prefix]
|
103
|
+
|
104
|
+
if !output.empty?
|
105
|
+
machine.ui.output(output.chomp, **output_options)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Command
|
7
|
+
class Logs < Vagrant.plugin("2", :command)
|
8
|
+
def self.synopsis
|
9
|
+
"outputs the logs from the Podman container"
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
options = {}
|
14
|
+
options[:follow] = false
|
15
|
+
options[:prefix] = true
|
16
|
+
|
17
|
+
opts = OptionParser.new do |o|
|
18
|
+
o.banner = "Usage: vagrant podman-logs [options]"
|
19
|
+
o.separator ""
|
20
|
+
o.separator "Options:"
|
21
|
+
o.separator ""
|
22
|
+
|
23
|
+
o.on("--[no-]follow", "Continue streaming in log output") do |f|
|
24
|
+
options[:follow] = f
|
25
|
+
end
|
26
|
+
|
27
|
+
o.on("--[no-]prefix", "Prefix output with machine names") do |p|
|
28
|
+
options[:prefix] = p
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Parse the options
|
33
|
+
argv = parse_options(opts)
|
34
|
+
return if !argv
|
35
|
+
|
36
|
+
# This keeps track of if we ran our action on any machines...
|
37
|
+
any_success = false
|
38
|
+
|
39
|
+
# Start a batch action that sends all the logs to stdout. This
|
40
|
+
# will parallelize, if enabled, across all containers that are
|
41
|
+
# chosen.
|
42
|
+
@env.batch do |batch|
|
43
|
+
with_target_vms(argv) do |machine|
|
44
|
+
if machine.provider_name != :podman
|
45
|
+
machine.ui.output(I18n.t("podman_provider.not_podman_provider"))
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
|
+
state = machine.state.id
|
50
|
+
if state == :host_state_unknown
|
51
|
+
machine.ui.output(I18n.t("podman_provider.logs_host_state_unknown"))
|
52
|
+
next
|
53
|
+
elsif state == :not_created
|
54
|
+
machine.ui.output(I18n.t("podman_provider.not_created_skip"))
|
55
|
+
next
|
56
|
+
end
|
57
|
+
|
58
|
+
# At least one was run!
|
59
|
+
any_success = true
|
60
|
+
|
61
|
+
batch.custom(machine) do |m|
|
62
|
+
execute_single(m, options)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# If we didn't run on any machines, then exit status 1
|
68
|
+
return any_success ? 0 : 1
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
# Executes the "podman logs" command on a single machine and proxies
|
74
|
+
# the output to our UI.
|
75
|
+
def execute_single(machine, options)
|
76
|
+
command = ["podman", "logs"]
|
77
|
+
command << "--follow" if options[:follow]
|
78
|
+
command << machine.id
|
79
|
+
|
80
|
+
output_options = {}
|
81
|
+
output_options[:prefix] = false if !options[:prefix]
|
82
|
+
|
83
|
+
data_acc = ""
|
84
|
+
machine.provider.driver.execute(*command) do |type, data|
|
85
|
+
# Accumulate the data so we only output lines at a time
|
86
|
+
data_acc << data
|
87
|
+
|
88
|
+
# If we have a newline, then output all the lines we have so far
|
89
|
+
if data_acc.include?("\n")
|
90
|
+
lines = data_acc.split("\n")
|
91
|
+
|
92
|
+
if !data_acc.end_with?("\n")
|
93
|
+
data_acc = lines.pop.chomp
|
94
|
+
else
|
95
|
+
data_acc = ""
|
96
|
+
end
|
97
|
+
|
98
|
+
lines.each do |line|
|
99
|
+
line = " " if line == ""
|
100
|
+
machine.ui.output(line, **output_options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Output any remaining data
|
106
|
+
machine.ui.output(data_acc, **output_options) if !data_acc.empty?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Copyright (c) HashiCorp, Inc.
|
2
|
+
# SPDX-License-Identifier: BUSL-1.1
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module PodmanProvider
|
6
|
+
module Command
|
7
|
+
class Run < Vagrant.plugin("2", :command)
|
8
|
+
def self.synopsis
|
9
|
+
"run a one-off command in the context of a container"
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
options = {}
|
14
|
+
options[:detach] = false
|
15
|
+
options[:pty] = false
|
16
|
+
options[:rm] = true
|
17
|
+
|
18
|
+
opts = OptionParser.new do |o|
|
19
|
+
o.banner = "Usage: vagrant podman-run [command...]"
|
20
|
+
o.separator ""
|
21
|
+
o.separator "Options:"
|
22
|
+
o.separator ""
|
23
|
+
|
24
|
+
o.on("--[no-]detach", "Run in the background") do |d|
|
25
|
+
options[:detach] = d
|
26
|
+
end
|
27
|
+
|
28
|
+
o.on("-t", "--[no-]tty", "Allocate a pty") do |t|
|
29
|
+
options[:pty] = t
|
30
|
+
end
|
31
|
+
|
32
|
+
o.on("-r,", "--[no-]rm", "Remove container after execution") do |r|
|
33
|
+
options[:rm] = r
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parse out the extra args to send to SSH, which is everything
|
38
|
+
# after the "--"
|
39
|
+
command = nil
|
40
|
+
split_index = @argv.index("--")
|
41
|
+
if split_index
|
42
|
+
command = @argv.drop(split_index + 1)
|
43
|
+
@argv = @argv.take(split_index)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parse the options
|
47
|
+
argv = parse_options(opts)
|
48
|
+
return if !argv
|
49
|
+
|
50
|
+
# Show the error if we don't have "--" _after_ parse_options
|
51
|
+
# so that "-h" and "--help" work properly.
|
52
|
+
if !split_index
|
53
|
+
@env.ui.error(I18n.t("podman_provider.run_command_required"))
|
54
|
+
return 1
|
55
|
+
end
|
56
|
+
|
57
|
+
target_opts = { provider: :podman }
|
58
|
+
target_opts[:single_target] = options[:pty]
|
59
|
+
|
60
|
+
with_target_vms(argv, target_opts) do |machine|
|
61
|
+
# Run it!
|
62
|
+
machine.action(
|
63
|
+
:run_command,
|
64
|
+
run_command: command,
|
65
|
+
run_detach: options[:detach],
|
66
|
+
run_pty: options[:pty],
|
67
|
+
run_rm: options[:rm]
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|