From 6e0f11da5d2c19d178ce6b839f57b35f29e01402 Mon Sep 17 00:00:00 2001 From: Matt Heon Date: Tue, 7 Mar 2023 13:27:55 -0500 Subject: [PATCH] Improve handling of existing container names in SQLite Return more sensible errors than SQLite's embedded constraint failure ones. Should fix a number of integration tests. Signed-off-by: Matt Heon --- libpod/sqlite_state.go | 13 ++++++++++++- libpod/sqlite_state_internal.go | 11 +++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/libpod/sqlite_state.go b/libpod/sqlite_state.go index 881731f828..72ee89fc35 100644 --- a/libpod/sqlite_state.go +++ b/libpod/sqlite_state.go @@ -1482,7 +1482,7 @@ func (s *SQLiteState) AddPod(pod *Pod) (defErr error) { 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) + return fmt.Errorf("name %q is in use: %w", pod.Name(), define.ErrPodExists) } if _, err := tx.Exec("INSERT INTO IDNamespace VALUES (?);", pod.ID()); err != nil { @@ -1816,6 +1816,17 @@ func (s *SQLiteState) AddVolume(volume *Volume) (defErr error) { } }() + // TODO: There has to be a better way of doing this + var check int + row := tx.QueryRow("SELECT 1 FROM VolumeConfig WHERE Name=?;", volume.Name()) + if err := row.Scan(&check); err != nil { + if !errors.Is(err, sql.ErrNoRows) { + return fmt.Errorf("checking if volume name %s exists in database: %w", volume.Name(), err) + } + } else if check != 0 { + return fmt.Errorf("name %q is in use: %w", volume.Name(), define.ErrVolumeExists) + } + if _, err := tx.Exec("INSERT INTO VolumeConfig VALUES (?, ?, ?);", volume.Name(), storageID, cfgJSON); err != nil { return fmt.Errorf("adding volume %s config to database: %w", volume.Name(), err) } diff --git a/libpod/sqlite_state_internal.go b/libpod/sqlite_state_internal.go index bc8b966c9e..19c3d46c6a 100644 --- a/libpod/sqlite_state_internal.go +++ b/libpod/sqlite_state_internal.go @@ -374,6 +374,17 @@ func (s *SQLiteState) addContainer(ctr *Container) (defErr error) { } }() + // TODO: There has to be a better way of doing this + var check int + row := tx.QueryRow("SELECT 1 FROM ContainerConfig WHERE Name=?;", ctr.Name()) + if err := row.Scan(&check); err != nil { + if !errors.Is(err, sql.ErrNoRows) { + return fmt.Errorf("checking if container name %s exists in database: %w", ctr.Name(), err) + } + } else if check != 0 { + return fmt.Errorf("name %q is in use: %w", ctr.Name(), define.ErrCtrExists) + } + if _, err := tx.Exec("INSERT INTO IDNamespace VALUES (?);", ctr.ID()); err != nil { return fmt.Errorf("adding container id to database: %w", err) }