Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-16801: fix: fixes the bug on catalog when using field archiveSize: 1 #773

Merged
merged 1 commit into from Jan 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 88 additions & 6 deletions pkg/cli/mirror/publish.go
@@ -1,20 +1,23 @@
package mirror

import (
"archive/tar"
"context"
"errors"
"fmt"
"io"
"os"
"path"
"path/filepath"
"strings"

"github.com/opencontainers/go-digest"
"github.com/openshift/library-go/pkg/image/reference"
"github.com/openshift/library-go/pkg/image/registryclient"
"github.com/openshift/oc/pkg/cli/image/imagesource"
imagemanifest "github.com/openshift/oc/pkg/cli/image/manifest"
imgmirror "github.com/openshift/oc/pkg/cli/image/mirror"
"golang.org/x/exp/slices"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/klog/v2"

Expand Down Expand Up @@ -452,16 +455,95 @@ func (o *MirrorOptions) fetchBlob(ctx context.Context, regctx *registryclient.Co
}

func unpack(archiveFilePath, dest string, filesInArchive map[string]string) error {
archivePath, found := filesInArchive[archiveFilePath]
if !found {
archivePaths := getArchivePathsFromMap(filesInArchive, archiveFilePath)

if len(archivePaths) == 0 {
return &ErrArchiveFileNotFound{archiveFilePath}
}
if err := archive.NewArchiver().Extract(archivePath, archiveFilePath, dest); err != nil {
return err

for _, archivePath := range archivePaths {
if archiveFilePath == config.CatalogsDir {
err := unarchive(archivePath, dest)
if err != nil {
klog.V(2).Info("unarchive failed with the error: %s", err.Error())
return err
}
} else {
if err := archive.NewArchiver().Extract(archivePath, archiveFilePath, dest); err != nil {
return err
}
if _, err := os.Stat(filepath.Join(dest, archiveFilePath)); err != nil {
return err
}
}
}
if _, err := os.Stat(filepath.Join(dest, archiveFilePath)); err != nil {
return err

return nil
}

func getArchivePathsFromMap(m map[string]string, key string) []string {
var archivePaths []string
for k, v := range m {
if strings.Contains(k, key) {
if slices.Contains(archivePaths, v) {
continue
}
archivePaths = append(archivePaths, v)
}
}
return archivePaths
}

func unarchive(archivePath, dest string) error {
aguidirh marked this conversation as resolved.
Show resolved Hide resolved
file, err := os.Open(archivePath)
if err != nil {
return fmt.Errorf("error opening tar %s: %v", archivePath, err)
}
reader := tar.NewReader(file)
for {
header, err := reader.Next()

// break the infinite loop when EOF
if errors.Is(err, io.EOF) {
break
}

if err != nil {
return fmt.Errorf("error reading archive %s: %v", archivePath, err)
}

if header == nil {
continue
}
if header.Typeflag == tar.TypeReg {
if strings.HasPrefix(header.Name, config.CatalogsDir) {
fmt.Println(header.Name)
fpath := filepath.Join(dest, header.Name)

err := os.MkdirAll(filepath.Dir(fpath), 0755)
if err != nil {
return fmt.Errorf("%s: making directory for file: %v", fpath, err)
}

out, err := os.Create(fpath)
if err != nil {
return fmt.Errorf("%s: creating new file: %v", fpath, err)
}
defer out.Close()

err = out.Chmod(os.FileMode(header.Mode))
if err != nil {
return fmt.Errorf("%s: changing file mode: %v", fpath, err)
}

_, err = io.Copy(out, reader)
if err != nil {
return fmt.Errorf("%s: writing file: %v", fpath, err)
}
}
}
}

return nil
}

Expand Down