diff options
Diffstat (limited to 'libpod/sql_state.go')
-rw-r--r-- | libpod/sql_state.go | 144 |
1 files changed, 133 insertions, 11 deletions
diff --git a/libpod/sql_state.go b/libpod/sql_state.go index fe3232e62..42f5fe11e 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 = 7 +const DBSchema = 8 // SQLState is a state implementation backed by a persistent SQLite3 database type SQLState struct { @@ -284,7 +284,8 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ? + ?, ?, ?, ?, ?, + ?, ?, ?, ? );` addCtrState = `INSERT INTO containerState VALUES ( ?, ?, ?, ?, ?, @@ -306,9 +307,24 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { return errors.Wrapf(err, "error marshaling container %s mounts to JSON", ctr.ID()) } - portsJSON, err := json.Marshal(ctr.config.PortMappings) + dnsServerJSON, err := json.Marshal(ctr.config.DNSServer) + if err != nil { + return errors.Wrapf(err, "error marshaling container %s DNS servers to JSON", ctr.ID()) + } + + dnsSearchJSON, err := json.Marshal(ctr.config.DNSSearch) if err != nil { - return errors.Wrapf(err, "error marshaling container %s port mappings to JSON", ctr.ID()) + return errors.Wrapf(err, "error marshaling container %s DNS search domains to JSON", ctr.ID()) + } + + dnsOptionJSON, err := json.Marshal(ctr.config.DNSOption) + if err != nil { + return errors.Wrapf(err, "error marshaling container %s DNS options to JSON", ctr.ID()) + } + + hostAddJSON, err := json.Marshal(ctr.config.HostAdd) + if err != nil { + return errors.Wrapf(err, "error marshaling container %s hosts to JSON", ctr.ID()) } labelsJSON, err := json.Marshal(ctr.config.Labels) @@ -321,6 +337,19 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { netNSPath = ctr.state.NetNS.Path() } + specJSON, err := json.Marshal(ctr.config.Spec) + if err != nil { + return errors.Wrapf(err, "error marshalling container %s spec to JSON", ctr.ID()) + } + + portsJSON := []byte{} + if len(ctr.config.PortMappings) > 0 { + portsJSON, err = json.Marshal(&ctr.config.PortMappings) + if err != nil { + return errors.Wrapf(err, "error marshalling container %s port mappings to JSON", ctr.ID()) + } + } + tx, err := s.db.Begin() if err != nil { return errors.Wrapf(err, "error beginning database transaction") @@ -348,6 +377,8 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { ctr.config.StaticDir, string(mounts), + boolToSQL(ctr.config.Privileged), + boolToSQL(ctr.config.NoNewPrivs), ctr.config.ProcessLabel, ctr.config.MountLabel, ctr.config.User, @@ -358,9 +389,13 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { stringToNullString(ctr.config.PIDNsCtr), stringToNullString(ctr.config.UserNsCtr), stringToNullString(ctr.config.UTSNsCtr), + stringToNullString(ctr.config.CgroupNsCtr), boolToSQL(ctr.config.CreateNetNS), - string(portsJSON), + string(dnsServerJSON), + string(dnsSearchJSON), + string(dnsOptionJSON), + string(hostAddJSON), boolToSQL(ctr.config.Stdin), string(labelsJSON), @@ -392,10 +427,6 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { } // Save the container's runtime spec to disk - specJSON, err := json.Marshal(ctr.config.Spec) - if err != nil { - return errors.Wrapf(err, "error marshalling container %s spec to JSON", ctr.ID()) - } specPath := getSpecPath(s.specsDir, ctr.ID()) if err := ioutil.WriteFile(specPath, specJSON, 0750); err != nil { return errors.Wrapf(err, "error saving container %s spec JSON to disk", ctr.ID()) @@ -408,6 +439,21 @@ func (s *SQLState) AddContainer(ctr *Container) (err error) { } }() + // If the container has port mappings, save them to disk + if len(ctr.config.PortMappings) > 0 { + portPath := getPortsPath(s.specsDir, ctr.ID()) + if err := ioutil.WriteFile(portPath, portsJSON, 0750); err != nil { + return errors.Wrapf(err, "error saving container %s port JSON to disk", ctr.ID()) + } + defer func() { + if err != nil { + if err2 := os.Remove(portPath); err2 != nil { + logrus.Errorf("Error removing container %s JSON ports from state: %v", ctr.ID(), err2) + } + } + }() + } + if err := tx.Commit(); err != nil { return errors.Wrapf(err, "error committing transaction to add container %s", ctr.ID()) } @@ -481,8 +527,8 @@ func (s *SQLState) UpdateContainer(ctr *Container) error { return errors.Wrapf(err, "error parsing database state for container %s", ctr.ID()) } - newState := new(containerRuntimeInfo) - newState.State = ContainerState(state) + newState := new(containerState) + newState.State = ContainerStatus(state) newState.ConfigPath = configPath newState.RunDir = runDir newState.Mountpoint = mountpoint @@ -605,6 +651,8 @@ func (s *SQLState) SaveContainer(ctr *Container) error { return errors.Wrapf(err, "error retrieving number of rows modified by update of container %s", ctr.ID()) } if rows == 0 { + // Container was probably removed elsewhere + ctr.valid = false return ErrNoSuchCtr } @@ -615,6 +663,51 @@ func (s *SQLState) SaveContainer(ctr *Container) error { return nil } +// ContainerInUse checks if other containers depend on the given container +// It returns the IDs of containers which depend on the given container +func (s *SQLState) ContainerInUse(ctr *Container) ([]string, error) { + const inUseQuery = `SELECT Id FROM containers WHERE + IPCNsCtr=? OR + MountNsCtr=? OR + NetNsCtr=? OR + PIDNsCtr=? OR + UserNsCtr=? OR + UTSNsCtr=? OR + CgroupNsCtr=?;` + + if !s.valid { + return nil, ErrDBClosed + } + + if !ctr.valid { + return nil, ErrCtrRemoved + } + + id := ctr.ID() + + rows, err := s.db.Query(inUseQuery, id, id, id, id, id, id, id) + if err != nil { + return nil, errors.Wrapf(err, "error querying database for containers that depend on container %s", id) + } + defer rows.Close() + + ids := []string{} + + for rows.Next() { + var ctrID string + if err := rows.Scan(&ctrID); err != nil { + return nil, errors.Wrapf(err, "error scanning container IDs from db rows for container %s", id) + } + + ids = append(ids, ctrID) + } + if err := rows.Err(); err != nil { + return nil, errors.Wrapf(err, "error retrieving rows for container %s", id) + } + + return ids, nil +} + // RemoveContainer removes the container from the state func (s *SQLState) RemoveContainer(ctr *Container) error { const ( @@ -668,6 +761,15 @@ func (s *SQLState) RemoveContainer(ctr *Container) error { return errors.Wrapf(err, "error removing JSON spec from state for container %s", ctr.ID()) } + // Remove containers ports JSON from disk + // May not exist, so ignore os.IsNotExist + portsPath := getPortsPath(s.specsDir, ctr.ID()) + if err := os.Remove(portsPath); err != nil { + if !os.IsNotExist(err) { + return errors.Wrapf(err, "error removing JSON ports from state for container %s", ctr.ID()) + } + } + ctr.valid = false return nil @@ -736,6 +838,11 @@ func (s *SQLState) HasPod(id string) (bool, error) { return false, ErrNotImplemented } +// PodContainers returns all the containers in a pod given the pod's full ID +func (s *SQLState) PodContainers(id string) ([]*Container, error) { + return nil, ErrNotImplemented +} + // AddPod adds a pod to the state // Only empty pods can be added to the state func (s *SQLState) AddPod(pod *Pod) error { @@ -748,6 +855,21 @@ func (s *SQLState) RemovePod(pod *Pod) error { return ErrNotImplemented } +// UpdatePod updates a pod from the database +func (s *SQLState) UpdatePod(pod *Pod) error { + return ErrNotImplemented +} + +// AddContainerToPod adds a container to the given pod +func (s *SQLState) AddContainerToPod(pod *Pod, ctr *Container) error { + return ErrNotImplemented +} + +// RemoveContainerFromPod removes a container from the given pod +func (s *SQLState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { + return ErrNotImplemented +} + // AllPods retrieves all pods presently in the state func (s *SQLState) AllPods() ([]*Pod, error) { return nil, ErrNotImplemented |