diff --git a/domain/application/errors/errors.go b/domain/application/errors/errors.go index 244a043e352..54e1f7a8c4a 100644 --- a/domain/application/errors/errors.go +++ b/domain/application/errors/errors.go @@ -127,6 +127,11 @@ const ( // wrong value. CharmRelationRoleNotValid = errors.ConstError("charm relation role not valid") + // MultipleCharmHashes describes and error that occurs when a charm has multiple + // hash values. At the moment, we only support sha256 hash format, so if another + // is found, an error is returned. + MultipleCharmHashes = errors.ConstError("multiple charm hashes found") + // ResourceNotFound describes an error that occurs when a resource is // not found. ResourceNotFound = errors.ConstError("resource not found") diff --git a/domain/application/state/charm.go b/domain/application/state/charm.go index d0a10d1f623..702edadbe3c 100644 --- a/domain/application/state/charm.go +++ b/domain/application/state/charm.go @@ -400,28 +400,23 @@ func (s *State) GetCharmArchiveMetadata(ctx context.Context, id corecharm.ID) (a return "", "", internalerrors.Capture(err) } - var archivePathAndHash charmArchivePathAndHash + var archivePathAndHashes []charmArchivePathAndHash ident := charmID{UUID: id.String()} - // NOTE: In theory, we can store multiple hashes of different formats for a - // charm. As of writing, we only store the sha256 hash, but in case this changes - // filter to specify we return the sha256 hash. query := ` SELECT &charmArchivePathAndHash.* FROM charm JOIN charm_hash ON charm.uuid = charm_hash.charm_uuid -JOIN hash_kind ON charm_hash.hash_kind_id = hash_kind.id -WHERE charm.uuid = $charmID.uuid -AND hash_kind.name = "sha256"; +WHERE charm.uuid = $charmID.uuid; ` - stmt, err := s.Prepare(query, archivePathAndHash, ident) + stmt, err := s.Prepare(query, charmArchivePathAndHash{}, ident) if err != nil { return "", "", internalerrors.Errorf("preparing query: %w", err) } if err := db.Txn(ctx, func(ctx context.Context, tx *sqlair.TX) error { - if err := tx.Query(ctx, stmt, ident).Get(&archivePathAndHash); err != nil { + if err := tx.Query(ctx, stmt, ident).GetAll(&archivePathAndHashes); err != nil { if errors.Is(err, sqlair.ErrNoRows) { return applicationerrors.CharmNotFound } @@ -431,8 +426,11 @@ AND hash_kind.name = "sha256"; }); err != nil { return "", "", internalerrors.Errorf("getting charm archive metadata: %w", err) } + if len(archivePathAndHashes) > 1 { + return "", "", internalerrors.Errorf("getting charm archive metadata: %w", applicationerrors.MultipleCharmHashes) + } - return archivePathAndHash.ArchivePath, archivePathAndHash.Hash, nil + return archivePathAndHashes[0].ArchivePath, archivePathAndHashes[0].Hash, nil } // GetCharmMetadata returns the metadata for the charm using the charm ID. diff --git a/domain/application/state/charm_test.go b/domain/application/state/charm_test.go index 53ffa64fd76..077eb56d5b8 100644 --- a/domain/application/state/charm_test.go +++ b/domain/application/state/charm_test.go @@ -2521,10 +2521,8 @@ func (s *charmStateSuite) TestGetCharmArchiveMetadataInsertAdditionalHashKind(c }) c.Assert(err, jc.ErrorIsNil) - got, hash, err := st.GetCharmArchiveMetadata(context.Background(), id) - c.Assert(err, jc.ErrorIsNil) - c.Check(got, gc.DeepEquals, "archive") - c.Check(hash, gc.DeepEquals, "hash") + _, _, err = st.GetCharmArchiveMetadata(context.Background(), id) + c.Assert(err, jc.ErrorIs, applicationerrors.MultipleCharmHashes) } func (s *charmStateSuite) TestGetCharmArchiveMetadataCharmNotFound(c *gc.C) { diff --git a/domain/schema/model/sql/0015-charm.sql b/domain/schema/model/sql/0015-charm.sql index 220da97a77d..ceedb882cdc 100644 --- a/domain/schema/model/sql/0015-charm.sql +++ b/domain/schema/model/sql/0015-charm.sql @@ -159,6 +159,7 @@ CREATE TABLE hash_kind ( CREATE UNIQUE INDEX idx_hash_kind_name ON hash_kind (name); +-- We only support sha256 hashes for now. INSERT INTO hash_kind VALUES (0, 'sha256');