Created a global runtime checkpoint for libcontainer. Got rid of the network specific runtime checkpoint.
Docker-DCO-1.1-Signed-off-by: Vishnu Kannan <vishnuk@google.com> (github: vishh)
This commit is contained in:
parent
9253412ee1
commit
481552c02b
|
@ -1,21 +1,19 @@
|
|||
package api
|
||||
package libcontainer
|
||||
|
||||
import (
|
||||
"github.com/docker/libcontainer"
|
||||
"github.com/docker/libcontainer/cgroups/fs"
|
||||
|
||||
"github.com/docker/libcontainer/network"
|
||||
)
|
||||
|
||||
// Returns all available stats for the given container.
|
||||
func GetContainerStats(container *libcontainer.Container, networkInfo *network.NetworkRuntimeInfo) (*ContainerStats, error) {
|
||||
func GetContainerStats(container *Config, runtimeCkpt *RuntimeCkpt) (*ContainerStats, error) {
|
||||
containerStats := NewContainerStats()
|
||||
stats, err := fs.GetStats(container.Cgroups)
|
||||
if err != nil {
|
||||
return containerStats, err
|
||||
}
|
||||
containerStats.CgroupStats = stats
|
||||
networkStats, err := network.GetStats(networkInfo)
|
||||
networkStats, err := network.GetStats(&runtimeCkpt.NetworkCkpt)
|
||||
if err != nil {
|
||||
return containerStats, err
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package libcontainer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/libcontainer/network"
|
||||
)
|
||||
|
||||
// A checkpoint struct that will contain all runtime checkpointed information.
|
||||
type RuntimeCkpt struct {
|
||||
NetworkCkpt network.NetworkCkpt `json:"network_ckpt,omitempty"`
|
||||
}
|
||||
|
||||
// The name of the network checkpoint file
|
||||
const runtimeCkptFile = "runtimeCkpt.json"
|
||||
|
||||
var ErrRuntimeCkptNotFound = errors.New("Runtime Checkpoint not found")
|
||||
|
||||
// Returns the path to the network checkpoint given the path to the base directory of network checkpoint.
|
||||
func getRuntimeCkptPath(basePath string) string {
|
||||
return filepath.Join(basePath, runtimeCkptFile)
|
||||
}
|
||||
|
||||
// Updates the Runtime Checkpoint with current checkpoint information from all the subsystems.
|
||||
func UpdateRuntimeCkpt(basePath string) error {
|
||||
runtimeCkpt := &RuntimeCkpt{
|
||||
NetworkCkpt: *network.NetworkCkptImpl.GetNetworkCkpt(),
|
||||
}
|
||||
data, err := json.Marshal(runtimeCkpt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to checkpoint runtime information - %s", err)
|
||||
}
|
||||
return ioutil.WriteFile(getRuntimeCkptPath(basePath), data, 0655)
|
||||
}
|
||||
|
||||
// Loads and returns the rutime checkpointing existing inside basePath. Returns ErrRuntimeCkptNotFound
|
||||
// if the runtime checkpoint does not exist.
|
||||
func GetRuntimeCkpt(basePath string) (*RuntimeCkpt, error) {
|
||||
runtimeCkpt := &RuntimeCkpt{}
|
||||
checkpointPath := getRuntimeCkptPath(basePath)
|
||||
f, err := os.Open(checkpointPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return runtimeCkpt, ErrRuntimeCkptNotFound
|
||||
}
|
||||
return runtimeCkpt, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := json.NewDecoder(f).Decode(runtimeCkpt); err != nil {
|
||||
return runtimeCkpt, err
|
||||
}
|
||||
|
||||
return runtimeCkpt, nil
|
||||
}
|
||||
|
||||
// Deletes the runtime checkpoint under basePath
|
||||
func DeleteNetworkRuntimeInfo(basePath string) error {
|
||||
return os.Remove(getRuntimeCkptPath(basePath))
|
||||
}
|
|
@ -87,6 +87,13 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
|
|||
return -1, err
|
||||
}
|
||||
|
||||
// Update the runtime checkpoint.
|
||||
if err = libcontainer.UpdateRuntimeCkpt(dataPath); err != nil {
|
||||
command.Process.Kill()
|
||||
command.Wait()
|
||||
return -1, err
|
||||
}
|
||||
|
||||
// Sync with child
|
||||
syncPipe.Close()
|
||||
|
||||
|
|
|
@ -1,63 +1,25 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Struct describing the network specific checkpoint that will be maintained by libcontainer for all running containers
|
||||
// This is an internal checkpoint, so do not depend on it outside of libcontainer.
|
||||
type NetworkRuntimeInfo struct {
|
||||
type NetworkCkpt struct {
|
||||
// The name of the veth interface on the Host.
|
||||
VethHost string `json:"veth_host,omitempty"`
|
||||
// The name of the veth interface created inside the container for the child.
|
||||
VethChild string `json:"veth_child,omitempty"`
|
||||
}
|
||||
|
||||
// The name of the network checkpoint file
|
||||
const networkInfoFile = "network.json"
|
||||
type NetworkCkptIntImpl struct{}
|
||||
|
||||
var ErrNetworkRuntimeInfoNotFound = errors.New("Network Checkpoint not found")
|
||||
var (
|
||||
networkCkptInfo = &NetworkCkpt{}
|
||||
NetworkCkptImpl = &NetworkCkptIntImpl{}
|
||||
)
|
||||
|
||||
// Returns the path to the network checkpoint given the path to the base directory of network checkpoint.
|
||||
func getNetworkRuntimeInfoPath(basePath string) string {
|
||||
return filepath.Join(basePath, networkInfoFile)
|
||||
func (NetworkCkptIntImpl) GetNetworkCkpt() *NetworkCkpt {
|
||||
return networkCkptInfo
|
||||
}
|
||||
|
||||
// Marshalls the input network runtime info struct into a json object and stores it inside basepath.
|
||||
func writeNetworkRuntimeInfo(networkInfo *NetworkRuntimeInfo, basePath string) error {
|
||||
data, err := json.Marshal(networkInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to checkpoint network runtime information - %s", err)
|
||||
}
|
||||
return ioutil.WriteFile(getNetworkRuntimeInfoPath(basePath), data, 0655)
|
||||
}
|
||||
|
||||
// Loads the network runtime info from the checkpoint and returns the unmarshaled content.
|
||||
func LoadNetworkRuntimeInfo(basePath string) (NetworkRuntimeInfo, error) {
|
||||
var networkRuntimeInfo NetworkRuntimeInfo
|
||||
checkpointPath := getNetworkRuntimeInfoPath(basePath)
|
||||
f, err := os.Open(checkpointPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return networkRuntimeInfo, ErrNetworkRuntimeInfoNotFound
|
||||
}
|
||||
return networkRuntimeInfo, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := json.NewDecoder(f).Decode(&networkRuntimeInfo); err != nil {
|
||||
return networkRuntimeInfo, err
|
||||
}
|
||||
|
||||
return networkRuntimeInfo, nil
|
||||
}
|
||||
|
||||
// Deletes the network checkpoint under basePath
|
||||
func deleteNetworkRuntimeInfo(basePath string) error {
|
||||
return os.Remove(getNetworkRuntimeInfoPath(basePath))
|
||||
func (NetworkCkptIntImpl) updateNetworkCkpt(n *NetworkCkpt) {
|
||||
networkCkptInfo = n
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@ type NetworkStats struct {
|
|||
}
|
||||
|
||||
// Returns the network statistics for the network interfaces represented by the NetworkRuntimeInfo.
|
||||
func GetStats(networkRuntimeInfo *NetworkRuntimeInfo) (NetworkStats, error) {
|
||||
func GetStats(networkCkpt *NetworkCkpt) (NetworkStats, error) {
|
||||
// This can happen if the network runtime information is missing - possible if the container was created by an old version of libcontainer.
|
||||
if networkRuntimeInfo.VethHost == "" {
|
||||
if networkCkpt.VethHost == "" {
|
||||
return NetworkStats{}, nil
|
||||
}
|
||||
data, err := readSysfsNetworkStats(networkRuntimeInfo.VethHost)
|
||||
data, err := readSysfsNetworkStats(networkCkpt.VethHost)
|
||||
if err != nil {
|
||||
return NetworkStats{}, err
|
||||
}
|
||||
|
|
|
@ -45,8 +45,11 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath
|
|||
if err := SetInterfaceInNamespacePid(name2, nspid); err != nil {
|
||||
return err
|
||||
}
|
||||
networkRuntimeInfo := NetworkRuntimeInfo{VethHost: name1, VethChild: name2}
|
||||
return writeNetworkRuntimeInfo(&networkRuntimeInfo, dataPath)
|
||||
networkCkpt := NetworkCkptImpl.GetNetworkCkpt()
|
||||
networkCkpt.VethHost = name1
|
||||
networkCkpt.VethChild = name2
|
||||
NetworkCkptImpl.updateNetworkCkpt(networkCkpt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Veth) Initialize(config *Network, context map[string]string) error {
|
||||
|
|
|
@ -7,8 +7,6 @@ import (
|
|||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/libcontainer"
|
||||
"github.com/docker/libcontainer/api"
|
||||
"github.com/docker/libcontainer/network"
|
||||
)
|
||||
|
||||
var statsCommand = cli.Command{
|
||||
|
@ -23,12 +21,12 @@ func statsAction(context *cli.Context) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
networkRuntimeInfo, err := loadNetworkRuntimeInfo()
|
||||
runtimeCkpt, err := libcontainer.GetRuntimeCkpt(dataPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
stats, err := getContainerStats(container, &networkRuntimeInfo)
|
||||
stats, err := getContainerStats(container, runtimeCkpt)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get stats - %v\n", err)
|
||||
}
|
||||
|
@ -37,8 +35,8 @@ func statsAction(context *cli.Context) {
|
|||
}
|
||||
|
||||
// returns the container stats in json format.
|
||||
func getContainerStats(container *libcontainer.Config, networkRuntimeInfo *network.NetworkRuntimeInfo) (string, error) {
|
||||
stats, err := libcontainer.GetContainerStats(container, networkRuntimeInfo)
|
||||
func getContainerStats(container *libcontainer.Config, runtimeCkpt *libcontainer.RuntimeCkpt) (string, error) {
|
||||
stats, err := libcontainer.GetContainerStats(container, runtimeCkpt)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"github.com/docker/libcontainer"
|
||||
"github.com/docker/libcontainer/network"
|
||||
)
|
||||
|
||||
func loadContainer() (*libcontainer.Config, error) {
|
||||
|
@ -25,17 +24,6 @@ func loadContainer() (*libcontainer.Config, error) {
|
|||
return container, nil
|
||||
}
|
||||
|
||||
func loadNetworkRuntimeInfo() (network.NetworkRuntimeInfo, error) {
|
||||
data, err := network.LoadNetworkRuntimeInfo(dataPath)
|
||||
if err != nil {
|
||||
if err == network.ErrNetworkRuntimeInfoNotFound {
|
||||
return network.NetworkRuntimeInfo{}, nil
|
||||
}
|
||||
return network.NetworkRuntimeInfo{}, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func openLog(name string) error {
|
||||
f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0755)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package api
|
||||
package libcontainer
|
||||
|
||||
import (
|
||||
"github.com/docker/libcontainer/cgroups"
|
Loading…
Reference in New Issue