Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/druid/adapters/cli/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var pushScrollPorts []string
var pushPackMeta bool
var pushSmart bool
var pushCategory string
var pushDisableTarReproducible bool

var PushCommand = &cobra.Command{
Use: "push [artifact] [dir]",
Expand Down Expand Up @@ -62,6 +63,9 @@ var PushCommand = &cobra.Command{
logger.Log().Info("Pushing "+repo+":"+tag+" to registry", zap.String("path", fullPath))

ociClient := registry.NewOciClient(credStore)
if pushDisableTarReproducible {
ociClient.DisableTarReproducible()
}

overrides := map[string]string{}
if pushMinRAM != "" {
Expand Down Expand Up @@ -112,4 +116,5 @@ func init() {
PushCommand.Flags().StringVarP(&pushImage, "image", "i", pushImage, "Image to use for the scroll. (Will be added as a manifest annotation gg.druid.scroll.image)")
PushCommand.Flags().StringSliceVarP(&pushScrollPorts, "port", "p", pushScrollPorts, "Ports to expose. Format webserver=80, dns=53/udp or just ftp (Will be added as a manifest annotation gg.druid.scroll.ports.<name>)")
PushCommand.Flags().BoolVarP(&pushPackMeta, "pack-meta", "m", pushPackMeta, "Pack the meta folder into the scroll.")
PushCommand.PersistentFlags().BoolVar(&pushDisableTarReproducible, "no-tar-reproducible", false, "Preserve file timestamps in pushed tar layers.")
}
3 changes: 3 additions & 0 deletions apps/druid/adapters/cli/push_category.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ var PushCategoryCommand = &cobra.Command{
logger.Log().Info("Pushing "+repo+" category to registry", zap.String("scrollDir", scrollDir))

ociClient := registry.NewOciClient(credStore)
if pushDisableTarReproducible {
ociClient.DisableTarReproducible()
}

_, err := ociClient.PushCategory(scrollDir, repo, category)

Expand Down
20 changes: 18 additions & 2 deletions internal/core/services/registry/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type OciClient struct {
httpClient *http.Client
// plainHTTP forces plain HTTP (no TLS) for registry communication.
plainHTTP bool
// disableTarReproducible opts out of reproducible tar layers for pushes.
disableTarReproducible bool
}

func NewOciClient(credentialStore *CredentialStore) *OciClient {
Expand All @@ -54,6 +56,20 @@ func plainHTTPFromEnv() bool {
return value == "1" || value == "true" || value == "yes"
}

// DisableTarReproducible preserves source file timestamps in pushed tar layers.
func (c *OciClient) DisableTarReproducible() {
c.disableTarReproducible = true
}

func (c *OciClient) newFileStore(root string) (*file.Store, error) {
fs, err := file.New(root)
if err != nil {
return nil, err
}
fs.TarReproducible = !c.disableTarReproducible
return fs, nil
}

func (c *OciClient) GetRepo(repoUrl string) (*remote.Repository, error) {
repo, err := remote.NewRepository(repoUrl)
if err != nil {
Expand Down Expand Up @@ -762,7 +778,7 @@ func (c *OciClient) Push(folder string, repo string, tag string, overrides map[s
return v1.Descriptor{}, fmt.Errorf("no files found to push")
}

fs, err := file.New(folder)
fs, err := c.newFileStore(folder)
if err != nil {
return v1.Descriptor{}, err
}
Expand Down Expand Up @@ -888,7 +904,7 @@ func (c *OciClient) PushCategory(dir string, repo string, category string) (v1.D
return v1.Descriptor{}, err
}

fs, err := file.New(dir)
fs, err := c.newFileStore(dir)
if err != nil {
return v1.Descriptor{}, err
}
Expand Down
25 changes: 25 additions & 0 deletions internal/core/services/registry/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,31 @@ func TestValidateCredentialsUsesPlainHTTPEnv(t *testing.T) {
}
}

func TestNewFileStoreUsesReproducibleTarsByDefault(t *testing.T) {
client := NewOciClient(NewCredentialStore(nil))
store, err := client.newFileStore(t.TempDir())
if err != nil {
t.Fatal(err)
}
defer store.Close()
if !store.TarReproducible {
t.Fatal("TarReproducible = false, want true")
}
}

func TestDisableTarReproducible(t *testing.T) {
client := NewOciClient(NewCredentialStore(nil))
client.DisableTarReproducible()
store, err := client.newFileStore(t.TempDir())
if err != nil {
t.Fatal(err)
}
defer store.Close()
if store.TarReproducible {
t.Fatal("TarReproducible = true, want false")
}
}

// TestPushDataChunkPathNotDoubled calls OciClient.Push directly with a
// relative scroll folder containing a data directory, pushing to a fake
// in-process OCI registry. This verifies the data-chunk file paths are
Expand Down
Loading