Replace pid and started file with State type
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)
This commit is contained in:
parent
e49f5f4788
commit
81e5a3f7a7
|
@ -56,12 +56,18 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
|
|||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if err := WritePid(dataPath, command.Process.Pid, started); err != nil {
|
||||
|
||||
state := &libcontainer.State{
|
||||
Pid1: command.Process.Pid,
|
||||
Pid1StartTime: started,
|
||||
}
|
||||
|
||||
if err := libcontainer.WriteState(dataPath, state); err != nil {
|
||||
command.Process.Kill()
|
||||
command.Wait()
|
||||
return -1, err
|
||||
}
|
||||
defer DeletePid(dataPath)
|
||||
defer libcontainer.DeleteState(dataPath)
|
||||
|
||||
// Do this before syncing with child so that no children
|
||||
// can escape the cgroup
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
// ExecIn uses an existing pid and joins the pid's namespaces with the new command.
|
||||
func ExecIn(container *libcontainer.Config, nspid int, args []string) error {
|
||||
func ExecIn(container *libcontainer.Config, state *libcontainer.State, args []string) error {
|
||||
// TODO(vmarmol): If this gets too long, send it over a pipe to the child.
|
||||
// Marshall the container into JSON since it won't be available in the namespace.
|
||||
containerJson, err := json.Marshal(container)
|
||||
|
@ -22,7 +22,7 @@ func ExecIn(container *libcontainer.Config, nspid int, args []string) error {
|
|||
}
|
||||
|
||||
// Enter the namespace and then finish setup
|
||||
finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(nspid), "--containerjson", string(containerJson), "--"}
|
||||
finalArgs := []string{os.Args[0], "nsenter", "--nspid", strconv.Itoa(state.Pid1), "--containerjson", string(containerJson), "--"}
|
||||
finalArgs = append(finalArgs, args...)
|
||||
if err := system.Execv(finalArgs[0], finalArgs[0:], os.Environ()); err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package namespaces
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// WritePid writes the namespaced processes pid to pid and it's start time
|
||||
// to the path specified
|
||||
func WritePid(path string, pid int, startTime string) error {
|
||||
err := ioutil.WriteFile(filepath.Join(path, "pid"), []byte(fmt.Sprint(pid)), 0655)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(filepath.Join(path, "start"), []byte(startTime), 0655)
|
||||
}
|
||||
|
||||
// DeletePid removes the pid and started file from disk when the container's process
|
||||
// dies and the container is cleanly removed
|
||||
func DeletePid(path string) error {
|
||||
err := os.Remove(filepath.Join(path, "pid"))
|
||||
if serr := os.Remove(filepath.Join(path, "start")); err == nil {
|
||||
err = serr
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -19,19 +19,20 @@ var execCommand = cli.Command{
|
|||
}
|
||||
|
||||
func execAction(context *cli.Context) {
|
||||
var nspid, exitCode int
|
||||
var exitCode int
|
||||
|
||||
container, err := loadContainer()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if nspid, err = readPid(); err != nil && !os.IsNotExist(err) {
|
||||
log.Fatalf("unable to read pid: %s", err)
|
||||
state, err := libcontainer.LoadState(dataPath)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
log.Fatalf("unable to read state.json: %s", err)
|
||||
}
|
||||
|
||||
if nspid > 0 {
|
||||
err = namespaces.ExecIn(container, nspid, []string(context.Args()))
|
||||
if state != nil {
|
||||
err = namespaces.ExecIn(container, state, []string(context.Args()))
|
||||
} else {
|
||||
term := namespaces.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty)
|
||||
exitCode, err = startContainer(container, term, dataPath, []string(context.Args()))
|
||||
|
|
|
@ -2,11 +2,9 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/libcontainer"
|
||||
)
|
||||
|
@ -26,20 +24,6 @@ func loadContainer() (*libcontainer.Config, error) {
|
|||
return container, nil
|
||||
}
|
||||
|
||||
func readPid() (int, error) {
|
||||
data, err := ioutil.ReadFile(filepath.Join(dataPath, "pid"))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(string(data))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
func openLog(name string) error {
|
||||
f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0755)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package libcontainer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// State represents a running container's state
|
||||
type State struct {
|
||||
// Pid1 is the process id for the container's pid 1 in it's parent namespace
|
||||
Pid1 int `json:"pid1,omitempty"`
|
||||
// Pid1StartTime is the process start time for the container's pid 1
|
||||
Pid1StartTime string `json:"pid1_start_time,omitempty"`
|
||||
}
|
||||
|
||||
// WriteState writes the container's runtime state to a state.json file
|
||||
// in the specified path
|
||||
func WriteState(basePath string, state *State) error {
|
||||
f, err := os.Create(filepath.Join(basePath, "state.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return json.NewEncoder(f).Encode(state)
|
||||
}
|
||||
|
||||
// LoadState reads the state.json file for a running container
|
||||
func LoadState(basePath string) (*State, error) {
|
||||
f, err := os.Open(filepath.Join(basePath, "state.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var state *State
|
||||
if err := json.NewDecoder(f).Decode(&state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// DeleteState deletes the state.json file
|
||||
func DeleteState(basePath string) error {
|
||||
return os.Remove(filepath.Join(basePath, "state.json"))
|
||||
}
|
Loading…
Reference in New Issue