Skip to content

Commit c045f5c

Browse files
author
Antonio Salinas
authored
feat: Snapshots for Static source preparation (#407)
* Use distro ref snapshot to checkout sources at a point in time * Schema update for snapshot * Refactored distro resolutions and feedback * Fixed lint error * Fixed formatting mistakes * Updated scenario schema for snapshot
1 parent eda4edc commit c045f5c

12 files changed

Lines changed: 562 additions & 185 deletions

File tree

internal/projectconfig/distro.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ type DistroReference struct {
1515
Name string `toml:"name" json:"name,omitempty" jsonschema:"required,title=Name,description=Name of the referenced distro"`
1616
// Version of the referenced distro.
1717
Version string `toml:"version,omitempty" json:"version,omitempty" jsonschema:"title=Version,description=Version of the referenced distro"`
18+
// Snapshot date/time for source code if specified components will use source as it existed at this time.
19+
Snapshot string `toml:"snapshot,omitempty" json:"snapshot,omitempty" jsonschema:"format=date-time,title=Snapshot,description=If specified use source code as it existed at this date/time"`
1820
}
1921

2022
// Implements the [Stringer] interface for [DistroReference].

internal/providers/sourceproviders/fedorasource/fedorasource.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@ import (
2323
type FedoraSourceDownloader interface {
2424
// ExtractSourcesFromRepo processes a git repository by downloading any required
2525
// lookaside cache files into the repository directory.
26-
ExtractSourcesFromRepo(ctx context.Context, repoDir string, packageName string) error
26+
ExtractSourcesFromRepo(ctx context.Context, repoDir string, packageName string, lookasideBaseURI string) error
2727
}
2828

2929
// FedoraSourceDownloaderImpl is an implementation of GitRepoExtractor.
3030
type FedoraSourceDownloaderImpl struct {
31-
dryRunnable opctx.DryRunnable
32-
fileSystem opctx.FS
33-
downloader downloader.Downloader
34-
lookasideBaseURI string
31+
dryRunnable opctx.DryRunnable
32+
fileSystem opctx.FS
33+
downloader downloader.Downloader
3534
}
3635

3736
// Ensure [FedoraSourceDownloaderImpl] implements [FedoraSourceDownloader].
@@ -62,12 +61,11 @@ type sourceFileInfo struct {
6261
}
6362

6463
// NewFedoraRepoExtractorImpl creates a new instance of FedoraRepoExtractorImpl
65-
// with the provided downloader and lookaside base URI.
64+
// with the provided downloader.
6665
func NewFedoraRepoExtractorImpl(
6766
dryRunnable opctx.DryRunnable,
6867
fileSystem opctx.FS,
6968
downloader downloader.Downloader,
70-
lookasideBaseURI string,
7169
) (*FedoraSourceDownloaderImpl, error) {
7270
if fileSystem == nil {
7371
return nil, errors.New("filesystem cannot be nil")
@@ -81,31 +79,30 @@ func NewFedoraRepoExtractorImpl(
8179
return nil, errors.New("dry runnable cannot be nil")
8280
}
8381

84-
if lookasideBaseURI == "" {
85-
return nil, errors.New("lookaside base URI cannot be empty")
86-
}
87-
88-
if err := verifyFedoraLookasideBaseURI(lookasideBaseURI); err != nil {
89-
return nil, err
90-
}
91-
9282
return &FedoraSourceDownloaderImpl{
93-
dryRunnable: dryRunnable,
94-
fileSystem: fileSystem,
95-
downloader: downloader,
96-
lookasideBaseURI: lookasideBaseURI,
83+
dryRunnable: dryRunnable,
84+
fileSystem: fileSystem,
85+
downloader: downloader,
9786
}, nil
9887
}
9988

10089
// ExtractSourcesFromRepo processes the git repository by downloading any required
10190
// lookaside cache files into the repository directory.
10291
func (g *FedoraSourceDownloaderImpl) ExtractSourcesFromRepo(
103-
ctx context.Context, repoDir string, packageName string,
92+
ctx context.Context, repoDir string, packageName string, lookasideBaseURI string,
10493
) error {
10594
if repoDir == "" {
10695
return errors.New("repository directory cannot be empty")
10796
}
10897

98+
if lookasideBaseURI == "" {
99+
return errors.New("lookaside base URI cannot be empty")
100+
}
101+
102+
if err := verifyFedoraLookasideBaseURI(lookasideBaseURI); err != nil {
103+
return err
104+
}
105+
109106
repoDirExists, err := fileutils.Exists(g.fileSystem, repoDir)
110107
if err != nil {
111108
return fmt.Errorf("failed to check if repository directory exists at %#q:\n%w", repoDir, err)
@@ -117,7 +114,7 @@ func (g *FedoraSourceDownloaderImpl) ExtractSourcesFromRepo(
117114

118115
sourcesFilePath := filepath.Join(repoDir, "sources")
119116

120-
sourceFiles, err := g.extractSourcesInfo(sourcesFilePath, packageName)
117+
sourceFiles, err := g.extractSourcesInfo(sourcesFilePath, packageName, lookasideBaseURI)
121118
if err != nil {
122119
return fmt.Errorf("failed to extract sources info from sources file at %#q:\n%w", sourcesFilePath, err)
123120
}
@@ -174,6 +171,7 @@ func (g *FedoraSourceDownloaderImpl) validateDownloadedFile(
174171
func (g *FedoraSourceDownloaderImpl) extractSourcesInfo(
175172
sourcesFilePath string,
176173
packageName string,
174+
lookasideBaseURI string,
177175
) ([]sourceFileInfo, error) {
178176
sourcesContent, err := afero.ReadFile(g.fileSystem, sourcesFilePath)
179177
if err != nil {
@@ -200,7 +198,7 @@ func (g *FedoraSourceDownloaderImpl) extractSourcesInfo(
200198
fileName := matches[sourcesPatternFilenameIndex]
201199
hash := matches[sourcesPatternHashValueIndex]
202200

203-
sourceURI := g.lookasideBaseURI
201+
sourceURI := lookasideBaseURI
204202
sourceURI = strings.ReplaceAll(sourceURI, "$pkg", packageName)
205203
sourceURI = strings.ReplaceAll(sourceURI, "$filename", fileName)
206204
sourceURI = strings.ReplaceAll(sourceURI, "$hashtype", strings.ToLower(hashType))

internal/providers/sourceproviders/fedorasource/fedorasource_test.go

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestNewFedoraRepoExtractorImpl(t *testing.T) {
5555
ctx := testctx.NewCtx()
5656
mockDownloader := downloader_test.NewMockDownloader(ctrl)
5757

58-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
58+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
5959

6060
require.NoError(t, err)
6161
require.NotNil(t, extractor)
@@ -67,27 +67,17 @@ func TestNewFedoraRepoExtractorImplValidation(t *testing.T) {
6767
mockDownloader := downloader_test.NewMockDownloader(ctrl)
6868

6969
t.Run("nil dryRunnable should fail", func(t *testing.T) {
70-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(nil, ctx.FS(), mockDownloader, testLookasideURI)
70+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(nil, ctx.FS(), mockDownloader)
7171
require.Error(t, err)
7272
require.Nil(t, extractor)
7373
})
7474
t.Run("nil filesystem should fail", func(t *testing.T) {
75-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, nil, mockDownloader, testLookasideURI)
75+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, nil, mockDownloader)
7676
require.Error(t, err)
7777
require.Nil(t, extractor)
7878
})
7979
t.Run("nil downloader should fail", func(t *testing.T) {
80-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), nil, testLookasideURI)
81-
require.Error(t, err)
82-
require.Nil(t, extractor)
83-
})
84-
t.Run("empty lookaside URI should fail", func(t *testing.T) {
85-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, "")
86-
require.Error(t, err)
87-
require.Nil(t, extractor)
88-
})
89-
t.Run("lookaside URI missing placeholders should fail", func(t *testing.T) {
90-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, "missing-placeholders")
80+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), nil)
9181
require.Error(t, err)
9282
require.Nil(t, extractor)
9383
})
@@ -98,7 +88,7 @@ func TestExtractSourcesFromRepo(t *testing.T) {
9888
ctx := testctx.NewCtx()
9989
mockDownloader := downloader_test.NewMockDownloader(ctrl)
10090

101-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
91+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
10292
require.NoError(t, err)
10393

10494
require.NoError(t, ctx.FS().MkdirAll(testRepoDir, testDirPerms))
@@ -123,7 +113,7 @@ func TestExtractSourcesFromRepo(t *testing.T) {
123113
return afero.WriteFile(ctx.FS(), destPath, []byte("test patch content"), testFilePerms)
124114
})
125115

126-
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName)
116+
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName, testLookasideURI)
127117
require.NoError(t, err)
128118
}
129119

@@ -132,19 +122,31 @@ func TestExtractSourcesFromRepoValidation(t *testing.T) {
132122
ctx := testctx.NewCtx()
133123
mockDownloader := downloader_test.NewMockDownloader(ctrl)
134124

135-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
125+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
136126
require.NoError(t, err)
137127

138128
t.Run("empty repo dir", func(t *testing.T) {
139-
err := extractor.ExtractSourcesFromRepo(context.Background(), "", testPackageName)
129+
err := extractor.ExtractSourcesFromRepo(context.Background(), "", testPackageName, testLookasideURI)
140130
require.Error(t, err)
141131
assert.Contains(t, err.Error(), "repository directory cannot be empty")
142132
})
143133

134+
t.Run("empty lookaside URI", func(t *testing.T) {
135+
err := extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName, "")
136+
require.Error(t, err)
137+
assert.Contains(t, err.Error(), "lookaside base URI cannot be empty")
138+
})
139+
140+
t.Run("lookaside URI missing placeholders", func(t *testing.T) {
141+
err := extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName, "missing-placeholders")
142+
require.Error(t, err)
143+
assert.Contains(t, err.Error(), "lookaside base URI is missing required placeholder")
144+
})
145+
144146
t.Run("missing sources file", func(t *testing.T) {
145147
require.NoError(t, ctx.FS().MkdirAll(testEmptyRepoDir, 0o755))
146148

147-
err := extractor.ExtractSourcesFromRepo(context.Background(), testEmptyRepoDir, testPackageName)
149+
err := extractor.ExtractSourcesFromRepo(context.Background(), testEmptyRepoDir, testPackageName, testLookasideURI)
148150
require.Error(t, err)
149151
assert.Contains(t, err.Error(), "failed to read sources file")
150152
})
@@ -155,13 +157,13 @@ func TestExtractSourcesFromRepoInvalidFormats(t *testing.T) {
155157
ctx := testctx.NewCtx()
156158
mockDownloader := downloader_test.NewMockDownloader(ctrl)
157159

158-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
160+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
159161
require.NoError(t, err)
160162

161163
require.NoError(t, ctx.FS().MkdirAll(testInvalidDir, testDirPerms))
162164
setupSourcesFile(t, ctx.FS(), testInvalidDir, testInvalidSourcesContent)
163165

164-
err = extractor.ExtractSourcesFromRepo(context.Background(), testInvalidDir, testPackageName)
166+
err = extractor.ExtractSourcesFromRepo(context.Background(), testInvalidDir, testPackageName, testLookasideURI)
165167
require.Error(t, err)
166168
assert.Contains(t, err.Error(), "invalid format in sources file at line")
167169
}
@@ -171,7 +173,7 @@ func TestExtractSourcesFromRepoDownloadFailure(t *testing.T) {
171173
ctx := testctx.NewCtx()
172174
mockDownloader := downloader_test.NewMockDownloader(ctrl)
173175

174-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
176+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
175177
require.NoError(t, err)
176178

177179
require.NoError(t, ctx.FS().MkdirAll(testRepoDir, testDirPerms))
@@ -181,7 +183,7 @@ func TestExtractSourcesFromRepoDownloadFailure(t *testing.T) {
181183
mockDownloader.EXPECT().Download(gomock.Any(), gomock.Any(), gomock.Any()).
182184
Return(downloadErr)
183185

184-
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName)
186+
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName, testLookasideURI)
185187
require.Error(t, err)
186188
require.ErrorIs(t, err, downloadErr)
187189
assert.Contains(t, err.Error(), "failed to download sources")
@@ -192,7 +194,7 @@ func TestExtractSourcesFromRepoHashMismatch(t *testing.T) {
192194
ctx := testctx.NewCtx()
193195
mockDownloader := downloader_test.NewMockDownloader(ctrl)
194196

195-
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader, testLookasideURI)
197+
extractor, err := fedorasource.NewFedoraRepoExtractorImpl(ctx, ctx.FS(), mockDownloader)
196198
require.NoError(t, err)
197199

198200
require.NoError(t, ctx.FS().MkdirAll(testRepoDir, testDirPerms))
@@ -205,7 +207,7 @@ func TestExtractSourcesFromRepoHashMismatch(t *testing.T) {
205207
return afero.WriteFile(ctx.FS(), destPath, []byte("wrong content"), testFilePerms)
206208
})
207209

208-
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName)
210+
err = extractor.ExtractSourcesFromRepo(context.Background(), testRepoDir, testPackageName, testLookasideURI)
209211
require.Error(t, err)
210212
assert.Contains(t, err.Error(), "hash mismatch")
211213
}

internal/providers/sourceproviders/fedorasource/fedorasource_test/fedorasource_mocks.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)