summaryrefslogtreecommitdiffhomepage
path: root/runsc/specutils/specutils.go
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-09-04 20:08:41 -0700
committerShentubot <shentubot@google.com>2018-09-04 20:10:01 -0700
commitad8648c6343cf2cf3e51a0f58cb053ee303f6ffb (patch)
tree3b1c7c9e8d978258eee349592fd13fbebb36eb1e /runsc/specutils/specutils.go
parent2cff07381a911ad52cf9df70d702f39217e9539e (diff)
runsc: Pass log and config files to sandbox process by FD.
This is a prereq for running the sandbox process as user "nobody", when it may not have permissions to open these files. Instead, we must open then before starting the sandbox process, and pass them by FD. The specutils.ReadSpecFromFile method was fixed to always seek to the beginning of the file before reading. This allows Files from the same FD to be read multiple times, as we do in the boot command when the apply-caps flag is set. Tested with --network=host. PiperOrigin-RevId: 211570647 Change-Id: I685be0a290aa7f70731ebdce82ebc0ebcc9d475c
Diffstat (limited to 'runsc/specutils/specutils.go')
-rw-r--r--runsc/specutils/specutils.go30
1 files changed, 26 insertions, 4 deletions
diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go
index 6c1ac56c3..3234cc088 100644
--- a/runsc/specutils/specutils.go
+++ b/runsc/specutils/specutils.go
@@ -126,14 +126,28 @@ func absPath(base, rel string) string {
// path, e.g. spec.Root.Path, mount.Source.
func ReadSpec(bundleDir string) (*specs.Spec, error) {
// The spec file must be in "config.json" inside the bundle directory.
- specFile := filepath.Join(bundleDir, "config.json")
- specBytes, err := ioutil.ReadFile(specFile)
+ specPath := filepath.Join(bundleDir, "config.json")
+ specFile, err := os.Open(specPath)
if err != nil {
- return nil, fmt.Errorf("error reading spec from file %q: %v", specFile, err)
+ return nil, fmt.Errorf("error opening spec file %q: %v", specPath, err)
+ }
+ defer specFile.Close()
+ return ReadSpecFromFile(bundleDir, specFile)
+}
+
+// ReadSpecFromFile reads an OCI runtime spec from the given File, and
+// normalizes all relative paths into absolute by prepending the bundle dir.
+func ReadSpecFromFile(bundleDir string, specFile *os.File) (*specs.Spec, error) {
+ if _, err := specFile.Seek(0, os.SEEK_SET); err != nil {
+ return nil, fmt.Errorf("error seeking to beginning of file %q: %v", specFile.Name(), err)
+ }
+ specBytes, err := ioutil.ReadAll(specFile)
+ if err != nil {
+ return nil, fmt.Errorf("error reading spec from file %q: %v", specFile.Name(), err)
}
var spec specs.Spec
if err := json.Unmarshal(specBytes, &spec); err != nil {
- return nil, fmt.Errorf("error unmarshaling spec from file %q: %v\n %s", specFile, err, string(specBytes))
+ return nil, fmt.Errorf("error unmarshaling spec from file %q: %v\n %s", specFile.Name(), err, string(specBytes))
}
if err := ValidateSpec(&spec); err != nil {
return nil, err
@@ -372,3 +386,11 @@ func WaitForReady(pid int, timeout time.Duration, ready func() (bool, error)) er
}
return backoff.Retry(op, b)
}
+
+// DebugLogFile opens a file in logDir based on the timestamp and subcommand
+// for writing.
+func DebugLogFile(logDir, subcommand string) (*os.File, error) {
+ // Format: <debug-log-dir>/runsc.log.<yyyymmdd-hhmmss.uuuuuu>.<command>
+ filename := fmt.Sprintf("runsc.log.%s.%s", time.Now().Format("20060102-150405.000000"), subcommand)
+ return os.OpenFile(filepath.Join(logDir, filename), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0664)
+}