From b33ca2823678e69acb1bfdd2c71f26803992f3cd Mon Sep 17 00:00:00 2001 From: rverdile Date: Wed, 12 Nov 2025 16:40:12 -0500 Subject: [PATCH] HMS-8948: Fix module stream version parsing A bug in the yummy dependency led to incorrect module stream version parsing. This bumps the yummy version to include the fix and fixes a bug that prevented the incorrect stream from being removed --- go.mod | 3 +- go.sum | 6 +-- pkg/dao/environments_test.go | 26 +++++++++++++ pkg/dao/module_streams.go | 5 ++- pkg/dao/module_streams_test.go | 42 +++++++++++++++++++++ pkg/dao/package_groups_test.go | 26 +++++++++++++ pkg/dao/rpms_test.go | 26 +++++++++++++ pkg/middleware/enforce_consistent_org_id.go | 4 ++ 8 files changed, 130 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index eeb79e128..8c9a2fe2e 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/ProtonMail/go-crypto v1.3.0 github.com/content-services/lecho/v3 v3.5.2 github.com/content-services/tang v0.0.16 - github.com/content-services/yummy v1.0.17 + github.com/content-services/yummy v1.0.18 github.com/getkin/kin-openapi v0.133.0 github.com/go-openapi/spec v0.22.0 // indirect github.com/golang-migrate/migrate/v4 v4.19.0 @@ -159,7 +159,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/go.sum b/go.sum index 50ee31e7b..ffb6d8af0 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/content-services/lecho/v3 v3.5.2 h1:lNGYoG/6RnPtnGtWkKSUwO2Huw6lxDrW1 github.com/content-services/lecho/v3 v3.5.2/go.mod h1:hALn6ZuFGV3AIYlkhZDU1C5JoWM4TeIx//VO2xt8oZA= github.com/content-services/tang v0.0.16 h1:omJ9qxuj3OaNR9XD1K2YS2QqABtAT5u7LrNaN1Z08CQ= github.com/content-services/tang v0.0.16/go.mod h1:Kny+gBiKxmn4YNzDP3zaRG/QrD8CzkKs+9Xk+Ivqogs= -github.com/content-services/yummy v1.0.17 h1:DbMNfA9uWmABOyAsUsj5HzLqkrdERuxKmjPCrePIoqk= -github.com/content-services/yummy v1.0.17/go.mod h1:80EJlin8wGY8+hBfTtD8LgYPma19iV+LaQ+4u0ObCJ0= +github.com/content-services/yummy v1.0.18 h1:+2O7OuhNbLkJ57X96Rqp2QjA9700lBZH0+TVfQ45Xqs= +github.com/content-services/yummy v1.0.18/go.mod h1:amF1J0cbrwL19dcRZrvIC6POPEbMV4C6M8kP8kcl/VI= github.com/content-services/zest/release/v2025 v2025.11.1763728709 h1:ykPtrGO3MZpVE71xxUY11YanSaJJI/DKyZHoeXly5Dw= github.com/content-services/zest/release/v2025 v2025.11.1763728709/go.mod h1:Aci51FiIoCrGZ0/oziL7jVF/bKN+A7QzPfpI4uTaRYQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -256,8 +256,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= diff --git a/pkg/dao/environments_test.go b/pkg/dao/environments_test.go index 5344a6a03..72aca477f 100644 --- a/pkg/dao/environments_test.go +++ b/pkg/dao/environments_test.go @@ -660,6 +660,32 @@ func (s *EnvironmentSuite) TestInsertForRepositoryWithExistingEnvironments() { assert.Equal(t, int64(len(e[1:groupCount+1])), environmentCount) } +func (s *EnvironmentSuite) TestInsertForRepositoryDeleteUnneeded() { + t := s.T() + tx := s.tx + var environmentCount int64 + + dao := GetEnvironmentDao(tx) + + initialEnvironments := s.prepareScenarioEnvironments(scenarioThreshold, 3) + records, err := dao.InsertForRepository(context.Background(), s.repo.UUID, initialEnvironments) + assert.NoError(t, err) + assert.Equal(t, int64(3), records) + + environmentCount, err = repoEnvironmentCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(3), environmentCount) + + reducedEnvironments := s.prepareScenarioEnvironments(scenarioThreshold, 2) + records, err = dao.InsertForRepository(context.Background(), s.repo.UUID, reducedEnvironments) + assert.NoError(t, err) + assert.Equal(t, int64(2), records) + + environmentCount, err = repoEnvironmentCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(2), environmentCount) +} + func (s *EnvironmentSuite) TestInsertForRepositoryWithWrongRepoUUID() { t := s.T() tx := s.tx diff --git a/pkg/dao/module_streams.go b/pkg/dao/module_streams.go index 80c678ca1..851a31f25 100644 --- a/pkg/dao/module_streams.go +++ b/pkg/dao/module_streams.go @@ -220,7 +220,7 @@ func ModuleMdToModuleStreams(moduleMds []yum.ModuleMD) (moduleStreams []models.M for _, m := range moduleMds { mStream := models.ModuleStream{ Name: m.Data.Name, - Stream: m.Data.Stream, + Stream: m.Data.Stream.String(), Version: m.Data.Version, Context: m.Data.Context, Arch: m.Data.Arch, @@ -308,11 +308,12 @@ func (r moduleStreamsImpl) InsertForRepository(ctx context.Context, repoUuid str return int64(len(repoModStreams)), nil } -// deleteUnneeded removes any RepositoryPackageGroup entries that are not in the list of package_group_uuids +// deleteUnneeded removes any ModuleStream entries that are not in the list of moduleStreamUUIDs func (r moduleStreamsImpl) deleteUnneeded(ctx context.Context, repo models.Repository, moduleStreamUUIDs []string) error { if err := r.db.WithContext(ctx).Model(&models.RepositoryModuleStream{}). Where("repository_uuid = ?", repo.UUID). Where("module_stream_uuid NOT IN (?)", moduleStreamUUIDs). + Delete(&models.RepositoryModuleStream{}). Error; err != nil { return err } diff --git a/pkg/dao/module_streams_test.go b/pkg/dao/module_streams_test.go index 846ba98f8..2664db5c8 100644 --- a/pkg/dao/module_streams_test.go +++ b/pkg/dao/module_streams_test.go @@ -249,6 +249,48 @@ func (s *ModuleStreamSuite) TestInsertForRepository() { assert.Equal(t, int64(1), count) } +func (s *ModuleStreamSuite) TestInsertForRepositoryDeletedUnneeded() { + t := s.T() + tx := s.tx + + mods := []yum.ModuleMD{testYumModuleMD()} + mod2 := testYumModuleMD() + mod2.Data.Name = "secondmodule" + mod2.Data.Stream = "2.0" + mod2.Data.Context = "secondcontext" + + dao := GetModuleStreamsDao(tx) + + twoMods := []yum.ModuleMD{mods[0], mod2} + cnt, err := dao.InsertForRepository(context.Background(), s.repo.UUID, twoMods) + assert.NoError(t, err) + assert.Equal(t, int64(2), cnt) + + // Verify both are in repositories_module_streams table + var repoModCount int64 + res := tx.Model(&models.RepositoryModuleStream{}). + Where("repository_uuid = ?", s.repo.UUID). + Count(&repoModCount) + assert.NoError(t, res.Error) + assert.Equal(t, int64(2), repoModCount) + + // Insert only the first module again - should delete the second one + cnt, err = dao.InsertForRepository(context.Background(), s.repo.UUID, mods) + assert.NoError(t, err) + assert.Equal(t, int64(1), cnt) + + // Verify the correct module stream remains + var repoModStreams []models.RepositoryModuleStream + res = tx.Where("repository_uuid = ?", s.repo.UUID).Find(&repoModStreams) + assert.NoError(t, res.Error) + assert.Len(t, repoModStreams, 1) + + var remainingModStream models.ModuleStream + res = tx.Where("uuid = ?", repoModStreams[0].ModuleStreamUUID).Find(&remainingModStream) + assert.NoError(t, res.Error) + assert.Equal(t, mods[0].Data.Context, remainingModStream.Context) +} + func (s *ModuleStreamSuite) TestOrphanCleanup() { mod1 := models.ModuleStream{ Name: "mod1", diff --git a/pkg/dao/package_groups_test.go b/pkg/dao/package_groups_test.go index 9a6b23296..ddd60b488 100644 --- a/pkg/dao/package_groups_test.go +++ b/pkg/dao/package_groups_test.go @@ -703,6 +703,32 @@ func (s *PackageGroupSuite) TestInsertForRepositoryWithExistingGroups() { assert.Equal(t, int64(len(p[1:groupCount+1])), packageGroupCount) } +func (s *PackageGroupSuite) TestInsertForRepositoryDeleteUnneeded() { + t := s.T() + tx := s.tx + var packageGroupCount int64 + + dao := GetPackageGroupDao(tx) + + initialPackageGroups := s.prepareScenarioPackageGroups(scenarioThreshold, 3) + records, err := dao.InsertForRepository(context.Background(), s.repo.UUID, initialPackageGroups) + assert.NoError(t, err) + assert.Equal(t, int64(3), records) + + packageGroupCount, err = repoPackageGroupCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(3), packageGroupCount) + + reducedPackageGroups := s.prepareScenarioPackageGroups(scenarioThreshold, 2) + records, err = dao.InsertForRepository(context.Background(), s.repo.UUID, reducedPackageGroups) + assert.NoError(t, err) + assert.Equal(t, int64(2), records) + + packageGroupCount, err = repoPackageGroupCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(2), packageGroupCount) +} + func (s *PackageGroupSuite) TestInsertForRepositoryWithWrongRepoUUID() { t := s.T() tx := s.tx diff --git a/pkg/dao/rpms_test.go b/pkg/dao/rpms_test.go index da9c02507..7c9685a39 100644 --- a/pkg/dao/rpms_test.go +++ b/pkg/dao/rpms_test.go @@ -979,6 +979,32 @@ func (s *RpmSuite) TestInsertForRepositoryWithExistingChecksums() { assert.Equal(t, int64(len(p[1:groupCount+1])), rpm_count) } +func (s *RpmSuite) TestInsertForRepositoryDeleteUnneeded() { + t := s.T() + tx := s.tx + var rpm_count int64 + + dao := GetRpmDao(tx, s.mockRoadmapClient) + + initialRpms := makeYumPackage(3) + records, err := dao.InsertForRepository(context.Background(), s.repo.UUID, initialRpms) + assert.NoError(t, err) + assert.Equal(t, int64(3), records) + + rpm_count, err = repoRpmCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(3), rpm_count) + + reducedRpms := makeYumPackage(2) + records, err = dao.InsertForRepository(context.Background(), s.repo.UUID, reducedRpms) + assert.NoError(t, err) + assert.Equal(t, int64(2), records) + + rpm_count, err = repoRpmCount(tx, s.repo.UUID) + assert.NoError(t, err) + assert.Equal(t, int64(2), rpm_count) +} + func (s *RpmSuite) TestInsertForRepositoryWithLotsOfRpms() { t := s.T() tx := s.tx diff --git a/pkg/middleware/enforce_consistent_org_id.go b/pkg/middleware/enforce_consistent_org_id.go index 5e5298345..f443e0999 100644 --- a/pkg/middleware/enforce_consistent_org_id.go +++ b/pkg/middleware/enforce_consistent_org_id.go @@ -133,6 +133,10 @@ func SkipEnforceConsistentOrgId(c echo.Context) bool { "/admin/tasks/:uuid", "/admin/features/", "/admin/features/:name/content/", + "/rpms/names", + "/package_groups/names", + "/environments/names", + "/module_streams/search", } return utils.Contains(skipped, path) }