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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/lib/podman.rb +1 -0
  3. data/lib/vagrant/podman/action/build.rb +99 -0
  4. data/lib/vagrant/podman/action/compare_synced_folders.rb +65 -0
  5. data/lib/vagrant/podman/action/connect_networks.rb +80 -0
  6. data/lib/vagrant/podman/action/create.rb +165 -0
  7. data/lib/vagrant/podman/action/destroy.rb +34 -0
  8. data/lib/vagrant/podman/action/destroy_build_image.rb +51 -0
  9. data/lib/vagrant/podman/action/destroy_network.rb +53 -0
  10. data/lib/vagrant/podman/action/forwarded_ports.rb +36 -0
  11. data/lib/vagrant/podman/action/has_ssh.rb +21 -0
  12. data/lib/vagrant/podman/action/host_machine.rb +75 -0
  13. data/lib/vagrant/podman/action/host_machine_build_dir.rb +49 -0
  14. data/lib/vagrant/podman/action/host_machine_port_checker.rb +34 -0
  15. data/lib/vagrant/podman/action/host_machine_port_warning.rb +40 -0
  16. data/lib/vagrant/podman/action/host_machine_required.rb +20 -0
  17. data/lib/vagrant/podman/action/host_machine_sync_folders.rb +176 -0
  18. data/lib/vagrant/podman/action/host_machine_sync_folders_disable.rb +91 -0
  19. data/lib/vagrant/podman/action/init_state.rb +23 -0
  20. data/lib/vagrant/podman/action/is_build.rb +19 -0
  21. data/lib/vagrant/podman/action/is_host_machine_created.rb +32 -0
  22. data/lib/vagrant/podman/action/login.rb +51 -0
  23. data/lib/vagrant/podman/action/prepare_forwarded_port_collision_params.rb +64 -0
  24. data/lib/vagrant/podman/action/prepare_networks.rb +397 -0
  25. data/lib/vagrant/podman/action/prepare_nfs_settings.rb +60 -0
  26. data/lib/vagrant/podman/action/prepare_nfs_valid_ids.rb +22 -0
  27. data/lib/vagrant/podman/action/prepare_ssh.rb +48 -0
  28. data/lib/vagrant/podman/action/pull.rb +30 -0
  29. data/lib/vagrant/podman/action/start.rb +24 -0
  30. data/lib/vagrant/podman/action/stop.rb +24 -0
  31. data/lib/vagrant/podman/action/wait_for_running.rb +71 -0
  32. data/lib/vagrant/podman/action.rb +319 -0
  33. data/lib/vagrant/podman/cap/has_communicator.rb +14 -0
  34. data/lib/vagrant/podman/cap/proxy_machine.rb +15 -0
  35. data/lib/vagrant/podman/cap/public_address.rb +26 -0
  36. data/lib/vagrant/podman/command/exec.rb +112 -0
  37. data/lib/vagrant/podman/command/logs.rb +111 -0
  38. data/lib/vagrant/podman/command/run.rb +76 -0
  39. data/lib/vagrant/podman/communicator.rb +199 -0
  40. data/lib/vagrant/podman/config.rb +368 -0
  41. data/lib/vagrant/podman/driver/compose.rb +315 -0
  42. data/lib/vagrant/podman/driver.rb +417 -0
  43. data/lib/vagrant/podman/errors.rb +108 -0
  44. data/lib/vagrant/podman/executor/local.rb +48 -0
  45. data/lib/vagrant/podman/executor/vagrant.rb +88 -0
  46. data/lib/vagrant/podman/hostmachine/Vagrantfile +3 -0
  47. data/lib/vagrant/podman/plugin.rb +89 -0
  48. data/lib/vagrant/podman/provider.rb +216 -0
  49. data/lib/vagrant/podman/synced_folder.rb +35 -0
  50. data/templates/locales/providers_podman.yml +321 -0
  51. metadata +103 -0
@@ -0,0 +1,49 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ require "digest/md5"
5
+
6
+ require "log4r"
7
+
8
+ module VagrantPlugins
9
+ module PodmanProvider
10
+ module Action
11
+ class HostMachineBuildDir
12
+ def initialize(app, env)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant::podman::hostmachinebuilddir")
15
+ end
16
+
17
+ def call(env)
18
+ machine = env[:machine]
19
+ build_dir = machine.provider_config.build_dir
20
+
21
+ # If we're not building a Podmanfile, ignore
22
+ return @app.call(env) if !build_dir
23
+
24
+ # If we're building a podman file, expand the directory
25
+ build_dir = File.expand_path(build_dir, env[:machine].env.root_path)
26
+ env[:build_dir] = build_dir
27
+
28
+ # If we're not on a host VM, we're done
29
+ return @app.call(env) if !machine.provider.host_vm?
30
+
31
+ # We're on a host VM, so we need to move our build dir to
32
+ # that machine. We do this by putting the synced folder on
33
+ # ourself and letting HostMachineSyncFolders handle it.
34
+ new_build_dir = "/var/lib/podman/podman_build_#{Digest::MD5.hexdigest(build_dir)}"
35
+ options = {
36
+ podman__ignore: true,
37
+ podman__exact: true,
38
+ }.merge(machine.provider_config.host_vm_build_dir_options || {})
39
+ machine.config.vm.synced_folder(build_dir, new_build_dir, options)
40
+
41
+ # Set the build dir to be the correct one
42
+ env[:build_dir] = new_build_dir
43
+
44
+ @app.call(env)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ require "log4r"
5
+
6
+ module VagrantPlugins
7
+ module PodmanProvider
8
+ module Action
9
+ # This sets up the middleware env var to check for ports in use.
10
+ class HostMachinePortChecker
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant::podman::hostmachineportchecker")
14
+ end
15
+
16
+ def call(env)
17
+ return @app.call(env) if !env[:machine].provider.host_vm?
18
+
19
+ @machine = env[:machine]
20
+ env[:port_collision_port_check] = method(:port_check)
21
+
22
+ @app.call(env)
23
+ end
24
+
25
+ protected
26
+
27
+ def port_check(port)
28
+ host_machine = @machine.provider.host_vm
29
+ host_machine.guest.capability(:port_open_check, port)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ class HostMachinePortWarning
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ if !env[:machine].provider.host_vm?
14
+ return @app.call(env)
15
+ end
16
+
17
+ # If we have forwarded ports, then notify the user that they
18
+ # won't be immediately available unless a private network
19
+ # is created.
20
+ if has_forwarded_ports?(env[:machine])
21
+ env[:machine].ui.warn(I18n.t(
22
+ "podman_provider.host_machine_forwarded_ports"))
23
+ end
24
+
25
+ @app.call(env)
26
+ end
27
+
28
+ protected
29
+
30
+ def has_forwarded_ports?(machine)
31
+ machine.config.vm.networks.each do |type, _|
32
+ return true if type == :forwarded_port
33
+ end
34
+
35
+ false
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ # This middleware is used with Call to test if we're using a host VM.
8
+ class HostMachineRequired
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ env[:result] = env[:machine].provider.host_vm?
15
+ @app.call(env)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,176 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ require "digest/md5"
5
+ require "securerandom"
6
+
7
+ require "log4r"
8
+
9
+ require "vagrant/action/builtin/mixin_synced_folders"
10
+
11
+ module VagrantPlugins
12
+ module PodmanProvider
13
+ module Action
14
+ # This action is responsible for creating the host machine if
15
+ # we need to. The host machine is where Podman containers will
16
+ # live.
17
+ class HostMachineSyncFolders
18
+ include Vagrant::Action::Builtin::MixinSyncedFolders
19
+
20
+ def initialize(app, env)
21
+ @app = app
22
+ @logger = Log4r::Logger.new("vagrant::podman::hostmachine")
23
+ end
24
+
25
+ def call(env)
26
+ return @app.call(env) if !env[:machine].provider.host_vm?
27
+
28
+ if !env.key?(:host_machine_sync_folders)
29
+ env[:host_machine_sync_folders] = true
30
+ end
31
+
32
+ host_machine = env[:machine].provider.host_vm
33
+
34
+ # Lock while we make changes
35
+ begin
36
+ env[:machine].provider.host_vm_lock do
37
+ setup_synced_folders(host_machine, env)
38
+ end
39
+ rescue Vagrant::Errors::EnvironmentLockedError
40
+ sleep 1
41
+ retry
42
+ end
43
+
44
+ @app.call(env)
45
+ end
46
+
47
+ protected
48
+
49
+ def setup_synced_folders(host_machine, env)
50
+ # Write the host machine SFID if we have one
51
+ id_path = env[:machine].data_dir.join("host_machine_sfid")
52
+ if !id_path.file?
53
+ host_sfid = SecureRandom.uuid
54
+ id_path.open("w") do |f|
55
+ f.binmode
56
+ f.write("#{host_sfid}\n")
57
+ end
58
+ else
59
+ host_sfid = id_path.read.chomp
60
+ end
61
+
62
+ # Create a UI for this machine that stays at the detail level
63
+ proxy_ui = host_machine.ui.dup
64
+ proxy_ui.opts[:bold] = false
65
+ proxy_ui.opts[:prefix_spaces] = true
66
+ proxy_ui.opts[:target] = env[:machine].name.to_s
67
+
68
+ # Read the existing folders that are setup
69
+ existing_folders = synced_folders(host_machine, cached: true)
70
+ existing_ids = {}
71
+ if existing_folders
72
+ existing_folders.each do |impl, fs|
73
+ fs.each do |_name, data|
74
+ if data[:podman_sfid] && data[:podman_host_sfid] == host_sfid
75
+ existing_ids[data[:podman_sfid]] = data
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ # Sync some folders so that our volumes work later.
82
+ new_config = VagrantPlugins::Kernel_V2::VMConfig.new
83
+ our_folders = synced_folders(env[:machine])
84
+ our_folders.each do |type, folders|
85
+ folders.each do |id, data|
86
+ data = data.dup
87
+
88
+ if type == :podman
89
+ # We don't use the Podman type explicitly on the host VM
90
+ data.delete(:type)
91
+ end
92
+
93
+ # Expand the hostpath relative to _our_ root path. Otherwise,
94
+ # it expands it relative to the proxy VM, which is not what
95
+ # we want.
96
+ data[:hostpath] = File.expand_path(
97
+ data[:hostpath], env[:machine].env.root_path)
98
+
99
+ # Generate an ID that is deterministic based on our machine
100
+ # and Vagrantfile path...
101
+ id = Digest::MD5.hexdigest(
102
+ "#{env[:machine].env.root_path}" +
103
+ "#{data[:hostpath]}" +
104
+ "#{data[:guestpath]}" +
105
+ "#{env[:machine].name}")
106
+
107
+ # Generate a new guestpath
108
+ data[:podman_guestpath] = data[:guestpath]
109
+ data[:podman_sfid] = id
110
+ data[:podman_host_sfid] = host_sfid
111
+ data[:id] = id[0...6] + rand(10000).to_s
112
+
113
+ # If we specify exact then we know what we're doing
114
+ if !data[:podman__exact]
115
+ data[:guestpath] = "/var/lib/podman/podman_#{id}"
116
+ end
117
+
118
+ # Add this synced folder onto the new config if we haven't
119
+ # already shared it before.
120
+ if !existing_ids.key?(id)
121
+ # A bit of a hack for VirtualBox to mount our
122
+ # folder as transient. This can be removed once
123
+ # the VirtualBox synced folder mechanism is smarter.
124
+ data[:virtualbox__transient] = true
125
+
126
+ new_config.synced_folder(
127
+ data[:hostpath],
128
+ data[:guestpath],
129
+ data)
130
+ else
131
+ # We already have the folder, so just load its data
132
+ data = existing_ids[id]
133
+ end
134
+
135
+ # Remove from our machine
136
+ env[:machine].config.vm.synced_folders.delete(id)
137
+
138
+ # Add the "fixed" folder to our machine
139
+ data = data.merge({
140
+ hostpath_exact: true,
141
+ type: :podman,
142
+ })
143
+ env[:machine].config.vm.synced_folder(
144
+ data[:guestpath],
145
+ data[:podman_guestpath],
146
+ data)
147
+ end
148
+ end
149
+
150
+ if !env[:host_machine_sync_folders]
151
+ @logger.info("Not syncing folders because container created.")
152
+ end
153
+
154
+ if !new_config.synced_folders.empty?
155
+ # Sync the folders!
156
+ env[:machine].ui.output(I18n.t(
157
+ "podman_provider.host_machine_syncing_folders"))
158
+ host_machine.with_ui(proxy_ui) do
159
+ action_env = { synced_folders_config: new_config }
160
+ begin
161
+ host_machine.action(:sync_folders, action_env)
162
+ rescue Vagrant::Errors::MachineActionLockedError
163
+ sleep 1
164
+ retry
165
+ rescue Vagrant::Errors::UnimplementedProviderAction
166
+ callable = Vagrant::Action::Builder.new
167
+ callable.use Vagrant::Action::Builtin::SyncedFolders
168
+ host_machine.action_raw(:sync_folders, callable, action_env)
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,91 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ require "log4r"
5
+
6
+ require "vagrant/action/builtin/mixin_synced_folders"
7
+
8
+ module VagrantPlugins
9
+ module PodmanProvider
10
+ module Action
11
+ # This action disables the synced folders we created.
12
+ class HostMachineSyncFoldersDisable
13
+ include Vagrant::Action::Builtin::MixinSyncedFolders
14
+
15
+ def initialize(app, env)
16
+ @app = app
17
+ @logger = Log4r::Logger.new("vagrant::podman::hostmachine")
18
+ end
19
+
20
+ def call(env)
21
+ return @app.call(env) if !env[:machine].provider.host_vm?
22
+
23
+ # Read our random ID for this instance
24
+ id_path = env[:machine].data_dir.join("host_machine_sfid")
25
+ return @app.call(env) if !id_path.file?
26
+ host_sfid = id_path.read.chomp
27
+
28
+ host_machine = env[:machine].provider.host_vm
29
+
30
+ @app.call(env)
31
+
32
+ begin
33
+ env[:machine].provider.host_vm_lock do
34
+ setup_synced_folders(host_machine, host_sfid, env)
35
+ end
36
+ rescue Vagrant::Errors::EnvironmentLockedError
37
+ sleep 1
38
+ retry
39
+ end
40
+ end
41
+
42
+ protected
43
+
44
+ def setup_synced_folders(host_machine, host_sfid, env)
45
+ to_disable = []
46
+
47
+ # Read the existing folders that are setup
48
+ existing_folders = synced_folders(host_machine, cached: true)
49
+ if existing_folders
50
+ existing_folders.each do |impl, fs|
51
+ fs.each do |id, data|
52
+ if data[:podman_host_sfid] == host_sfid
53
+ to_disable << id
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Nothing to do if we have no bad folders
60
+ return if to_disable.empty?
61
+
62
+ # Create a UI for this machine that stays at the detail level
63
+ proxy_ui = host_machine.ui.dup
64
+ proxy_ui.opts[:bold] = false
65
+ proxy_ui.opts[:prefix_spaces] = true
66
+ proxy_ui.opts[:target] = env[:machine].name.to_s
67
+
68
+ env[:machine].ui.output(I18n.t(
69
+ "podman_provider.host_machine_disabling_folders"))
70
+ host_machine.with_ui(proxy_ui) do
71
+ action_env = {
72
+ synced_folders_cached: true,
73
+ synced_folders_disable: to_disable,
74
+ }
75
+
76
+ begin
77
+ host_machine.action(:sync_folders, action_env)
78
+ rescue Vagrant::Errors::MachineActionLockedError
79
+ sleep 1
80
+ retry
81
+ rescue Vagrant::Errors::UnimplementedProviderAction
82
+ callable = Vagrant::Action::Builder.new
83
+ callable.use Vagrant::Action::Builtin::SyncedFolders
84
+ host_machine.action_raw(:sync_folders, callable, action_env)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ class InitState
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ # We set the ID of the machine to "preparing" so that we can use
14
+ # the data dir without it being deleted with the not_created state.
15
+ env[:machine].id = nil
16
+ env[:machine].id = "preparing"
17
+
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ class IsBuild
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ env[:result] = (!!env[:machine].provider_config.build_dir || !!env[:machine].provider_config.git_repo)
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ class IsHostMachineCreated
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ if !env[:machine].provider.host_vm?
14
+ env[:result] = true
15
+ return @app.call(env)
16
+ end
17
+
18
+ host_machine = env[:machine].provider.host_vm
19
+ env[:result] =
20
+ host_machine.state.id != Vagrant::MachineState::NOT_CREATED_ID
21
+
22
+ # If the host machine isn't created, neither are we. It is
23
+ # important we set this to nil here so that global-status
24
+ # sees the right thing.
25
+ env[:machine].id = nil if !env[:result]
26
+
27
+ @app.call(env)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ require "log4r"
5
+
6
+ module VagrantPlugins
7
+ module PodmanProvider
8
+ module Action
9
+ class Login
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("vagrant::podman::login")
13
+ end
14
+
15
+ def login(env, config, driver)
16
+ # Login!
17
+ env[:ui].output(I18n.t("podman_provider.logging_in"))
18
+ driver.login(
19
+ config.email, config.username,
20
+ config.password, config.auth_server)
21
+
22
+ # Continue, so that the auth is protected
23
+ # from meddling.
24
+ @app.call(env)
25
+
26
+ # Log out
27
+ driver.logout(config.auth_server)
28
+ end
29
+
30
+ def call(env)
31
+ config = env[:machine].provider_config
32
+ driver = env[:machine].provider.driver
33
+
34
+ # If we don't have a password set, don't auth
35
+ return @app.call(env) if config.password == ""
36
+
37
+ if !env[:machine].provider.host_vm?
38
+ # no host vm in use, using podman directly
39
+ login(env, config, driver)
40
+ else
41
+ # Grab a host VM lock to do the login so that we only login
42
+ # once per container for the rest of this process.
43
+ env[:machine].provider.host_vm_lock do
44
+ login(env, config, driver)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,64 @@
1
+ # Copyright (c) HashiCorp, Inc.
2
+ # SPDX-License-Identifier: BUSL-1.1
3
+
4
+ module VagrantPlugins
5
+ module PodmanProvider
6
+ module Action
7
+ class PrepareForwardedPortCollisionParams
8
+ def initialize(app, env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ machine = env[:machine]
14
+
15
+ # Get the forwarded ports used by other containers and
16
+ # consider those in use as well.
17
+ other_used_ports = machine.provider.driver.read_used_ports
18
+ env[:port_collision_extra_in_use] = other_used_ports
19
+
20
+ # Build the remap for any existing collision detections
21
+ #
22
+ # Note: This remap might not be required yet (as it is with the virtualbox provider)
23
+ # so for now we leave the remap hash empty.
24
+ remap = {}
25
+ env[:port_collision_remap] = remap
26
+
27
+ # This port checker method calls the custom port_check method
28
+ # defined below. If its false, it will go ahead and use the built-in
29
+ # port_check method to see if there are any live containers with bound
30
+ # ports
31
+ podman_port_check = proc { |host_ip, host_port|
32
+ result = port_check(env, host_port)
33
+ if !result
34
+ result = Vagrant::Action::Builtin::HandleForwardedPortCollisions.port_check(machine, host_ip, host_port)
35
+ end
36
+ result}
37
+ env[:port_collision_port_check] = podman_port_check
38
+
39
+ @app.call(env)
40
+ end
41
+
42
+ protected
43
+
44
+ # This check is required the podman provider. Containers
45
+ # can bind ports but be halted. We don't want new containers to
46
+ # grab these bound ports, so this check is here for that since
47
+ # the checks above won't detect it
48
+ #
49
+ # @param [Vagrant::Environment] env
50
+ # @param [String] host_port
51
+ # @returns [Bool]
52
+ def port_check(env, host_port)
53
+ extra_in_use = env[:port_collision_extra_in_use]
54
+
55
+ if extra_in_use
56
+ return extra_in_use.include?(host_port.to_s)
57
+ else
58
+ return false
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end