mirror of
https://github.com/containers/podman.git
synced 2025-06-19 00:06:43 +08:00
Update DB to add new fields required for planned features
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #209 Approved by: rhatdan
This commit is contained in:
@ -61,8 +61,8 @@ const (
|
|||||||
artifactsDir = "artifacts"
|
artifactsDir = "artifacts"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CGroupParent is the prefix to a cgroup path in libpod
|
// CgroupParent is the default prefix to a cgroup path in libpod
|
||||||
var CGroupParent = "/libpod_parent"
|
var CgroupParent = "/libpod_parent"
|
||||||
|
|
||||||
// Container is a single OCI container
|
// Container is a single OCI container
|
||||||
type Container struct {
|
type Container struct {
|
||||||
@ -78,6 +78,13 @@ type Container struct {
|
|||||||
runtime *Runtime
|
runtime *Runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO fetch IP and Subnet Mask from networks once we have updated OCICNI
|
||||||
|
// TODO enable pod support
|
||||||
|
// TODO Add readonly support
|
||||||
|
// TODO add SHM size support
|
||||||
|
// TODO add shared namespace support
|
||||||
|
// TODO add cgroup parent support
|
||||||
|
|
||||||
// containerRuntimeInfo contains the current state of the container
|
// containerRuntimeInfo contains the current state of the container
|
||||||
// It is stored on disk in a tmpfs and recreated on reboot
|
// It is stored on disk in a tmpfs and recreated on reboot
|
||||||
type containerRuntimeInfo struct {
|
type containerRuntimeInfo struct {
|
||||||
@ -107,7 +114,10 @@ type containerRuntimeInfo struct {
|
|||||||
// Will only be set if config.CreateNetNS is true, or the container was
|
// Will only be set if config.CreateNetNS is true, or the container was
|
||||||
// told to join another container's network namespace
|
// told to join another container's network namespace
|
||||||
NetNS ns.NetNS
|
NetNS ns.NetNS
|
||||||
// TODO: Save information about image used in container if one is used
|
// IP address of container (if network namespace was created)
|
||||||
|
IPAddress string
|
||||||
|
// Subnet mask of container (if network namespace was created)
|
||||||
|
SubnetMask string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerConfig contains all information that was used to create the
|
// ContainerConfig contains all information that was used to create the
|
||||||
@ -117,49 +127,76 @@ type ContainerConfig struct {
|
|||||||
Spec *spec.Spec `json:"spec"`
|
Spec *spec.Spec `json:"spec"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
// Full ID of the pood the container belongs to
|
||||||
|
Pod string `json:"pod,omitempty"`
|
||||||
|
|
||||||
|
// TODO consider breaking these subsections up into smaller structs
|
||||||
|
|
||||||
|
// Storage Config
|
||||||
// Information on the image used for the root filesystem
|
// Information on the image used for the root filesystem
|
||||||
RootfsImageID string `json:"rootfsImageID,omitempty"`
|
RootfsImageID string `json:"rootfsImageID,omitempty"`
|
||||||
RootfsImageName string `json:"rootfsImageName,omitempty"`
|
RootfsImageName string `json:"rootfsImageName,omitempty"`
|
||||||
UseImageConfig bool `json:"useImageConfig"`
|
// Whether to mount volumes specified in the image
|
||||||
|
ImageVolumes bool `json:"imageVolumes"`
|
||||||
|
// Whether to make the container read only
|
||||||
|
ReadOnly bool `json:"readOnly"`
|
||||||
|
// Src path to be mounted on /dev/shm in container
|
||||||
|
ShmDir string `json:"ShmDir,omitempty"`
|
||||||
|
// Size of the container's SHM
|
||||||
|
ShmSize int64 `json:"shmSize"`
|
||||||
|
// Static directory for container content that will persist across
|
||||||
|
// reboot
|
||||||
|
StaticDir string `json:"staticDir"`
|
||||||
|
// Mounts list contains all additional mounts into the container rootfs
|
||||||
|
// These include the SHM mount
|
||||||
|
// These must be unmounted before the container's rootfs is unmounted
|
||||||
|
Mounts []string `json:"mounts,omitempty"`
|
||||||
|
|
||||||
|
// Security Config
|
||||||
// SELinux process label for container
|
// SELinux process label for container
|
||||||
ProcessLabel string `json:"ProcessLabel,omitempty"`
|
ProcessLabel string `json:"ProcessLabel,omitempty"`
|
||||||
// SELinux mount label for root filesystem
|
// SELinux mount label for root filesystem
|
||||||
MountLabel string `json:"MountLabel,omitempty"`
|
MountLabel string `json:"MountLabel,omitempty"`
|
||||||
// Src path to be mounted on /dev/shm in container
|
// User and group to use in the container
|
||||||
ShmDir string `json:"ShmDir,omitempty"`
|
// Can be specified by name or UID/GID
|
||||||
|
User string `json:"user"`
|
||||||
|
|
||||||
|
// Namespace Config
|
||||||
|
// IDs of container to share namespaces with
|
||||||
|
// NetNsCtr conflicts with the CreateNetNS bool
|
||||||
|
IPCNsCtr string `json:"ipcNsCtr"`
|
||||||
|
MountNsCtr string `json:"mountNsCtr"`
|
||||||
|
NetNsCtr string `json:"netNsCtr"`
|
||||||
|
PIDNsCtr string `json:"pidNsCtr"`
|
||||||
|
UserNsCtr string `json:"userNsCtr"`
|
||||||
|
UTSNsCtr string `json:"utsNsCtr"`
|
||||||
|
|
||||||
|
// Network Config
|
||||||
// CreateNetNS indicates that libpod should create and configure a new
|
// CreateNetNS indicates that libpod should create and configure a new
|
||||||
// network namespace for the container
|
// network namespace for the container
|
||||||
|
// This cannot be set if NetNsCtr is also set
|
||||||
CreateNetNS bool `json:"createNetNS"`
|
CreateNetNS bool `json:"createNetNS"`
|
||||||
// PortMappings are the ports forwarded to the container's network
|
// PortMappings are the ports forwarded to the container's network
|
||||||
// namespace
|
// namespace
|
||||||
// These are not used unless CreateNetNS is true
|
// These are not used unless CreateNetNS is true
|
||||||
PortMappings []ocicni.PortMapping
|
PortMappings []ocicni.PortMapping `json:"portMappings,omitempty"`
|
||||||
// Static directory for container content that will persist across
|
|
||||||
// reboot
|
// Misc Options
|
||||||
StaticDir string `json:"staticDir"`
|
|
||||||
// Whether to keep container STDIN open
|
// Whether to keep container STDIN open
|
||||||
Stdin bool `json:"stdin,omitempty"`
|
Stdin bool `json:"stdin,omitempty"`
|
||||||
// Pod the container belongs to
|
|
||||||
Pod string `json:"pod,omitempty"`
|
|
||||||
// Labels is a set of key-value pairs providing additional information
|
// Labels is a set of key-value pairs providing additional information
|
||||||
// about a container
|
// about a container
|
||||||
Labels map[string]string `json:"labels,omitempty"`
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
// Mounts list contains all additional mounts by the container runtime.
|
|
||||||
Mounts []string `json:"mounts,omitempty"`
|
|
||||||
// StopSignal is the signal that will be used to stop the container
|
// StopSignal is the signal that will be used to stop the container
|
||||||
StopSignal uint `json:"stopSignal,omitempty"`
|
StopSignal uint `json:"stopSignal,omitempty"`
|
||||||
// StopTimeout is the signal that will be used to stop the container
|
// StopTimeout is the signal that will be used to stop the container
|
||||||
StopTimeout uint `json:"stopTimeout,omitempty"`
|
StopTimeout uint `json:"stopTimeout,omitempty"`
|
||||||
// Shared namespaces with container
|
|
||||||
SharedNamespaceCtr *string `json:"shareNamespacesWith,omitempty"`
|
|
||||||
SharedNamespaceMap map[string]string `json:"sharedNamespaces"`
|
|
||||||
// Time container was created
|
// Time container was created
|
||||||
CreatedTime time.Time `json:"createdTime"`
|
CreatedTime time.Time `json:"createdTime"`
|
||||||
// User/GID to use within the container
|
// Cgroup parent of the container
|
||||||
User string `json:"user"`
|
CgroupParent string `json:"cgroupParent"`
|
||||||
|
|
||||||
// TODO save log location here and pass into OCI code
|
// TODO log options - logpath for plaintext, others for log drivers
|
||||||
// TODO allow overriding of log path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStater returns a string representation for users
|
// ContainerStater returns a string representation for users
|
||||||
@ -192,6 +229,12 @@ func (c *Container) Name() string {
|
|||||||
return c.config.Name
|
return c.config.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodID returns the full ID of the pod the container belongs to, or "" if it
|
||||||
|
// does not belong to a pod
|
||||||
|
func (c *Container) PodID() string {
|
||||||
|
return c.config.Pod
|
||||||
|
}
|
||||||
|
|
||||||
// ShmDir returns the sources path to be mounted on /dev/shm in container
|
// ShmDir returns the sources path to be mounted on /dev/shm in container
|
||||||
func (c *Container) ShmDir() string {
|
func (c *Container) ShmDir() string {
|
||||||
return c.config.ShmDir
|
return c.config.ShmDir
|
||||||
@ -468,6 +511,9 @@ func newContainer(rspec *spec.Spec, lockDir string) (*Container, error) {
|
|||||||
deepcopier.Copy(rspec).To(ctr.config.Spec)
|
deepcopier.Copy(rspec).To(ctr.config.Spec)
|
||||||
ctr.config.CreatedTime = time.Now()
|
ctr.config.CreatedTime = time.Now()
|
||||||
|
|
||||||
|
ctr.config.ShmSize = DefaultShmSize
|
||||||
|
ctr.config.CgroupParent = CgroupParent
|
||||||
|
|
||||||
// Path our lock file will reside at
|
// Path our lock file will reside at
|
||||||
lockPath := filepath.Join(lockDir, ctr.config.ID)
|
lockPath := filepath.Join(lockDir, ctr.config.ID)
|
||||||
// Grab a lockfile at the given path
|
// Grab a lockfile at the given path
|
||||||
@ -679,7 +725,7 @@ func (c *Container) Init() (err error) {
|
|||||||
|
|
||||||
// With the spec complete, do an OCI create
|
// With the spec complete, do an OCI create
|
||||||
// TODO set cgroup parent in a sane fashion
|
// TODO set cgroup parent in a sane fashion
|
||||||
if err := c.runtime.ociRuntime.createContainer(c, CGroupParent); err != nil {
|
if err := c.runtime.ociRuntime.createContainer(c, CgroupParent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,7 +1228,7 @@ func (c *Container) cleanupStorage() error {
|
|||||||
|
|
||||||
// CGroupPath returns a cgroups "path" for a given container.
|
// CGroupPath returns a cgroups "path" for a given container.
|
||||||
func (c *Container) CGroupPath() cgroups.Path {
|
func (c *Container) CGroupPath() cgroups.Path {
|
||||||
return cgroups.StaticPath(filepath.Join(CGroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID())))
|
return cgroups.StaticPath(filepath.Join(CgroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID())))
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyHostFileToRundir copies the provided file to the runtimedir
|
// copyHostFileToRundir copies the provided file to the runtimedir
|
||||||
|
@ -25,7 +25,7 @@ func (c *Container) GetContainerPids() ([]string, error) {
|
|||||||
// Gets the pids for a container without locking. should only be called from a func where
|
// Gets the pids for a container without locking. should only be called from a func where
|
||||||
// locking has already been established.
|
// locking has already been established.
|
||||||
func (c *Container) getContainerPids() ([]string, error) {
|
func (c *Container) getContainerPids() ([]string, error) {
|
||||||
taskFile := filepath.Join("/sys/fs/cgroup/pids", CGroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID()), c.ID(), "tasks")
|
taskFile := filepath.Join("/sys/fs/cgroup/pids", CgroupParent, fmt.Sprintf("libpod-conmon-%s", c.ID()), c.ID(), "tasks")
|
||||||
logrus.Debug("reading pids from ", taskFile)
|
logrus.Debug("reading pids from ", taskFile)
|
||||||
content, err := ioutil.ReadFile(taskFile)
|
content, err := ioutil.ReadFile(taskFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -325,7 +325,7 @@ func WithUser(user string) CtrCreateOption {
|
|||||||
// If useImageConfig is specified, image volumes, environment variables, and
|
// If useImageConfig is specified, image volumes, environment variables, and
|
||||||
// other configuration from the image will be added to the config
|
// other configuration from the image will be added to the config
|
||||||
// TODO: Replace image name and ID with a libpod.Image struct when that is finished
|
// TODO: Replace image name and ID with a libpod.Image struct when that is finished
|
||||||
func WithRootFSFromImage(imageID string, imageName string, useImageConfig bool) CtrCreateOption {
|
func WithRootFSFromImage(imageID string, imageName string, useImageVolumes bool) CtrCreateOption {
|
||||||
return func(ctr *Container) error {
|
return func(ctr *Container) error {
|
||||||
if ctr.valid {
|
if ctr.valid {
|
||||||
return ErrCtrFinalized
|
return ErrCtrFinalized
|
||||||
@ -337,7 +337,7 @@ func WithRootFSFromImage(imageID string, imageName string, useImageConfig bool)
|
|||||||
|
|
||||||
ctr.config.RootfsImageID = imageID
|
ctr.config.RootfsImageID = imageID
|
||||||
ctr.config.RootfsImageName = imageName
|
ctr.config.RootfsImageName = imageName
|
||||||
ctr.config.UseImageConfig = useImageConfig
|
ctr.config.ImageVolumes = useImageVolumes
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
// DBSchema is the current DB schema version
|
// DBSchema is the current DB schema version
|
||||||
// Increments every time a change is made to the database's tables
|
// Increments every time a change is made to the database's tables
|
||||||
const DBSchema = 6
|
const DBSchema = 7
|
||||||
|
|
||||||
// SQLState is a state implementation backed by a persistent SQLite3 database
|
// SQLState is a state implementation backed by a persistent SQLite3 database
|
||||||
type SQLState struct {
|
type SQLState struct {
|
||||||
@ -104,7 +104,9 @@ func (s *SQLState) Refresh() (err error) {
|
|||||||
State=?,
|
State=?,
|
||||||
Mountpoint=?,
|
Mountpoint=?,
|
||||||
Pid=?,
|
Pid=?,
|
||||||
NetNSPath=?;`
|
NetNSPath=?,
|
||||||
|
IPAddress=?,
|
||||||
|
SubnetMask=?;`
|
||||||
|
|
||||||
if !s.valid {
|
if !s.valid {
|
||||||
return ErrDBClosed
|
return ErrDBClosed
|
||||||
@ -130,6 +132,8 @@ func (s *SQLState) Refresh() (err error) {
|
|||||||
ContainerStateConfigured,
|
ContainerStateConfigured,
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
"")
|
"")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error refreshing database state")
|
return errors.Wrapf(err, "error refreshing database state")
|
||||||
@ -154,7 +158,9 @@ func (s *SQLState) Container(id string) (*Container, error) {
|
|||||||
containerState.ExitCode,
|
containerState.ExitCode,
|
||||||
containerState.OomKilled,
|
containerState.OomKilled,
|
||||||
containerState.Pid,
|
containerState.Pid,
|
||||||
containerState.NetNSPath
|
containerState.NetNSPath,
|
||||||
|
containerState.IPAddress,
|
||||||
|
containerState.SubnetMask
|
||||||
FROM containers
|
FROM containers
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
containerState ON containers.Id = containerState.Id
|
containerState ON containers.Id = containerState.Id
|
||||||
@ -170,7 +176,7 @@ func (s *SQLState) Container(id string) (*Container, error) {
|
|||||||
|
|
||||||
row := s.db.QueryRow(query, id)
|
row := s.db.QueryRow(query, id)
|
||||||
|
|
||||||
ctr, err := ctrFromScannable(row, s.runtime, s.specsDir, s.lockDir)
|
ctr, err := s.ctrFromScannable(row)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving container %s from database", id)
|
return nil, errors.Wrapf(err, "error retrieving container %s from database", id)
|
||||||
}
|
}
|
||||||
@ -190,7 +196,9 @@ func (s *SQLState) LookupContainer(idOrName string) (*Container, error) {
|
|||||||
containerState.ExitCode,
|
containerState.ExitCode,
|
||||||
containerState.OomKilled,
|
containerState.OomKilled,
|
||||||
containerState.Pid,
|
containerState.Pid,
|
||||||
containerState.NetNSPath
|
containerState.NetNSPath,
|
||||||
|
containerState.IPAddress,
|
||||||
|
containerState.SubnetMask
|
||||||
FROM containers
|
FROM containers
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
containerState ON containers.Id = containerState.Id
|
containerState ON containers.Id = containerState.Id
|
||||||
@ -218,7 +226,7 @@ func (s *SQLState) LookupContainer(idOrName string) (*Container, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
ctr, err = ctrFromScannable(rows, s.runtime, s.specsDir, s.lockDir)
|
ctr, err = s.ctrFromScannable(rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving container %s from database", idOrName)
|
return nil, errors.Wrapf(err, "error retrieving container %s from database", idOrName)
|
||||||
}
|
}
|
||||||
@ -271,10 +279,17 @@ func (s *SQLState) HasContainer(id string) (bool, error) {
|
|||||||
func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
||||||
const (
|
const (
|
||||||
addCtr = `INSERT INTO containers VALUES (
|
addCtr = `INSERT INTO containers VALUES (
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?
|
||||||
);`
|
);`
|
||||||
addCtrState = `INSERT INTO containerState VALUES (
|
addCtrState = `INSERT INTO containerState VALUES (
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?, ?, ?,
|
||||||
|
?, ?, ?
|
||||||
);`
|
);`
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -286,11 +301,6 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
|||||||
return ErrCtrRemoved
|
return ErrCtrRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
labelsJSON, err := json.Marshal(ctr.config.Labels)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "error marshaling container %s labels to JSON", ctr.ID())
|
|
||||||
}
|
|
||||||
|
|
||||||
mounts, err := json.Marshal(ctr.config.Mounts)
|
mounts, err := json.Marshal(ctr.config.Mounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error marshaling container %s mounts to JSON", ctr.ID())
|
return errors.Wrapf(err, "error marshaling container %s mounts to JSON", ctr.ID())
|
||||||
@ -301,6 +311,11 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
|||||||
return errors.Wrapf(err, "error marshaling container %s port mappings to JSON", ctr.ID())
|
return errors.Wrapf(err, "error marshaling container %s port mappings to JSON", ctr.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labelsJSON, err := json.Marshal(ctr.config.Labels)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error marshaling container %s labels to JSON", ctr.ID())
|
||||||
|
}
|
||||||
|
|
||||||
netNSPath := ""
|
netNSPath := ""
|
||||||
if ctr.state.NetNS != nil {
|
if ctr.state.NetNS != nil {
|
||||||
netNSPath = ctr.state.NetNS.Path()
|
netNSPath = ctr.state.NetNS.Path()
|
||||||
@ -322,22 +337,37 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
|||||||
_, err = tx.Exec(addCtr,
|
_, err = tx.Exec(addCtr,
|
||||||
ctr.ID(),
|
ctr.ID(),
|
||||||
ctr.Name(),
|
ctr.Name(),
|
||||||
|
stringToNullString(ctr.PodID()),
|
||||||
|
|
||||||
|
ctr.config.RootfsImageID,
|
||||||
|
ctr.config.RootfsImageName,
|
||||||
|
boolToSQL(ctr.config.ImageVolumes),
|
||||||
|
boolToSQL(ctr.config.ReadOnly),
|
||||||
|
ctr.config.ShmDir,
|
||||||
|
ctr.config.ShmSize,
|
||||||
|
ctr.config.StaticDir,
|
||||||
|
string(mounts),
|
||||||
|
|
||||||
ctr.config.ProcessLabel,
|
ctr.config.ProcessLabel,
|
||||||
ctr.config.MountLabel,
|
ctr.config.MountLabel,
|
||||||
string(mounts),
|
ctr.config.User,
|
||||||
ctr.config.ShmDir,
|
|
||||||
|
stringToNullString(ctr.config.IPCNsCtr),
|
||||||
|
stringToNullString(ctr.config.MountNsCtr),
|
||||||
|
stringToNullString(ctr.config.NetNsCtr),
|
||||||
|
stringToNullString(ctr.config.PIDNsCtr),
|
||||||
|
stringToNullString(ctr.config.UserNsCtr),
|
||||||
|
stringToNullString(ctr.config.UTSNsCtr),
|
||||||
|
|
||||||
boolToSQL(ctr.config.CreateNetNS),
|
boolToSQL(ctr.config.CreateNetNS),
|
||||||
string(portsJSON),
|
string(portsJSON),
|
||||||
ctr.config.StaticDir,
|
|
||||||
boolToSQL(ctr.config.Stdin),
|
boolToSQL(ctr.config.Stdin),
|
||||||
string(labelsJSON),
|
string(labelsJSON),
|
||||||
ctr.config.StopSignal,
|
ctr.config.StopSignal,
|
||||||
ctr.config.StopTimeout,
|
ctr.config.StopTimeout,
|
||||||
timeToSQL(ctr.config.CreatedTime),
|
timeToSQL(ctr.config.CreatedTime),
|
||||||
ctr.config.RootfsImageID,
|
ctr.config.CgroupParent)
|
||||||
ctr.config.RootfsImageName,
|
|
||||||
boolToSQL(ctr.config.UseImageConfig),
|
|
||||||
ctr.config.User)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error adding static information for container %s to database", ctr.ID())
|
return errors.Wrapf(err, "error adding static information for container %s to database", ctr.ID())
|
||||||
}
|
}
|
||||||
@ -354,7 +384,9 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) {
|
|||||||
ctr.state.ExitCode,
|
ctr.state.ExitCode,
|
||||||
boolToSQL(ctr.state.OOMKilled),
|
boolToSQL(ctr.state.OOMKilled),
|
||||||
ctr.state.PID,
|
ctr.state.PID,
|
||||||
netNSPath)
|
netNSPath,
|
||||||
|
ctr.state.IPAddress,
|
||||||
|
ctr.state.SubnetMask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error adding container %s state to database", ctr.ID())
|
return errors.Wrapf(err, "error adding container %s state to database", ctr.ID())
|
||||||
}
|
}
|
||||||
@ -394,7 +426,9 @@ func (s *SQLState) UpdateContainer(ctr *Container) error {
|
|||||||
ExitCode,
|
ExitCode,
|
||||||
OomKilled,
|
OomKilled,
|
||||||
Pid,
|
Pid,
|
||||||
NetNSPath
|
NetNSPath,
|
||||||
|
IPAddress,
|
||||||
|
SubnetMask
|
||||||
FROM containerState WHERE ID=?;`
|
FROM containerState WHERE ID=?;`
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -408,6 +442,8 @@ func (s *SQLState) UpdateContainer(ctr *Container) error {
|
|||||||
oomKilled int
|
oomKilled int
|
||||||
pid int
|
pid int
|
||||||
netNSPath string
|
netNSPath string
|
||||||
|
ipAddress string
|
||||||
|
subnetMask string
|
||||||
)
|
)
|
||||||
|
|
||||||
if !s.valid {
|
if !s.valid {
|
||||||
@ -429,7 +465,9 @@ func (s *SQLState) UpdateContainer(ctr *Container) error {
|
|||||||
&exitCode,
|
&exitCode,
|
||||||
&oomKilled,
|
&oomKilled,
|
||||||
&pid,
|
&pid,
|
||||||
&netNSPath)
|
&netNSPath,
|
||||||
|
&ipAddress,
|
||||||
|
&subnetMask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The container may not exist in the database
|
// The container may not exist in the database
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -451,6 +489,8 @@ func (s *SQLState) UpdateContainer(ctr *Container) error {
|
|||||||
newState.ExitCode = exitCode
|
newState.ExitCode = exitCode
|
||||||
newState.OOMKilled = boolFromSQL(oomKilled)
|
newState.OOMKilled = boolFromSQL(oomKilled)
|
||||||
newState.PID = pid
|
newState.PID = pid
|
||||||
|
newState.IPAddress = ipAddress
|
||||||
|
newState.SubnetMask = subnetMask
|
||||||
|
|
||||||
if newState.Mountpoint != "" {
|
if newState.Mountpoint != "" {
|
||||||
newState.Mounted = true
|
newState.Mounted = true
|
||||||
@ -512,7 +552,9 @@ func (s *SQLState) SaveContainer(ctr *Container) error {
|
|||||||
ExitCode=?,
|
ExitCode=?,
|
||||||
OomKilled=?,
|
OomKilled=?,
|
||||||
Pid=?,
|
Pid=?,
|
||||||
NetNSPath=?
|
NetNSPath=?,
|
||||||
|
IPAddress=?,
|
||||||
|
SubnetMask=?
|
||||||
WHERE Id=?;`
|
WHERE Id=?;`
|
||||||
|
|
||||||
if !ctr.valid {
|
if !ctr.valid {
|
||||||
@ -552,6 +594,8 @@ func (s *SQLState) SaveContainer(ctr *Container) error {
|
|||||||
boolToSQL(ctr.state.OOMKilled),
|
boolToSQL(ctr.state.OOMKilled),
|
||||||
ctr.state.PID,
|
ctr.state.PID,
|
||||||
netNSPath,
|
netNSPath,
|
||||||
|
ctr.state.IPAddress,
|
||||||
|
ctr.state.SubnetMask,
|
||||||
ctr.ID())
|
ctr.ID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error updating container %s state in database", ctr.ID())
|
return errors.Wrapf(err, "error updating container %s state in database", ctr.ID())
|
||||||
@ -642,7 +686,9 @@ func (s *SQLState) AllContainers() ([]*Container, error) {
|
|||||||
containerState.ExitCode,
|
containerState.ExitCode,
|
||||||
containerState.OomKilled,
|
containerState.OomKilled,
|
||||||
containerState.Pid,
|
containerState.Pid,
|
||||||
containerState.NetNSPath
|
containerState.NetNSPath,
|
||||||
|
containerState.IPAddress,
|
||||||
|
containerState.SubnetMask
|
||||||
FROM containers
|
FROM containers
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
containerState ON containers.Id = containerState.Id
|
containerState ON containers.Id = containerState.Id
|
||||||
@ -661,7 +707,7 @@ func (s *SQLState) AllContainers() ([]*Container, error) {
|
|||||||
containers := []*Container{}
|
containers := []*Container{}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
ctr, err := ctrFromScannable(rows, s.runtime, s.specsDir, s.lockDir)
|
ctr, err := s.ctrFromScannable(rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,7 @@ func prepareDB(db *sql.DB) (err error) {
|
|||||||
// TODO add ctr shared namespaces information - A separate table, probably? So we can FOREIGN KEY the ID
|
// TODO add ctr shared namespaces information - A separate table, probably? So we can FOREIGN KEY the ID
|
||||||
// TODO schema migration might be necessary and should be handled here
|
// TODO schema migration might be necessary and should be handled here
|
||||||
// TODO maybe make a port mappings table instead of JSONing the array and storing it?
|
// TODO maybe make a port mappings table instead of JSONing the array and storing it?
|
||||||
|
// TODO prepared statements for common queries for performance
|
||||||
|
|
||||||
// Enable foreign keys in SQLite
|
// Enable foreign keys in SQLite
|
||||||
if _, err := db.Exec("PRAGMA foreign_keys = ON;"); err != nil {
|
if _, err := db.Exec("PRAGMA foreign_keys = ON;"); err != nil {
|
||||||
@ -166,26 +167,51 @@ func prepareDB(db *sql.DB) (err error) {
|
|||||||
CREATE TABLE IF NOT EXISTS containers(
|
CREATE TABLE IF NOT EXISTS containers(
|
||||||
Id TEXT NOT NULL PRIMARY KEY,
|
Id TEXT NOT NULL PRIMARY KEY,
|
||||||
Name TEXT NOT NULL UNIQUE,
|
Name TEXT NOT NULL UNIQUE,
|
||||||
|
Pod TEXT,
|
||||||
|
|
||||||
|
RootfsImageID TEXT NOT NULL,
|
||||||
|
RootfsImageName TEXT NOT NULL,
|
||||||
|
ImageVolumes INTEGER NOT NULL,
|
||||||
|
ReadOnly INTEGER NOT NULL,
|
||||||
|
ShmDir TEXT NOT NULL,
|
||||||
|
ShmSize INTEGER NOT NULL,
|
||||||
|
StaticDir TEXT NOT NULL,
|
||||||
|
Mounts TEXT NOT NULL,
|
||||||
|
|
||||||
ProcessLabel TEXT NOT NULL,
|
ProcessLabel TEXT NOT NULL,
|
||||||
MountLabel TEXT NOT NULL,
|
MountLabel TEXT NOT NULL,
|
||||||
Mounts TEXT NOT NULL,
|
User TEXT NOT NULL,
|
||||||
ShmDir TEXT NOT NULL,
|
|
||||||
|
IPCNsCtr TEXT,
|
||||||
|
MountNsCtr TEXT,
|
||||||
|
NetNsCtr TEXT,
|
||||||
|
PIDNsCtr TEXT,
|
||||||
|
UserNsCtr TEXT,
|
||||||
|
UTSNsCtr TEXT,
|
||||||
|
|
||||||
CreateNetNS INTEGER NOT NULL,
|
CreateNetNS INTEGER NOT NULL,
|
||||||
PortMappings TEXT NOT NULL,
|
PortMappings TEXT NOT NULL,
|
||||||
StaticDir TEXT NOT NULL,
|
|
||||||
Stdin INTEGER NOT NULL,
|
Stdin INTEGER NOT NULL,
|
||||||
LabelsJSON TEXT NOT NULL,
|
LabelsJSON TEXT NOT NULL,
|
||||||
StopSignal INTEGER NOT NULL,
|
StopSignal INTEGER NOT NULL,
|
||||||
StopTimeout INTEGER NOT NULL,
|
StopTimeout INTEGER NOT NULL,
|
||||||
CreatedTime TEXT NOT NULL,
|
CreatedTime TEXT NOT NULL,
|
||||||
RootfsImageID TEXT NOT NULL,
|
CgroupParent TEXT NOT NULL,
|
||||||
RootfsImageName TEXT NOT NULL,
|
|
||||||
UseImageConfig INTEGER NOT NULL,
|
CHECK (ImageVolumes IN (0, 1)),
|
||||||
User TEXT NOT NULL,
|
CHECK (ReadOnly IN (0, 1)),
|
||||||
CHECK (Stdin IN (0, 1)),
|
CHECK (SHMSize>=0),
|
||||||
CHECK (CreateNetNS IN (0, 1)),
|
CHECK (CreateNetNS IN (0, 1)),
|
||||||
CHECK (UseImageConfig IN (0, 1)),
|
CHECK (Stdin IN (0, 1)),
|
||||||
CHECK (StopSignal>=0)
|
CHECK (StopSignal>=0),
|
||||||
|
FOREIGN KEY (Pod) REFERENCES pod(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (IPCNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (MountNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (NetNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (PIDNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (UserNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED,
|
||||||
|
FOREIGN KEY (UTSNsCtr) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -203,12 +229,24 @@ func prepareDB(db *sql.DB) (err error) {
|
|||||||
OomKilled INTEGER NOT NULL,
|
OomKilled INTEGER NOT NULL,
|
||||||
Pid INTEGER NOT NULL,
|
Pid INTEGER NOT NULL,
|
||||||
NetNSPath TEXT NOT NULL,
|
NetNSPath TEXT NOT NULL,
|
||||||
|
IPAddress TEXT NOT NULL,
|
||||||
|
SubnetMask TEXT NOT NULL,
|
||||||
|
|
||||||
CHECK (State>0),
|
CHECK (State>0),
|
||||||
CHECK (OomKilled IN (0, 1)),
|
CHECK (OomKilled IN (0, 1)),
|
||||||
FOREIGN KEY (Id) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED
|
FOREIGN KEY (Id) REFERENCES containers(Id) DEFERRABLE INITIALLY DEFERRED
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// Create a table for pod config
|
||||||
|
const createPod = `
|
||||||
|
CREATE TABLE IF NOT EXISTS pod(
|
||||||
|
Id TEXT NOT NULL PRIMARY KEY,
|
||||||
|
Name TEXT NOT NULL UNIQUE,
|
||||||
|
Labels TEXT NOT NULL
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
// Create the tables
|
// Create the tables
|
||||||
tx, err := db.Begin()
|
tx, err := db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -229,6 +267,9 @@ func prepareDB(db *sql.DB) (err error) {
|
|||||||
if _, err := tx.Exec(createCtrState); err != nil {
|
if _, err := tx.Exec(createCtrState); err != nil {
|
||||||
return errors.Wrapf(err, "error creating container state table in database")
|
return errors.Wrapf(err, "error creating container state table in database")
|
||||||
}
|
}
|
||||||
|
if _, err := tx.Exec(createPod); err != nil {
|
||||||
|
return errors.Wrapf(err, "error creating pods table in database")
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return errors.Wrapf(err, "error committing table creation transaction in database")
|
return errors.Wrapf(err, "error committing table creation transaction in database")
|
||||||
@ -251,6 +292,25 @@ func boolToSQL(b bool) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a null string from SQL-readable format
|
||||||
|
func stringFromNullString(s sql.NullString) string {
|
||||||
|
if s.Valid {
|
||||||
|
return s.String
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a string to a SQL nullable string
|
||||||
|
func stringToNullString(s string) sql.NullString {
|
||||||
|
if s == "" {
|
||||||
|
return sql.NullString{}
|
||||||
|
}
|
||||||
|
return sql.NullString{
|
||||||
|
String: s,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a bool from SQL-readable format
|
// Convert a bool from SQL-readable format
|
||||||
func boolFromSQL(i int) bool {
|
func boolFromSQL(i int) bool {
|
||||||
return i != 0
|
return i != 0
|
||||||
@ -272,26 +332,42 @@ type scannable interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read a single container from a single row result in the database
|
// Read a single container from a single row result in the database
|
||||||
func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir string) (*Container, error) {
|
func (s *SQLState) ctrFromScannable(row scannable) (*Container, error) {
|
||||||
var (
|
var (
|
||||||
id string
|
id string
|
||||||
name string
|
name string
|
||||||
|
pod sql.NullString
|
||||||
|
|
||||||
|
rootfsImageID string
|
||||||
|
rootfsImageName string
|
||||||
|
imageVolumes int
|
||||||
|
readOnly int
|
||||||
|
shmDir string
|
||||||
|
shmSize int64
|
||||||
|
staticDir string
|
||||||
|
mounts string
|
||||||
|
|
||||||
processLabel string
|
processLabel string
|
||||||
mountLabel string
|
mountLabel string
|
||||||
mounts string
|
user string
|
||||||
shmDir string
|
|
||||||
|
ipcNsCtrNullStr sql.NullString
|
||||||
|
mountNsCtrNullStr sql.NullString
|
||||||
|
netNsCtrNullStr sql.NullString
|
||||||
|
pidNsCtrNullStr sql.NullString
|
||||||
|
userNsCtrNullStr sql.NullString
|
||||||
|
utsNsCtrNullStr sql.NullString
|
||||||
|
|
||||||
createNetNS int
|
createNetNS int
|
||||||
portMappingsJSON string
|
portMappingsJSON string
|
||||||
staticDir string
|
|
||||||
stdin int
|
stdin int
|
||||||
labelsJSON string
|
labelsJSON string
|
||||||
stopSignal uint
|
stopSignal uint
|
||||||
stopTimeout uint
|
stopTimeout uint
|
||||||
createdTimeString string
|
createdTimeString string
|
||||||
rootfsImageID string
|
cgroupParent string
|
||||||
rootfsImageName string
|
|
||||||
useImageConfig int
|
|
||||||
user string
|
|
||||||
state int
|
state int
|
||||||
configPath string
|
configPath string
|
||||||
runDir string
|
runDir string
|
||||||
@ -302,27 +378,45 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
oomKilled int
|
oomKilled int
|
||||||
pid int
|
pid int
|
||||||
netNSPath string
|
netNSPath string
|
||||||
|
ipAddress string
|
||||||
|
subnetMask string
|
||||||
)
|
)
|
||||||
|
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&id,
|
&id,
|
||||||
&name,
|
&name,
|
||||||
|
&pod,
|
||||||
|
|
||||||
|
&rootfsImageID,
|
||||||
|
&rootfsImageName,
|
||||||
|
&imageVolumes,
|
||||||
|
&readOnly,
|
||||||
|
&shmDir,
|
||||||
|
&shmSize,
|
||||||
|
&staticDir,
|
||||||
|
&mounts,
|
||||||
|
|
||||||
&processLabel,
|
&processLabel,
|
||||||
&mountLabel,
|
&mountLabel,
|
||||||
&mounts,
|
&user,
|
||||||
&shmDir,
|
|
||||||
|
&ipcNsCtrNullStr,
|
||||||
|
&mountNsCtrNullStr,
|
||||||
|
&netNsCtrNullStr,
|
||||||
|
&pidNsCtrNullStr,
|
||||||
|
&userNsCtrNullStr,
|
||||||
|
&utsNsCtrNullStr,
|
||||||
|
|
||||||
&createNetNS,
|
&createNetNS,
|
||||||
&portMappingsJSON,
|
&portMappingsJSON,
|
||||||
&staticDir,
|
|
||||||
&stdin,
|
&stdin,
|
||||||
&labelsJSON,
|
&labelsJSON,
|
||||||
&stopSignal,
|
&stopSignal,
|
||||||
&stopTimeout,
|
&stopTimeout,
|
||||||
&createdTimeString,
|
&createdTimeString,
|
||||||
&rootfsImageID,
|
&cgroupParent,
|
||||||
&rootfsImageName,
|
|
||||||
&useImageConfig,
|
|
||||||
&user,
|
|
||||||
&state,
|
&state,
|
||||||
&configPath,
|
&configPath,
|
||||||
&runDir,
|
&runDir,
|
||||||
@ -332,7 +426,9 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
&exitCode,
|
&exitCode,
|
||||||
&oomKilled,
|
&oomKilled,
|
||||||
&pid,
|
&pid,
|
||||||
&netNSPath)
|
&netNSPath,
|
||||||
|
&ipAddress,
|
||||||
|
&subnetMask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return nil, ErrNoSuchCtr
|
return nil, ErrNoSuchCtr
|
||||||
@ -347,18 +443,33 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
|
|
||||||
ctr.config.ID = id
|
ctr.config.ID = id
|
||||||
ctr.config.Name = name
|
ctr.config.Name = name
|
||||||
|
ctr.config.Pod = stringFromNullString(pod)
|
||||||
|
|
||||||
ctr.config.RootfsImageID = rootfsImageID
|
ctr.config.RootfsImageID = rootfsImageID
|
||||||
ctr.config.RootfsImageName = rootfsImageName
|
ctr.config.RootfsImageName = rootfsImageName
|
||||||
ctr.config.UseImageConfig = boolFromSQL(useImageConfig)
|
ctr.config.ImageVolumes = boolFromSQL(imageVolumes)
|
||||||
|
ctr.config.ReadOnly = boolFromSQL(readOnly)
|
||||||
|
ctr.config.ShmDir = shmDir
|
||||||
|
ctr.config.ShmSize = shmSize
|
||||||
|
ctr.config.StaticDir = staticDir
|
||||||
|
|
||||||
ctr.config.ProcessLabel = processLabel
|
ctr.config.ProcessLabel = processLabel
|
||||||
ctr.config.MountLabel = mountLabel
|
ctr.config.MountLabel = mountLabel
|
||||||
ctr.config.ShmDir = shmDir
|
ctr.config.User = user
|
||||||
|
|
||||||
|
ctr.config.IPCNsCtr = stringFromNullString(ipcNsCtrNullStr)
|
||||||
|
ctr.config.MountNsCtr = stringFromNullString(mountNsCtrNullStr)
|
||||||
|
ctr.config.NetNsCtr = stringFromNullString(netNsCtrNullStr)
|
||||||
|
ctr.config.PIDNsCtr = stringFromNullString(pidNsCtrNullStr)
|
||||||
|
ctr.config.UserNsCtr = stringFromNullString(userNsCtrNullStr)
|
||||||
|
ctr.config.UTSNsCtr = stringFromNullString(utsNsCtrNullStr)
|
||||||
|
|
||||||
ctr.config.CreateNetNS = boolFromSQL(createNetNS)
|
ctr.config.CreateNetNS = boolFromSQL(createNetNS)
|
||||||
ctr.config.StaticDir = staticDir
|
|
||||||
ctr.config.Stdin = boolFromSQL(stdin)
|
ctr.config.Stdin = boolFromSQL(stdin)
|
||||||
ctr.config.StopSignal = stopSignal
|
ctr.config.StopSignal = stopSignal
|
||||||
ctr.config.StopTimeout = stopTimeout
|
ctr.config.StopTimeout = stopTimeout
|
||||||
ctr.config.User = user
|
ctr.config.CgroupParent = cgroupParent
|
||||||
|
|
||||||
ctr.state.State = ContainerState(state)
|
ctr.state.State = ContainerState(state)
|
||||||
ctr.state.ConfigPath = configPath
|
ctr.state.ConfigPath = configPath
|
||||||
@ -367,18 +478,14 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
ctr.state.ExitCode = exitCode
|
ctr.state.ExitCode = exitCode
|
||||||
ctr.state.OOMKilled = boolFromSQL(oomKilled)
|
ctr.state.OOMKilled = boolFromSQL(oomKilled)
|
||||||
ctr.state.PID = pid
|
ctr.state.PID = pid
|
||||||
|
ctr.state.IPAddress = ipAddress
|
||||||
|
ctr.state.SubnetMask = subnetMask
|
||||||
|
|
||||||
// TODO should we store this in the database separately instead?
|
// TODO should we store this in the database separately instead?
|
||||||
if ctr.state.Mountpoint != "" {
|
if ctr.state.Mountpoint != "" {
|
||||||
ctr.state.Mounted = true
|
ctr.state.Mounted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := make(map[string]string)
|
|
||||||
if err := json.Unmarshal([]byte(labelsJSON), &labels); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error parsing container %s labels JSON", id)
|
|
||||||
}
|
|
||||||
ctr.config.Labels = labels
|
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(mounts), &ctr.config.Mounts); err != nil {
|
if err := json.Unmarshal([]byte(mounts), &ctr.config.Mounts); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error parsing container %s mounts JSON", id)
|
return nil, errors.Wrapf(err, "error parsing container %s mounts JSON", id)
|
||||||
}
|
}
|
||||||
@ -387,6 +494,12 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
return nil, errors.Wrapf(err, "error parsing container %s port mappings JSON", id)
|
return nil, errors.Wrapf(err, "error parsing container %s port mappings JSON", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels := make(map[string]string)
|
||||||
|
if err := json.Unmarshal([]byte(labelsJSON), &labels); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error parsing container %s labels JSON", id)
|
||||||
|
}
|
||||||
|
ctr.config.Labels = labels
|
||||||
|
|
||||||
createdTime, err := timeFromSQL(createdTimeString)
|
createdTime, err := timeFromSQL(createdTimeString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error parsing container %s created time", id)
|
return nil, errors.Wrapf(err, "error parsing container %s created time", id)
|
||||||
@ -415,10 +528,10 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctr.valid = true
|
ctr.valid = true
|
||||||
ctr.runtime = runtime
|
ctr.runtime = s.runtime
|
||||||
|
|
||||||
// Open and set the lockfile
|
// Open and set the lockfile
|
||||||
lockPath := filepath.Join(lockDir, id)
|
lockPath := filepath.Join(s.lockDir, id)
|
||||||
lock, err := storage.GetLockfile(lockPath)
|
lock, err := storage.GetLockfile(lockPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving lockfile for container %s", id)
|
return nil, errors.Wrapf(err, "error retrieving lockfile for container %s", id)
|
||||||
@ -427,7 +540,7 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir
|
|||||||
|
|
||||||
// Retrieve the spec from disk
|
// Retrieve the spec from disk
|
||||||
ociSpec := new(spec.Spec)
|
ociSpec := new(spec.Spec)
|
||||||
specPath := getSpecPath(specsDir, id)
|
specPath := getSpecPath(s.specsDir, id)
|
||||||
fileContents, err := ioutil.ReadFile(specPath)
|
fileContents, err := ioutil.ReadFile(specPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error reading container %s OCI spec", id)
|
return nil, errors.Wrapf(err, "error reading container %s OCI spec", id)
|
||||||
|
@ -21,7 +21,8 @@ func getTestContainer(id, name, locksDir string) (*Container, error) {
|
|||||||
Name: name,
|
Name: name,
|
||||||
RootfsImageID: id,
|
RootfsImageID: id,
|
||||||
RootfsImageName: "testimg",
|
RootfsImageName: "testimg",
|
||||||
UseImageConfig: true,
|
ImageVolumes: true,
|
||||||
|
ReadOnly: true,
|
||||||
StaticDir: "/does/not/exist/",
|
StaticDir: "/does/not/exist/",
|
||||||
Stdin: true,
|
Stdin: true,
|
||||||
Labels: make(map[string]string),
|
Labels: make(map[string]string),
|
||||||
|
Reference in New Issue
Block a user