2022-11-16 16:38:39 +00:00
|
|
|
package platform
|
|
|
|
|
2022-12-11 06:58:22 +00:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/docker/docker/client"
|
|
|
|
"github.com/pkg/errors"
|
2023-02-08 04:00:22 +00:00
|
|
|
"github.com/portainer/portainer/api/docker"
|
2022-12-21 16:08:18 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2022-12-11 06:58:22 +00:00
|
|
|
)
|
2022-11-16 16:38:39 +00:00
|
|
|
|
|
|
|
const (
|
|
|
|
PodmanMode = "PODMAN"
|
|
|
|
KubernetesServiceHost = "KUBERNETES_SERVICE_HOST"
|
|
|
|
NomadJobName = "NOMAD_JOB_NAME"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ContainerPlatform represent the platform on which the container is running (Docker, Kubernetes, Nomad)
|
|
|
|
type ContainerPlatform string
|
|
|
|
|
|
|
|
const (
|
2022-12-11 06:58:22 +00:00
|
|
|
// PlatformDockerStandalone represent the Docker platform (Standalone)
|
|
|
|
PlatformDockerStandalone = ContainerPlatform("Docker Standalone")
|
|
|
|
// PlatformDockerSwarm represent the Docker platform (Swarm)
|
|
|
|
PlatformDockerSwarm = ContainerPlatform("Docker Swarm")
|
2022-11-16 16:38:39 +00:00
|
|
|
// PlatformKubernetes represent the Kubernetes platform
|
|
|
|
PlatformKubernetes = ContainerPlatform("Kubernetes")
|
|
|
|
// PlatformPodman represent the Podman platform (Standalone)
|
|
|
|
PlatformPodman = ContainerPlatform("Podman")
|
|
|
|
// PlatformNomad represent the Nomad platform (Standalone)
|
|
|
|
PlatformNomad = ContainerPlatform("Nomad")
|
|
|
|
)
|
|
|
|
|
|
|
|
// DetermineContainerPlatform will check for the existence of the PODMAN_MODE
|
|
|
|
// or KUBERNETES_SERVICE_HOST environment variable to determine if
|
|
|
|
// the container is running on Podman or inside the Kubernetes platform.
|
|
|
|
// Defaults to Docker otherwise.
|
2022-12-11 06:58:22 +00:00
|
|
|
func DetermineContainerPlatform() (ContainerPlatform, error) {
|
2022-11-16 16:38:39 +00:00
|
|
|
podmanModeEnvVar := os.Getenv(PodmanMode)
|
|
|
|
if podmanModeEnvVar == "1" {
|
2022-12-11 06:58:22 +00:00
|
|
|
return PlatformPodman, nil
|
2022-11-16 16:38:39 +00:00
|
|
|
}
|
2023-03-08 02:34:55 +00:00
|
|
|
|
2022-11-16 16:38:39 +00:00
|
|
|
serviceHostKubernetesEnvVar := os.Getenv(KubernetesServiceHost)
|
|
|
|
if serviceHostKubernetesEnvVar != "" {
|
2022-12-11 06:58:22 +00:00
|
|
|
return PlatformKubernetes, nil
|
2022-11-16 16:38:39 +00:00
|
|
|
}
|
2023-03-08 02:34:55 +00:00
|
|
|
|
2022-11-16 16:38:39 +00:00
|
|
|
nomadJobName := os.Getenv(NomadJobName)
|
|
|
|
if nomadJobName != "" {
|
2022-12-11 06:58:22 +00:00
|
|
|
return PlatformNomad, nil
|
|
|
|
}
|
|
|
|
|
2022-12-21 16:08:18 +00:00
|
|
|
if !isRunningInContainer() {
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
2023-02-08 04:00:22 +00:00
|
|
|
dockerCli, err := docker.CreateSimpleClient()
|
2022-12-11 06:58:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", errors.WithMessage(err, "failed to create docker client")
|
|
|
|
}
|
|
|
|
defer dockerCli.Close()
|
|
|
|
|
|
|
|
info, err := dockerCli.Info(context.Background())
|
|
|
|
if err != nil {
|
2022-12-21 16:08:18 +00:00
|
|
|
if client.IsErrConnectionFailed(err) {
|
|
|
|
log.Warn().
|
|
|
|
Err(err).
|
|
|
|
Msg("failed to retrieve docker info")
|
|
|
|
return "", nil
|
|
|
|
}
|
|
|
|
|
2022-12-11 06:58:22 +00:00
|
|
|
return "", errors.WithMessage(err, "failed to retrieve docker info")
|
|
|
|
}
|
|
|
|
|
|
|
|
if info.Swarm.NodeID == "" {
|
|
|
|
return PlatformDockerStandalone, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return PlatformDockerSwarm, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// isRunningInContainer returns true if the process is running inside a container
|
|
|
|
// this code is taken from https://github.com/moby/libnetwork/blob/master/drivers/bridge/setup_bridgenetfiltering.go
|
|
|
|
func isRunningInContainer() bool {
|
|
|
|
_, err := os.Stat("/.dockerenv")
|
|
|
|
return !os.IsNotExist(err)
|
2022-11-16 16:38:39 +00:00
|
|
|
}
|