From 16237fe067362f73d0ce5699cef9b3b62a45dd3e Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Tue, 5 Dec 2017 17:50:29 -0500 Subject: Add networking configuration to the libpod DB Signed-off-by: Matthew Heon Closes: #109 Approved by: mheon --- libpod/container.go | 10 +++++++++- libpod/options.go | 17 +++++++++++++++++ libpod/sql_state.go | 20 ++++++++++++++------ libpod/sql_state_internal.go | 20 +++++++++++++++++--- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/libpod/container.go b/libpod/container.go index 43ed56848..12fd13f51 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -14,6 +14,7 @@ import ( "github.com/containerd/cgroups" "github.com/containers/storage" "github.com/containers/storage/pkg/archive" + "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/docker/daemon/caps" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/namesgenerator" @@ -119,6 +120,13 @@ type ContainerConfig struct { MountLabel string `json:"MountLabel,omitempty"` // Src path to be mounted on /dev/shm in container ShmDir string `json:"ShmDir,omitempty"` + // CreateNetNS indicates that libpod should create and configure a new + // network namespace for the container + CreateNetNS bool `json:"createNetNS"` + // PortMappings are the ports forwarded to the container's network + // namespace + // These are not used unless CreateNetNS is true + PortMappings []ocicni.PortMapping // Static directory for container content that will persist across // reboot StaticDir string `json:"staticDir"` @@ -130,7 +138,7 @@ type ContainerConfig struct { // about a container Labels map[string]string `json:"labels,omitempty"` // Mounts list contains all additional mounts by the container runtime. - Mounts []string + Mounts []string `json:"mounts,omitempty"` // StopSignal is the signal that will be used to stop the container StopSignal uint `json:"stopSignal,omitempty"` // Shared namespaces with container diff --git a/libpod/options.go b/libpod/options.go index 1fe472ccc..3020ef51a 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -6,6 +6,7 @@ import ( "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" + "github.com/cri-o/ocicni/pkg/ocicni" "github.com/pkg/errors" ) @@ -402,6 +403,22 @@ func WithStopSignal(signal uint) CtrCreateOption { } } +// WithNetNS indicates that the container should be given a new network +// namespace with a minimal configuration +// An optional array of port mappings can be provided +func WithNetNS(portMappings []ocicni.PortMapping) CtrCreateOption { + return func(ctr *Container) error { + if ctr.valid { + return ErrCtrFinalized + } + + ctr.config.CreateNetNS = true + copy(ctr.config.PortMappings, portMappings) + + return nil + } +} + // Pod Creation Options // WithPodName sets the name of the pod diff --git a/libpod/sql_state.go b/libpod/sql_state.go index 02cbd63d8..d0969a783 100644 --- a/libpod/sql_state.go +++ b/libpod/sql_state.go @@ -15,7 +15,7 @@ import ( // DBSchema is the current DB schema version // Increments every time a change is made to the database's tables -const DBSchema = 2 +const DBSchema = 3 // SQLState is a state implementation backed by a persistent SQLite3 database type SQLState struct { @@ -267,7 +267,7 @@ func (s *SQLState) HasContainer(id string) (bool, error) { func (s *SQLState) AddContainer(ctr *Container) (err error) { const ( addCtr = `INSERT INTO containers VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );` addCtrState = `INSERT INTO containerState VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? @@ -287,6 +287,16 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { return errors.Wrapf(err, "error marshaling container %s labels to JSON", ctr.ID()) } + mounts, err := json.Marshal(ctr.config.Mounts) + if err != nil { + return errors.Wrapf(err, "error marshaling container %s mounts to JSON", ctr.ID()) + } + + portsJSON, err := json.Marshal(ctr.config.PortMappings) + if err != nil { + return errors.Wrapf(err, "error marshaling container %s port mappings to JSON", ctr.ID()) + } + tx, err := s.db.Begin() if err != nil { return errors.Wrapf(err, "error beginning database transaction") @@ -299,10 +309,6 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { } }() - mounts, err := json.Marshal(ctr.config.Mounts) - if err != nil { - return errors.Wrapf(err, "error marshaling container %s monunts to JSON", ctr.ID()) - } // Add static container information _, err = tx.Exec(addCtr, ctr.ID(), @@ -311,6 +317,8 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { ctr.config.MountLabel, string(mounts), ctr.config.ShmDir, + boolToSQL(ctr.config.CreateNetNS), + string(portsJSON), ctr.config.StaticDir, boolToSQL(ctr.config.Stdin), string(labelsJSON), diff --git a/libpod/sql_state_internal.go b/libpod/sql_state_internal.go index 12a7dbd10..1d1878b9d 100644 --- a/libpod/sql_state_internal.go +++ b/libpod/sql_state_internal.go @@ -154,6 +154,7 @@ func prepareDB(db *sql.DB) (err error) { // TODO add Pod ID to CreateStaticContainer as a FOREIGN KEY referencing podStatic(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 maybe make a port mappings table instead of JSONing the array and storing it? // Enable foreign keys in SQLite if _, err := db.Exec("PRAGMA foreign_keys = ON;"); err != nil { @@ -169,6 +170,8 @@ func prepareDB(db *sql.DB) (err error) { MountLabel TEXT NOT NULL, Mounts TEXT NOT NULL, ShmDir TEXT NOT NULL, + CreateNetNS INTEGER NOT NULL, + PortMappings TEXT NOT NULL, StaticDir TEXT NOT NULL, Stdin INTEGER NOT NULL, LabelsJSON TEXT NOT NULL, @@ -178,6 +181,7 @@ func prepareDB(db *sql.DB) (err error) { RootfsImageName TEXT NOT NULL, UseImageConfig INTEGER NOT NULL, CHECK (Stdin IN (0, 1)), + CHECK (CreateNetNS IN (0, 1)), CHECK (UseImageConfig IN (0, 1)), CHECK (StopSignal>=0) ); @@ -273,6 +277,8 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir mountLabel string mounts string shmDir string + createNetNS int + portMappingsJSON string staticDir string stdin int labelsJSON string @@ -299,6 +305,8 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir &mountLabel, &mounts, &shmDir, + &createNetNS, + &portMappingsJSON, &staticDir, &stdin, &labelsJSON, @@ -335,10 +343,8 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir ctr.config.UseImageConfig = boolFromSQL(useImageConfig) ctr.config.ProcessLabel = processLabel ctr.config.MountLabel = mountLabel - if err := json.Unmarshal([]byte(mounts), &ctr.config.Mounts); err != nil { - return nil, errors.Wrapf(err, "error parsing container %s mounts JSON", id) - } ctr.config.ShmDir = shmDir + ctr.config.CreateNetNS = boolFromSQL(createNetNS) ctr.config.StaticDir = staticDir ctr.config.Stdin = boolFromSQL(stdin) ctr.config.StopSignal = stopSignal @@ -362,6 +368,14 @@ func ctrFromScannable(row scannable, runtime *Runtime, specsDir string, lockDir } ctr.config.Labels = labels + if err := json.Unmarshal([]byte(mounts), &ctr.config.Mounts); err != nil { + return nil, errors.Wrapf(err, "error parsing container %s mounts JSON", id) + } + + if err := json.Unmarshal([]byte(portMappingsJSON), &ctr.config.PortMappings); err != nil { + return nil, errors.Wrapf(err, "error parsing container %s port mappings JSON", id) + } + createdTime, err := timeFromSQL(createdTimeString) if err != nil { return nil, errors.Wrapf(err, "error parsing container %s created time", id) -- cgit v1.2.3-54-g00ecf