forked from kata-containers/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ability to check whether kata is running rootlessly or not. Add the setup of the rootless directory located in the dir /run/user/<UID> directory. Fixes: kata-containers#1874 Signed-off-by: Gabi Beyer <[email protected]>
- Loading branch information
Gabi Beyer
committed
Jul 16, 2019
1 parent
bc15e44
commit 0f16cef
Showing
3 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright (c) 2019 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package rootless | ||
|
||
import ( | ||
"bufio" | ||
"context" | ||
"io" | ||
"os" | ||
"strings" | ||
|
||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
var ( | ||
isRootless bool | ||
rootlessDir = os.Getenv("XDG_RUNTIME_DIR") | ||
uidMapPath = "/proc/self/uid_map" | ||
|
||
rootlessLog = logrus.WithFields(logrus.Fields{ | ||
"source": "rootless", | ||
}) | ||
) | ||
|
||
// SetLogger sets up a logger for the rootless pkg | ||
func SetLogger(ctx context.Context, logger *logrus.Entry) { | ||
fields := rootlessLog.Data | ||
rootlessLog = logger.WithFields(fields) | ||
} | ||
|
||
// SetRootless reads a uid_map file, compares the UID of the | ||
// user inside the container vs on the host. If the host UID | ||
// is not root, but the container ID is, it can be determined | ||
// the user is running rootlessly. | ||
func SetRootless() error { | ||
file, err := os.Open(uidMapPath) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
|
||
buf := bufio.NewReader(file) | ||
for { | ||
line, _, err := buf.ReadLine() | ||
if err != nil { | ||
if err == io.EOF { | ||
return nil | ||
} | ||
return err | ||
} | ||
if line == nil { | ||
return nil | ||
} | ||
|
||
// if the container id (id[0]) is 0 (root inside the container) | ||
// has a mapping to the host id (id[1]) that is not root, then | ||
// it can be determined that the host user is running rootless | ||
ids := strings.Fields(string(line)) | ||
if ids[0] == "0" && ids[1] != "0" { | ||
rootlessLog.Infof("Running as rootless") | ||
isRootless = true | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
// IsRootless states whether kata is being ran with root or not | ||
func IsRootless() bool { | ||
return isRootless | ||
} | ||
|
||
// GetRootlessDir returns the path to the location for rootless | ||
// container and sandbox storage | ||
func GetRootlessDir() string { | ||
return rootlessDir | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright (c) 2019 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package rootless | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func createTestUIDMapFile(input string) error { | ||
f, err := os.Create(uidMapPath) | ||
if err != nil { | ||
return err | ||
} | ||
defer f.Close() | ||
|
||
_, err = f.WriteString(input) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// TestSetRootlessRootlessUID1000 tests that isRootless is set to | ||
// true when a host UID is not 0 | ||
func TestSetRootlessRootlessUID1000(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// by default isRootless should be set to false initially | ||
assert.False(IsRootless()) | ||
|
||
tmpDir, err := ioutil.TempDir("", "") | ||
if err != nil { | ||
fmt.Printf("could not create tmpDir: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
uidMapPathStore := uidMapPath | ||
uidMapPath = filepath.Join(tmpDir, "testUIDMapFile") | ||
defer func() { | ||
uidMapPath = uidMapPathStore | ||
os.RemoveAll(tmpDir) | ||
isRootless = false | ||
}() | ||
|
||
mapping := "\t0\t1000\t5555" | ||
err = createTestUIDMapFile(mapping) | ||
if err != nil { | ||
fmt.Printf("Could not create test file: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
err = SetRootless() | ||
assert.NoError(err) | ||
|
||
assert.True(IsRootless()) | ||
} | ||
|
||
// TestSetRootlessRootUID0 tests that isRootless is not set when | ||
// the host UID is 0 | ||
func TestSetRootlessRootUID0(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// by default isRootless should be set to false initially | ||
assert.False(IsRootless()) | ||
|
||
tmpDir, err := ioutil.TempDir("", "") | ||
if err != nil { | ||
fmt.Printf("could not create tmpDir: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
uidMapPathStore := uidMapPath | ||
uidMapPath = filepath.Join(tmpDir, "testUIDMapFile") | ||
defer func() { | ||
uidMapPath = uidMapPathStore | ||
os.RemoveAll(uidMapPath) | ||
isRootless = false | ||
}() | ||
|
||
mapping := "\t0\t0\t5555" | ||
err = createTestUIDMapFile(mapping) | ||
if err != nil { | ||
fmt.Printf("Could not create test file: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
err = SetRootless() | ||
assert.NoError(err) | ||
|
||
assert.False(IsRootless()) | ||
} |