Skip to content

Commit 2bdcd07

Browse files
Merge pull request #283 from ecordell/index-separate-dirs
Bug 1825925: support deamonless export
2 parents a25687c + a022e61 commit 2bdcd07

File tree

9 files changed

+286
-144
lines changed

9 files changed

+286
-144
lines changed

cmd/opm/index/export.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package index
22

33
import (
4-
"fmt"
54
"github.com/sirupsen/logrus"
65
"github.com/spf13/cobra"
76
"k8s.io/kubectl/pkg/util/templates"
@@ -46,7 +45,7 @@ func newIndexExportCmd() *cobra.Command {
4645
logrus.Panic("Failed to set required `package` flag for `index export`")
4746
}
4847
indexCmd.Flags().StringP("download-folder", "f", "downloaded", "directory where downloaded operator bundle(s) will be stored")
49-
indexCmd.Flags().StringP("container-tool", "c", "podman", "tool to interact with container images (save, build, etc.). One of: [none, docker, podman]")
48+
indexCmd.Flags().StringP("container-tool", "c", "none", "tool to interact with container images (save, build, etc.). One of: [none, docker, podman]")
5049
if err := indexCmd.Flags().MarkHidden("debug"); err != nil {
5150
logrus.Panic(err.Error())
5251
}
@@ -76,21 +75,17 @@ func runIndexExportCmdFunc(cmd *cobra.Command, args []string) error {
7675
return err
7776
}
7877

79-
if containerTool == "none" {
80-
return fmt.Errorf("none is not a valid container-tool for index add")
81-
}
82-
8378
logger := logrus.WithFields(logrus.Fields{"index": index, "package": packageName})
8479

8580
logger.Info("export from the index")
8681

87-
indexExporter := indexer.NewIndexExporter(containertools.NewContainerTool(containerTool, containertools.PodmanTool), logger)
82+
indexExporter := indexer.NewIndexExporter(containertools.NewContainerTool(containerTool, containertools.NoneTool), logger)
8883

8984
request := indexer.ExportFromIndexRequest{
9085
Index: index,
9186
Package: packageName,
9287
DownloadPath: downloadPath,
93-
ContainerTool: containerTool,
88+
ContainerTool: containertools.NewContainerTool(containerTool, containertools.NoneTool),
9489
}
9590

9691
err = indexExporter.ExportFromIndex(request)

pkg/containertools/dockerfilegenerator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func NewDockerfileGenerator(logger *logrus.Entry) DockerfileGenerator {
3232

3333
// GenerateIndexDockerfile builds a string representation of a dockerfile to use when building
3434
// an operator-registry index image
35-
func (g *IndexDockerfileGenerator) GenerateIndexDockerfile(binarySourceImage, databaseFolder string) string {
35+
func (g *IndexDockerfileGenerator) GenerateIndexDockerfile(binarySourceImage, databasePath string) string {
3636
var dockerfile string
3737

3838
if binarySourceImage == "" {
@@ -48,7 +48,7 @@ func (g *IndexDockerfileGenerator) GenerateIndexDockerfile(binarySourceImage, da
4848
dockerfile += fmt.Sprintf("LABEL %s=%s\n", DbLocationLabel, DefaultDbLocation)
4949

5050
// Content
51-
dockerfile += fmt.Sprintf("ADD %s/index.db %s\n", databaseFolder, DefaultDbLocation)
51+
dockerfile += fmt.Sprintf("ADD %s %s\n", databasePath, DefaultDbLocation)
5252
dockerfile += fmt.Sprintf("EXPOSE 50051\n")
5353
dockerfile += fmt.Sprintf("ENTRYPOINT [\"/bin/opm\"]\n")
5454
dockerfile += fmt.Sprintf("CMD [\"registry\", \"serve\", \"--database\", \"%s\"]\n", DefaultDbLocation)

pkg/containertools/dockerfilegenerator_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func TestGenerateDockerfile(t *testing.T) {
1515
defer controller.Finish()
1616

1717
binarySourceImage := "quay.io/operator-framework/builder"
18-
databaseFolder := "database"
18+
databasePath := "database/index.db"
1919
expectedDockerfile := `FROM quay.io/operator-framework/builder
2020
LABEL operators.operatorframework.io.index.database.v1=/database/index.db
2121
ADD database/index.db /database/index.db
@@ -30,15 +30,15 @@ CMD ["registry", "serve", "--database", "/database/index.db"]
3030
Logger: logger,
3131
}
3232

33-
dockerfile := dockerfileGenerator.GenerateIndexDockerfile(binarySourceImage, databaseFolder)
33+
dockerfile := dockerfileGenerator.GenerateIndexDockerfile(binarySourceImage, databasePath)
3434
require.Equal(t, dockerfile, expectedDockerfile)
3535
}
3636

3737
func TestGenerateDockerfile_EmptyBaseImage(t *testing.T) {
3838
controller := gomock.NewController(t)
3939
defer controller.Finish()
4040

41-
databaseFolder := "database"
41+
databasePath := "database/index.db"
4242
expectedDockerfile := `FROM quay.io/operator-framework/upstream-registry-builder
4343
LABEL operators.operatorframework.io.index.database.v1=/database/index.db
4444
ADD database/index.db /database/index.db
@@ -53,6 +53,6 @@ CMD ["registry", "serve", "--database", "/database/index.db"]
5353
Logger: logger,
5454
}
5555

56-
dockerfile := dockerfileGenerator.GenerateIndexDockerfile("", databaseFolder)
56+
dockerfile := dockerfileGenerator.GenerateIndexDockerfile("", databasePath)
5757
require.Equal(t, dockerfile, expectedDockerfile)
5858
}

pkg/image/containerdregistry/registry.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package containerdregistry
22

33
import (
44
"archive/tar"
5+
"bytes"
56
"context"
7+
"encoding/json"
68
"fmt"
79
"github.com/containerd/containerd/archive"
810
"github.com/containerd/containerd/archive/compression"
@@ -14,6 +16,7 @@ import (
1416
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1517
"github.com/sirupsen/logrus"
1618
"io"
19+
"io/ioutil"
1720
"os"
1821

1922
"github.com/operator-framework/operator-registry/pkg/image"
@@ -93,6 +96,52 @@ func (r *Registry) Unpack(ctx context.Context, ref image.Reference, dir string)
9396
return nil
9497
}
9598

99+
// Labels gets the labels for an image reference.
100+
func (r *Registry) Labels(ctx context.Context, ref image.Reference) (map[string]string, error) {
101+
// Set the default namespace if unset
102+
ctx = ensureNamespace(ctx)
103+
tmpDir, err := ioutil.TempDir("./", "bundle_tmp")
104+
if err != nil {
105+
return nil, err
106+
}
107+
defer os.RemoveAll(tmpDir)
108+
109+
img, err := r.Images().Get(ctx, ref.String())
110+
if err != nil {
111+
return nil, err
112+
}
113+
114+
manifest, err := images.Manifest(ctx, r.Content(), img.Target, r.platform)
115+
if err != nil {
116+
return nil, err
117+
}
118+
119+
ra, err := r.Content().ReaderAt(ctx, manifest.Config)
120+
if err != nil {
121+
return nil, err
122+
}
123+
defer ra.Close()
124+
125+
decompressed, err := compression.DecompressStream(io.NewSectionReader(ra, 0, ra.Size()))
126+
if err != nil {
127+
return nil, err
128+
}
129+
var buf bytes.Buffer
130+
if _, err := io.Copy(&buf, decompressed); err != nil {
131+
return nil, err
132+
}
133+
r.log.Warn(buf.String())
134+
135+
var imageConfig ocispec.Image
136+
137+
if err := json.Unmarshal(buf.Bytes(), &imageConfig); err != nil {
138+
return nil, err
139+
}
140+
141+
return imageConfig.Config.Labels, nil
142+
}
143+
144+
96145
// Destroy cleans up the on-disk boltdb file and other cache files, unless preserve cache is true
97146
func (r *Registry) Destroy() (err error) {
98147
return r.destroy()

pkg/image/execregistry/registry.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ func (r *Registry) Unpack(ctx context.Context, ref image.Reference, dir string)
3838
}.GetImageData(ref.String(), dir)
3939
}
4040

41+
// Labels gets the labels for an image reference.
42+
func (r *Registry) Labels(ctx context.Context, ref image.Reference) (map[string]string, error) {
43+
return containertools.ImageLabelReader{
44+
Cmd: r.cmd,
45+
Logger: r.log,
46+
}.GetLabelsFromImage(ref.String())
47+
}
48+
4149
// Destroy is no-op for exec tools
4250
func (r *Registry) Destroy() error {
4351
return nil

pkg/image/registry.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ type Registry interface {
1818
// If the referenced image does not exist in the registry, an error is returned.
1919
Unpack(ctx context.Context, ref Reference, dir string) error
2020

21+
// Labels gets the labels for an image that is already stored.
22+
Labels(ctx context.Context, ref Reference) (map[string]string, error)
23+
2124
// Destroy cleans up any on-disk resources used to track images
2225
Destroy() error
2326

@@ -26,3 +29,4 @@ type Registry interface {
2629
// If it exists, it's used as the base image.
2730
// Pack(ctx context.Context, ref Reference, from io.Reader) (next string, err error)
2831
}
32+

pkg/lib/bundle/exporter.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package bundle
22

33
import (
4+
"context"
5+
"github.com/operator-framework/operator-registry/pkg/image"
6+
"github.com/operator-framework/operator-registry/pkg/image/execregistry"
47
"io/ioutil"
58
"os"
69
"path/filepath"
@@ -9,6 +12,7 @@ import (
912
"github.com/sirupsen/logrus"
1013

1114
"github.com/operator-framework/operator-registry/pkg/containertools"
15+
"github.com/operator-framework/operator-registry/pkg/image/containerdregistry"
1216
)
1317

1418
// BundleExporter exports the manifests of a bundle image into a directory
@@ -18,11 +22,11 @@ type BundleExporter struct {
1822
containerTool containertools.ContainerTool
1923
}
2024

21-
func NewSQLExporterForBundle(image, directory, containerTool string) *BundleExporter {
25+
func NewSQLExporterForBundle(image, directory string, containerTool containertools.ContainerTool) *BundleExporter {
2226
return &BundleExporter{
2327
image: image,
2428
directory: directory,
25-
containerTool: containertools.NewContainerTool(containerTool, containertools.NoneTool),
29+
containerTool: containerTool,
2630
}
2731
}
2832

@@ -36,13 +40,33 @@ func (i *BundleExporter) Export() error {
3640
}
3741
defer os.RemoveAll(tmpDir)
3842

39-
// Pull the image and get the manifests
40-
reader := containertools.NewImageReader(i.containerTool, log)
43+
var reg image.Registry
44+
var rerr error
45+
switch i.containerTool {
46+
case containertools.NoneTool:
47+
reg, rerr = containerdregistry.NewRegistry(containerdregistry.WithLog(log))
48+
case containertools.PodmanTool:
49+
fallthrough
50+
case containertools.DockerTool:
51+
reg, rerr = execregistry.NewRegistry(i.containerTool, log)
52+
}
53+
if rerr != nil {
54+
return rerr
55+
}
56+
defer func() {
57+
if err := reg.Destroy(); err != nil {
58+
log.WithError(err).Warn("error destroying local cache")
59+
}
60+
}()
4161

42-
err = reader.GetImageData(i.image, tmpDir)
43-
if err != nil {
62+
if err := reg.Pull(context.TODO(), image.SimpleReference(i.image)); err != nil {
4463
return err
4564
}
65+
66+
if err := reg.Unpack(context.TODO(), image.SimpleReference(i.image), tmpDir); err != nil {
67+
return err
68+
}
69+
4670
if err := os.MkdirAll(i.directory, 0777); err != nil {
4771
return err
4872
}

0 commit comments

Comments
 (0)