Skip to content

Commit

Permalink
Merge pull request #9535 from afbjorklund/podman2-env
Browse files Browse the repository at this point in the history
Add support for podman v2 to podman-env command
  • Loading branch information
medyagh authored Nov 6, 2020
2 parents 939d2d5 + bfefa72 commit 7747655
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 15 deletions.
124 changes: 110 additions & 14 deletions cmd/minikube/cmd/podman-env.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@ import (
"k8s.io/minikube/pkg/minikube/shell"
)

var podmanEnvTmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .VarlinkBridge }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubePodmanProfile }}{{ .Suffix }}{{ .UsageHint }}", constants.PodmanVarlinkBridgeEnv, constants.MinikubeActivePodmanEnv)
var podmanEnv1Tmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .VarlinkBridge }}{{ .Suffix }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubePodmanProfile }}{{ .Suffix }}{{ .UsageHint }}", constants.PodmanVarlinkBridgeEnv, constants.MinikubeActivePodmanEnv)

var podmanEnv2Tmpl = fmt.Sprintf("{{ .Prefix }}%s{{ .Delimiter }}{{ .ContainerHost }}{{ .Suffix }}{{ if .ContainerSSHKey }}{{ .Prefix }}%s{{ .Delimiter }}{{ .ContainerSSHKey}}{{ .Suffix }}{{ end }}{{ .Prefix }}%s{{ .Delimiter }}{{ .MinikubePodmanProfile }}{{ .Suffix }}{{ .UsageHint }}", constants.PodmanContainerHostEnv, constants.PodmanContainerSSHKeyEnv, constants.MinikubeActivePodmanEnv)

// PodmanShellConfig represents the shell config for Podman
type PodmanShellConfig struct {
shell.Config
VarlinkBridge string
ContainerHost string
ContainerSSHKey string
MinikubePodmanProfile string
}

Expand All @@ -59,17 +63,24 @@ func podmanShellCfgSet(ec PodmanEnvConfig, envMap map[string]string) *PodmanShel
Config: *shell.CfgSet(ec.EnvConfig, usgPlz, usgCmd),
}
s.VarlinkBridge = envMap[constants.PodmanVarlinkBridgeEnv]
s.ContainerHost = envMap[constants.PodmanContainerHostEnv]
s.ContainerSSHKey = envMap[constants.PodmanContainerSSHKeyEnv]
s.MinikubePodmanProfile = envMap[constants.MinikubeActivePodmanEnv]

return s
}

// isPodmanAvailable checks if Podman is available
func isPodmanAvailable(r command.Runner) bool {
// isVarlinkAvailable checks if varlink command is available
func isVarlinkAvailable(r command.Runner) bool {
if _, err := r.RunCmd(exec.Command("which", "varlink")); err != nil {
return false
}

return true
}

// isPodmanAvailable checks if podman command is available
func isPodmanAvailable(r command.Runner) bool {
if _, err := r.RunCmd(exec.Command("which", "podman")); err != nil {
return false
}
Expand Down Expand Up @@ -130,11 +141,25 @@ var podmanEnvCmd = &cobra.Command{
exit.Message(reason.Usage, `The podman-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/`)
}

if ok := isPodmanAvailable(co.CP.Runner); !ok {
r := co.CP.Runner
if ok := isPodmanAvailable(r); !ok {
exit.Message(reason.EnvPodmanUnavailable, `The podman service within '{{.cluster}}' is not active`, out.V{"cluster": cname})
}

client, err := createExternalSSHClient(co.CP.Host.Driver)
varlink := isVarlinkAvailable(r)

d := co.CP.Host.Driver
client, err := createExternalSSHClient(d)
if err != nil {
exit.Error(reason.IfSSHClient, "Error getting ssh client", err)
}

hostname, err := d.GetSSHHostname()
if err != nil {
exit.Error(reason.IfSSHClient, "Error getting ssh client", err)
}

port, err := d.GetSSHPort()
if err != nil {
exit.Error(reason.IfSSHClient, "Error getting ssh client", err)
}
Expand All @@ -143,7 +168,12 @@ var podmanEnvCmd = &cobra.Command{
EnvConfig: sh,
profile: cname,
driver: driverName,
varlink: varlink,
client: client,
username: d.GetSSHUsername(),
hostname: hostname,
port: port,
keypath: d.GetSSHKeyPath(),
}

if ec.Shell == "" {
Expand All @@ -162,23 +192,31 @@ var podmanEnvCmd = &cobra.Command{
// PodmanEnvConfig encapsulates all external inputs into shell generation for Podman
type PodmanEnvConfig struct {
shell.EnvConfig
profile string
driver string
client *ssh.ExternalClient
profile string
driver string
varlink bool
client *ssh.ExternalClient
username string
hostname string
port int
keypath string
}

// podmanSetScript writes out a shell-compatible 'podman-env' script
func podmanSetScript(ec PodmanEnvConfig, w io.Writer) error {
var podmanEnvTmpl string
if ec.varlink {
podmanEnvTmpl = podmanEnv1Tmpl
} else {
podmanEnvTmpl = podmanEnv2Tmpl
}
envVars := podmanEnvVars(ec)
return shell.SetScript(ec.EnvConfig, w, podmanEnvTmpl, podmanShellCfgSet(ec, envVars))
}

// podmanUnsetScript writes out a shell-compatible 'podman-env unset' script
func podmanUnsetScript(ec PodmanEnvConfig, w io.Writer) error {
vars := []string{
constants.PodmanVarlinkBridgeEnv,
constants.MinikubeActivePodmanEnv,
}
vars := podmanEnvNames(ec)
return shell.UnsetScript(ec.EnvConfig, w, vars)
}

Expand All @@ -190,15 +228,73 @@ func podmanBridge(client *ssh.ExternalClient) string {
return strings.Join(command, " ")
}

// podmanURL returns the url to use in a var for accessing the podman socket over ssh
func podmanURL(username string, hostname string, port int) string {
path := "/run/podman/podman.sock"
return fmt.Sprintf("ssh://%s@%s:%d%s", username, hostname, port, path)
}

// podmanEnvVars gets the necessary podman env variables to allow the use of minikube's podman service
func podmanEnvVars(ec PodmanEnvConfig) map[string]string {
env := map[string]string{
constants.PodmanVarlinkBridgeEnv: podmanBridge(ec.client),
// podman v1
env1 := map[string]string{
constants.PodmanVarlinkBridgeEnv: podmanBridge(ec.client),
}
// podman v2
env2 := map[string]string{
constants.PodmanContainerHostEnv: podmanURL(ec.username, ec.hostname, ec.port),
constants.PodmanContainerSSHKeyEnv: ec.keypath,
}
//common
env0 := map[string]string{
constants.MinikubeActivePodmanEnv: ec.profile,
}

var env map[string]string
if ec.varlink {
env = env1
} else {
env = env2
}
for k, v := range env0 {
env[k] = v
}
return env
}

// podmanEnvNames gets the necessary podman env variables to reset after using minikube's podman service
func podmanEnvNames(ec PodmanEnvConfig) []string {
// podman v1
vars1 := []string{
constants.PodmanVarlinkBridgeEnv,
}
// podman v2
vars2 := []string{
constants.PodmanContainerHostEnv,
constants.PodmanContainerSSHKeyEnv,
}
// common
vars0 := []string{
constants.MinikubeActivePodmanEnv,
}

var vars []string
if ec.client != nil || ec.hostname != "" {
// getting ec.varlink needs a running machine
if ec.varlink {
vars = vars1
} else {
vars = vars2
}
} else {
// just unset *all* of the variables instead
vars = vars1
vars = append(vars, vars2...)
}
vars = append(vars, vars0...)
return vars
}

func init() {
podmanEnvCmd.Flags().StringVar(&shell.ForceShell, "shell", "", "Force environment to be configured for a specified shell: [fish, cmd, powershell, tcsh, bash, zsh], default is auto-detect")
podmanEnvCmd.Flags().BoolVarP(&podmanUnset, "unset", "u", false, "Unset variables instead of setting them")
Expand Down
15 changes: 14 additions & 1 deletion cmd/minikube/cmd/podman-env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestGeneratePodmanScripts(t *testing.T) {
}{
{
"bash",
PodmanEnvConfig{profile: "bash", driver: "kvm2", client: newFakeClient()},
PodmanEnvConfig{profile: "bash", driver: "kvm2", varlink: true, client: newFakeClient()},
nil,
`export PODMAN_VARLINK_BRIDGE="/usr/bin/ssh root@host -- sudo varlink -A \'podman varlink \\\$VARLINK_ADDRESS\' bridge"
export MINIKUBE_ACTIVE_PODMAN="bash"
Expand All @@ -50,6 +50,19 @@ export MINIKUBE_ACTIVE_PODMAN="bash"
# eval $(minikube -p bash podman-env)
`,
`unset PODMAN_VARLINK_BRIDGE MINIKUBE_ACTIVE_PODMAN
`,
},
{
"bash",
PodmanEnvConfig{profile: "bash", driver: "kvm2", client: newFakeClient(), username: "root", hostname: "host", port: 22},
nil,
`export CONTAINER_HOST="ssh://root@host:22/run/podman/podman.sock"
export MINIKUBE_ACTIVE_PODMAN="bash"
# To point your shell to minikube's podman service, run:
# eval $(minikube -p bash podman-env)
`,
`unset CONTAINER_HOST CONTAINER_SSHKEY MINIKUBE_ACTIVE_PODMAN
`,
},
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/minikube/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const (
MinikubeActiveDockerdEnv = "MINIKUBE_ACTIVE_DOCKERD"
// PodmanVarlinkBridgeEnv is used for podman settings
PodmanVarlinkBridgeEnv = "PODMAN_VARLINK_BRIDGE"
// PodmanContainerHostEnv is used for podman settings
PodmanContainerHostEnv = "CONTAINER_HOST"
// PodmanContainerSSHKeyEnv is used for podman settings
PodmanContainerSSHKeyEnv = "CONTAINER_SSHKEY"
// MinikubeActivePodmanEnv holds the podman service that the user's shell is pointing at
// value would be profile or empty if pointing to the user's host.
MinikubeActivePodmanEnv = "MINIKUBE_ACTIVE_PODMAN"
Expand Down

0 comments on commit 7747655

Please sign in to comment.