Merge pull request #17658 from vrothberg/sqlite

sqlite updates
This commit is contained in:
OpenShift Merge Robot
2023-03-02 07:55:04 +01:00
committed by GitHub
2 changed files with 71 additions and 42 deletions

View File

@ -1186,7 +1186,7 @@ func (s *SQLiteState) RewritePodConfig(pod *Pod, newCfg *PodConfig) (defErr erro
} }
if rows == 0 { if rows == 0 {
pod.valid = false pod.valid = false
return define.ErrNoSuchPod return fmt.Errorf("no pod with ID %s found in DB: %w", pod.ID(), define.ErrNoSuchPod)
} }
if err := tx.Commit(); err != nil { if err := tx.Commit(); err != nil {
@ -1199,8 +1199,7 @@ func (s *SQLiteState) RewritePodConfig(pod *Pod, newCfg *PodConfig) (defErr erro
// RewriteVolumeConfig rewrites a volume's configuration. // RewriteVolumeConfig rewrites a volume's configuration.
// WARNING: This function is DANGEROUS. Do not use without reading the full // WARNING: This function is DANGEROUS. Do not use without reading the full
// comment on this function in state.go. // comment on this function in state.go.
// TODO TODO TODO func (s *SQLiteState) RewriteVolumeConfig(volume *Volume, newCfg *VolumeConfig) (defErr error) {
func (s *SQLiteState) RewriteVolumeConfig(volume *Volume, newCfg *VolumeConfig) error {
if !s.valid { if !s.valid {
return define.ErrDBClosed return define.ErrDBClosed
} }
@ -1209,38 +1208,41 @@ func (s *SQLiteState) RewriteVolumeConfig(volume *Volume, newCfg *VolumeConfig)
return define.ErrVolumeRemoved return define.ErrVolumeRemoved
} }
return define.ErrNotImplemented json, err := json.Marshal(newCfg)
if err != nil {
return fmt.Errorf("error marshalling volume %s new config JSON: %w", volume.Name(), err)
}
// newCfgJSON, err := json.Marshal(newCfg) tx, err := s.conn.Begin()
// if err != nil { if err != nil {
// return fmt.Errorf("marshalling new configuration JSON for volume %q: %w", volume.Name(), err) return fmt.Errorf("beginning transaction to rewrite volume %s config: %w", volume.Name(), err)
// } }
defer func() {
if defErr != nil {
if err := tx.Rollback(); err != nil {
logrus.Errorf("Rolling back transaction to rewrite volume %s config: %v", volume.Name(), err)
}
}
}()
// db, err := s.getDBCon() results, err := tx.Exec("UPDATE VolumeConfig SET Name=?, JSON=? WHERE ID=?;", newCfg.Name, json, volume.Name())
// if err != nil { if err != nil {
// return err return fmt.Errorf("updating volume config table with new configuration for volume %s: %w", volume.Name(), err)
// } }
// defer s.deferredCloseDBCon(db) rows, err := results.RowsAffected()
if err != nil {
return fmt.Errorf("retrieving volume %s config rewrite rows affected: %w", volume.Name(), err)
}
if rows == 0 {
volume.valid = false
return fmt.Errorf("no volume with name %q found in DB: %w", volume.Name(), define.ErrNoSuchVolume)
}
// err = db.Update(func(tx *bolt.Tx) error { if err := tx.Commit(); err != nil {
// volBkt, err := getVolBucket(tx) return fmt.Errorf("committing transaction to rewrite volume %s config: %w", volume.Name(), err)
// if err != nil { }
// return err
// }
// volDB := volBkt.Bucket([]byte(volume.Name())) return nil
// if volDB == nil {
// volume.valid = false
// return fmt.Errorf("no volume with name %q found in DB: %w", volume.Name(), define.ErrNoSuchVolume)
// }
// if err := volDB.Put(configKey, newCfgJSON); err != nil {
// return fmt.Errorf("updating volume %q config JSON: %w", volume.Name(), err)
// }
// return nil
// })
// return err
} }
// Pod retrieves a pod given its full ID // Pod retrieves a pod given its full ID
@ -1470,6 +1472,19 @@ func (s *SQLiteState) AddPod(pod *Pod) (defErr error) {
} }
}() }()
// TODO: explore whether there's a more idiomatic way to do error checks for the name.
// There is a sqlite3.ErrConstraintUnique error but I (vrothberg) couldn't find a way
// to work with the returned errors yet.
var check int
row := tx.QueryRow("SELECT 1 FROM PodConfig WHERE Name=?;", pod.Name())
if err := row.Scan(&check); err != nil {
if !errors.Is(err, sql.ErrNoRows) {
return fmt.Errorf("checking if pod name %s exists in database: %w", pod.Name(), err)
}
} else if check != 0 {
return fmt.Errorf("name \"%s\" is in use: %w", pod.Name(), define.ErrPodExists)
}
if _, err := tx.Exec("INSERT INTO IDNamespace VALUES (?);", pod.ID()); err != nil { if _, err := tx.Exec("INSERT INTO IDNamespace VALUES (?);", pod.ID()); err != nil {
return fmt.Errorf("adding pod id to database: %w", err) return fmt.Errorf("adding pod id to database: %w", err)
} }
@ -2033,25 +2048,26 @@ func (s *SQLiteState) LookupVolume(name string) (*Volume, error) {
return nil, define.ErrDBClosed return nil, define.ErrDBClosed
} }
rows, err := s.conn.Query("SELECT JSON FROM VolumeConfig WHERE Name LIKE ?;", name+"%") rows, err := s.conn.Query("SELECT Name, JSON FROM VolumeConfig WHERE Name LIKE ? ORDER BY LENGTH(Name) ASC;", name+"%")
if err != nil { if err != nil {
return nil, fmt.Errorf("querying database for volume %s: %w", name, err) return nil, fmt.Errorf("querying database for volume %s: %w", name, err)
} }
defer rows.Close() defer rows.Close()
var configJSON string var foundName, configJSON string
foundResult := false
for rows.Next() { for rows.Next() {
if foundResult { if foundName != "" {
return nil, fmt.Errorf("more than one result for volume name %s: %w", name, define.ErrVolumeExists) return nil, fmt.Errorf("more than one result for volume name %s: %w", name, define.ErrVolumeExists)
} }
if err := rows.Scan(&configJSON); err != nil { if err := rows.Scan(&foundName, &configJSON); err != nil {
return nil, fmt.Errorf("retrieving volume %s config from database: %w", name, err) return nil, fmt.Errorf("retrieving volume %s config from database: %w", name, err)
} }
foundResult = true if foundName == name {
break
} }
if !foundResult { }
return nil, define.ErrNoSuchVolume if foundName == "" {
return nil, fmt.Errorf("no volume with name %q found: %w", name, define.ErrNoSuchVolume)
} }
vol := new(Volume) vol := new(Volume)

View File

@ -318,7 +318,7 @@ func (s *SQLiteState) rewriteContainerConfig(ctr *Container, newCfg *ContainerCo
} }
}() }()
results, err := tx.Exec("UPDATE TABLE ContainerConfig SET Name=?, JSON=? WHERE ID=?;", newCfg.Name, json, ctr.ID()) results, err := tx.Exec("UPDATE ContainerConfig SET Name=?, JSON=? WHERE ID=?;", newCfg.Name, json, ctr.ID())
if err != nil { if err != nil {
return fmt.Errorf("updating container config table with new configuration for container %s: %w", ctr.ID(), err) return fmt.Errorf("updating container config table with new configuration for container %s: %w", ctr.ID(), err)
} }
@ -339,6 +339,12 @@ func (s *SQLiteState) rewriteContainerConfig(ctr *Container, newCfg *ContainerCo
} }
func (s *SQLiteState) addContainer(ctr *Container) (defErr error) { func (s *SQLiteState) addContainer(ctr *Container) (defErr error) {
for net := range ctr.config.Networks {
opts := ctr.config.Networks[net]
opts.Aliases = append(opts.Aliases, ctr.config.ID[:12])
ctr.config.Networks[net] = opts
}
configJSON, err := json.Marshal(ctr.config) configJSON, err := json.Marshal(ctr.config)
if err != nil { if err != nil {
return fmt.Errorf("marshalling container config json: %w", err) return fmt.Errorf("marshalling container config json: %w", err)
@ -399,10 +405,14 @@ func (s *SQLiteState) addContainer(ctr *Container) (defErr error) {
return fmt.Errorf("adding container dependency %s to database: %w", dep, err) return fmt.Errorf("adding container dependency %s to database: %w", dep, err)
} }
} }
volMap := make(map[string]bool)
for _, vol := range ctr.config.NamedVolumes { for _, vol := range ctr.config.NamedVolumes {
if _, ok := volMap[vol.Name]; !ok {
if _, err := tx.Exec("INSERT INTO ContainerVolume VALUES (?, ?);", ctr.ID(), vol.Name); err != nil { if _, err := tx.Exec("INSERT INTO ContainerVolume VALUES (?, ?);", ctr.ID(), vol.Name); err != nil {
return fmt.Errorf("adding container volume %s to database: %w", vol.Name, err) return fmt.Errorf("adding container volume %s to database: %w", vol.Name, err)
} }
volMap[vol.Name] = true
}
} }
if err := tx.Commit(); err != nil { if err := tx.Commit(); err != nil {
@ -499,6 +509,9 @@ func (s *SQLiteState) networkModify(ctr *Container, network string, opts types.P
} }
if !disconnect { if !disconnect {
if newCfg.Networks == nil {
newCfg.Networks = make(map[string]types.PerNetworkOptions)
}
newCfg.Networks[network] = opts newCfg.Networks[network] = opts
} else { } else {
delete(newCfg.Networks, network) delete(newCfg.Networks, network)