Skip to content

Commit

Permalink
better checks for if we're in a container
Browse files Browse the repository at this point in the history
- set `ISCENV_CONTAINER` when starting containers so we can look for it
  on the inside
- look for .dockerenv and .containerenv files, from docker or podman
  • Loading branch information
b-dean committed Jan 25, 2024
1 parent dbf2af1 commit 9325e2a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
33 changes: 26 additions & 7 deletions internal/app/ensurewithincontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ import (
"os"
"strings"

"github.com/ontariosystems/iscenv/v3/iscenv"
log "github.com/sirupsen/logrus"
)

// EnsureWithinContainer returns an error if it is executed from outside a container
func EnsureWithinContainer(commandName string) error {
// if iscenv started the container, this will be set
if _, ok := os.LookupEnv(iscenv.EnvInternalContainer); ok {
return nil
}

proc1CGroupContents, err := os.ReadFile("/proc/1/cgroup")
if err != nil {
e := fmt.Errorf("Failed to determine environment")
Expand All @@ -35,13 +41,26 @@ func EnsureWithinContainer(commandName string) error {

// if we have some control groups owned by docker, then we are within a container
contents := string(proc1CGroupContents)
if !strings.Contains(contents, ":/docker/") &&
!strings.Contains(contents, ":/kubepods/") &&
!strings.Contains(contents, ":/kubepods.slice/") &&
!strings.Contains(contents, ":/system.slice/docker-") &&
!strings.Contains(contents, ":/system.slice/system.slice:docker:") {
return ErrNotInContainer
cgroup_substrs := []string{
":/docker/",
":/kubepods/",
":/kubepods.slice/",
":/system.slice/docker-",
":/system.slice/system.slice:docker:",
}
for _, substr := range cgroup_substrs {
if strings.Contains(contents, substr) {
return nil
}
}

// if one of these files exists, probably inside a container
for _, p := range []string{"/.dockerenv", "/run/.containerenv"} {
if _, err = os.Stat(p); err == nil {
return nil
}
}

return nil
// Couldn't find anything else, not in a container
return ErrNotInContainer
}
3 changes: 3 additions & 0 deletions internal/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ func start(cmd *cobra.Command, args []string) {
environment = append(environment, fmt.Sprintf("%s=%d", iscenv.EnvInternalWeb, flags.GetInt(cmd, "isc-http-port")))
environment = append(environment, fmt.Sprintf("%s=%d", iscenv.EnvInternalHC, iscenv.PortInternalHC))

// Add environment variable to let iscenv know we're in a container
environment = append(environment, fmt.Sprintf("%s=%d", iscenv.EnvInternalContainer, 1))

// Add the file which will temporarily disable the primary command
if flags.GetBool(cmd, "disable-primary-command") {
// While there is no technical reason to require a file on the file system, by creating an empty temp file we can (ab)use the
Expand Down
4 changes: 4 additions & 0 deletions iscenv/iscenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const (

InternalISCEnvBinaryDir = "/bin"
InternalISCEnvPath = InternalISCEnvBinaryDir + "/iscenv"

// EnvInternalContainer is the environment variable we set for every container we start.
// Later we can check if it has a value to know if we started with iscenv.
EnvInternalContainer = "ISCENV_CONTAINER"
)

var (
Expand Down

0 comments on commit 9325e2a

Please sign in to comment.