diff --git a/client/process.go b/client/process.go index 958fdb5d..678c4cdc 100644 --- a/client/process.go +++ b/client/process.go @@ -136,7 +136,8 @@ func (config *Config) DebugGCS() { cmd += debugCommand("ls -l /tmp/gcs/*") cmd += debugCommand("cat /tmp/gcs/*/config.json") cmd += debugCommand("ls -lR /var/run/gcsrunc") - cmd += debugCommand("cat /var/run/gcsrunc/log.log") + cmd += debugCommand("cat /tmp/gcs/global-runc.log") + cmd += debugCommand("cat /tmp/gcs/*/runc.log") cmd += debugCommand("ps -ef") cmd += `"` } diff --git a/service/gcs/core/gcs/gcs.go b/service/gcs/core/gcs/gcs.go index 5518922a..e3088a12 100644 --- a/service/gcs/core/gcs/gcs.go +++ b/service/gcs/core/gcs/gcs.go @@ -46,16 +46,20 @@ type gcsCore struct { // processCache stores information about processes which persists between calls // into the gcsCore. It is structured as a map from pid to cache entry. processCache map[int]*processCacheEntry + + // baseStoragePath is the path where all container storage should be nested. + baseStoragePath string } // NewGCSCore creates a new gcsCore struct initialized with the given Runtime. -func NewGCSCore(rtime runtime.Runtime, os oslayer.OS, vsock transport.Transport) core.Core { +func NewGCSCore(basePath string, rtime runtime.Runtime, os oslayer.OS, vsock transport.Transport) core.Core { return &gcsCore{ - Rtime: rtime, - OS: os, - vsock: vsock, - containerCache: make(map[string]*containerCacheEntry), - processCache: make(map[int]*processCacheEntry), + baseStoragePath: basePath, + Rtime: rtime, + OS: os, + vsock: vsock, + containerCache: make(map[string]*containerCacheEntry), + processCache: make(map[int]*processCacheEntry), } } diff --git a/service/gcs/core/gcs/gcs_test.go b/service/gcs/core/gcs/gcs_test.go index b13118ee..b8efac40 100644 --- a/service/gcs/core/gcs/gcs_test.go +++ b/service/gcs/core/gcs/gcs_test.go @@ -584,9 +584,9 @@ var _ = Describe("GCS", func() { err error ) BeforeEach(func() { - rtime := mockruntime.NewRuntime() + rtime := mockruntime.NewRuntime("/tmp/gcs") os := mockos.NewOS() - cint := NewGCSCore(rtime, os, &transport.MockTransport{}) + cint := NewGCSCore("/tmp/gcs", rtime, os, &transport.MockTransport{}) coreint = cint.(*gcsCore) containerID = "01234567-89ab-cdef-0123-456789abcdef" processID = 101 diff --git a/service/gcs/core/gcs/storage.go b/service/gcs/core/gcs/storage.go index 77743061..25dcb40c 100644 --- a/service/gcs/core/gcs/storage.go +++ b/service/gcs/core/gcs/storage.go @@ -466,14 +466,10 @@ func (c *gcsCore) writeConfigFile(id string, config oci.Spec) error { return nil } -func (c *gcsCore) getStorageRootPath() string { - return "/tmp/gcs" -} - // getContainerStoragePath returns the path where the GCS stores files on disk // for the container with the given ID. func (c *gcsCore) getContainerStoragePath(id string) string { - return filepath.Join(c.getStorageRootPath(), id) + return filepath.Join(c.baseStoragePath, id) } // getUnioningPaths returns paths that will be used in the union filesystem for diff --git a/service/gcs/core/gcs/storage_test.go b/service/gcs/core/gcs/storage_test.go index e0dadd37..53bbb1b2 100644 --- a/service/gcs/core/gcs/storage_test.go +++ b/service/gcs/core/gcs/storage_test.go @@ -23,10 +23,10 @@ var _ = Describe("Storage", func() { ) BeforeEach(func() { - rtime, err := runc.NewRuntime() + rtime, err := runc.NewRuntime("/tmp/gcs") Expect(err).NotTo(HaveOccurred()) os := realos.NewOS() - cint := NewGCSCore(rtime, os, &transport.MockTransport{}) + cint := NewGCSCore("/tmp/gcs", rtime, os, &transport.MockTransport{}) coreint = cint.(*gcsCore) }) diff --git a/service/gcs/main.go b/service/gcs/main.go index f59614bc..10d4985c 100644 --- a/service/gcs/main.go +++ b/service/gcs/main.go @@ -48,14 +48,16 @@ func main() { logrus.SetLevel(level) + baseLogPath := "/tmp/gcs" + logrus.Info("GCS started") tport := &transport.VsockTransport{} - rtime, err := runc.NewRuntime() + rtime, err := runc.NewRuntime(baseLogPath) if err != nil { logrus.Fatalf("%+v", err) } os := realos.NewOS() - coreint := gcs.NewGCSCore(rtime, os, tport) + coreint := gcs.NewGCSCore(baseLogPath, rtime, os, tport) mux := bridge.NewBridgeMux() b := bridge.Bridge{ Transport: tport, diff --git a/service/gcs/runtime/mockruntime/mockruntime.go b/service/gcs/runtime/mockruntime/mockruntime.go index 0eaffa72..5d19bac6 100644 --- a/service/gcs/runtime/mockruntime/mockruntime.go +++ b/service/gcs/runtime/mockruntime/mockruntime.go @@ -20,7 +20,7 @@ type mockRuntime struct { var _ runtime.Runtime = &mockRuntime{} // NewRuntime constructs a new mockRuntime with the default settings. -func NewRuntime() runtime.Runtime { +func NewRuntime(_ string) runtime.Runtime { var lock sync.Mutex return &mockRuntime{killed: sync.NewCond(&lock)} } diff --git a/service/gcs/runtime/runc/runc.go b/service/gcs/runtime/runc/runc.go index bdd0bf98..9527e56b 100644 --- a/service/gcs/runtime/runc/runc.go +++ b/service/gcs/runtime/runc/runc.go @@ -30,6 +30,7 @@ const ( // runcRuntime is an implementation of the Runtime interface which uses runC as // the container runtime. type runcRuntime struct { + runcLogBasePath string } var _ runtime.Runtime = &runcRuntime{} @@ -68,8 +69,9 @@ func (p *process) Tty() *stdio.TtyRelay { } // NewRuntime instantiates a new runcRuntime struct. -func NewRuntime() (runtime.Runtime, error) { - rtime := &runcRuntime{} +func NewRuntime(logBasePath string) (runtime.Runtime, error) { + + rtime := &runcRuntime{runcLogBasePath: logBasePath} if err := rtime.initialize(); err != nil { return nil, err } @@ -78,15 +80,19 @@ func NewRuntime() (runtime.Runtime, error) { // initialize sets up any state necessary for the runcRuntime to function. func (r *runcRuntime) initialize() error { - exists, err := r.pathExists(containerFilesDir) - if err != nil { - return err - } - if !exists { - if err := os.MkdirAll(containerFilesDir, 0700); err != nil { - return errors.Wrapf(err, "failed making runC container files directory %s", containerFilesDir) + paths := [2]string{containerFilesDir, r.runcLogBasePath} + for _, p := range paths { + exists, err := r.pathExists(p) + if err != nil { + return err + } + if !exists { + if err := os.MkdirAll(p, 0700); err != nil { + return errors.Wrapf(err, "failed making runC container files directory %s", p) + } } } + return nil } @@ -105,7 +111,7 @@ func (r *runcRuntime) CreateContainer(id string, bundlePath string, stdioSet *st // Start unblocks the container's init process created by the call to // CreateContainer. func (c *container) Start() error { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "start", c.id) out, err := cmd.CombinedOutput() if err != nil { @@ -127,7 +133,7 @@ func (c *container) ExecProcess(process oci.Process, stdioSet *stdio.ConnectionS // Kill sends the specified signal to the container's init process. func (c *container) Kill(signal oslayer.Signal) error { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "kill", c.id, strconv.Itoa(int(signal))) out, err := cmd.CombinedOutput() if err != nil { @@ -139,7 +145,7 @@ func (c *container) Kill(signal oslayer.Signal) error { // Delete deletes any state created for the container by either this wrapper or // runC itself. func (c *container) Delete() error { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "delete", c.id) out, err := cmd.CombinedOutput() if err != nil { @@ -162,7 +168,7 @@ func (p *process) Delete() error { // Pause suspends all processes running in the container. func (c *container) Pause() error { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "pause", c.id) out, err := cmd.CombinedOutput() if err != nil { @@ -173,7 +179,7 @@ func (c *container) Pause() error { // Resume unsuspends processes running in the container. func (c *container) Resume() error { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "resume", c.id) out, err := cmd.CombinedOutput() if err != nil { @@ -184,7 +190,7 @@ func (c *container) Resume() error { // GetState returns information about the given container. func (c *container) GetState() (*runtime.ContainerState, error) { - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) cmd := exec.Command("runc", "--log", logPath, "state", c.id) out, err := cmd.CombinedOutput() if err != nil { @@ -219,7 +225,7 @@ func (c *container) Exists() (bool, error) { // ListContainerStates returns ContainerState structs for all existing // containers, whether they're running or not. func (r *runcRuntime) ListContainerStates() ([]runtime.ContainerState, error) { - logPath := r.getLogPath() + logPath := filepath.Join(r.runcLogBasePath, "global-runc.log") cmd := exec.Command("runc", "--log", logPath, "list", "-f", "json") out, err := cmd.CombinedOutput() if err != nil { @@ -327,7 +333,7 @@ func (c *container) GetAllProcesses() ([]runtime.ContainerProcessState, error) { // getRunningPids gets the pids of all processes which runC recognizes as // running. func (r *runcRuntime) getRunningPids(id string) ([]int, error) { - logPath := r.getLogPath() + logPath := r.getLogPath(id) cmd := exec.Command("runc", "--log", logPath, "ps", "-f", "json", id) out, err := cmd.CombinedOutput() if err != nil { @@ -496,7 +502,7 @@ func (c *container) startProcess(tempProcessDir string, hasTerminal bool, stdioS return nil, errors.Wrapf(err, "failed to set process as subreaper for process in container %s", c.id) } - logPath := c.r.getLogPath() + logPath := c.r.getLogPath(c.id) args = append([]string{"--log", logPath}, args...) args = append(args, "--pid-file", filepath.Join(tempProcessDir, "pid")) diff --git a/service/gcs/runtime/runc/runc_test.go b/service/gcs/runtime/runc/runc_test.go index 82338bed..4373ff10 100644 --- a/service/gcs/runtime/runc/runc_test.go +++ b/service/gcs/runtime/runc/runc_test.go @@ -210,7 +210,7 @@ var _ = Describe("runC", func() { BeforeEach(func() { var err error - rtime, err = NewRuntime() + rtime, err = NewRuntime("/tmp/gcs") Expect(err).NotTo(HaveOccurred()) cwd, err = os.Getwd() diff --git a/service/gcs/runtime/runc/utils.go b/service/gcs/runtime/runc/utils.go index 3178faef..35d62eec 100644 --- a/service/gcs/runtime/runc/utils.go +++ b/service/gcs/runtime/runc/utils.go @@ -62,8 +62,8 @@ func (r *runcRuntime) makeContainerDir(id string) error { } // getLogPath returns the path to the log file used by the runC wrapper. -func (r *runcRuntime) getLogPath() string { - return filepath.Join(containerFilesDir, "log.log") +func (r *runcRuntime) getLogPath(id string) string { + return filepath.Join(r.runcLogBasePath, id, "runc.log") } // processExists returns true if the given process exists in /proc, false if diff --git a/service/gcs/runtime/runc/utils_test.go b/service/gcs/runtime/runc/utils_test.go index 7612e7fd..24e6f11e 100644 --- a/service/gcs/runtime/runc/utils_test.go +++ b/service/gcs/runtime/runc/utils_test.go @@ -17,7 +17,7 @@ var _ = Describe("Utils", func() { ) BeforeEach(func() { - rt, err := NewRuntime() + rt, err := NewRuntime("/tmp/gcs") rtime = rt.(*runcRuntime) Expect(err).NotTo(HaveOccurred()) }) @@ -147,11 +147,12 @@ var _ = Describe("Utils", func() { expectedPath string actualPath string ) + id := "atestid" BeforeEach(func() { - expectedPath = "/var/run/gcsrunc/log.log" + expectedPath = "/tmp/gcs/" + id + "/runc.log" }) JustBeforeEach(func() { - actualPath = rtime.getLogPath() + actualPath = rtime.getLogPath(id) }) It("should return the correct log path", func() { Expect(actualPath).To(Equal(expectedPath))