Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TEMPORARY: use a different repository for source catalogs
- Loading branch information
Showing
4 changed files
with
220 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package main | ||
|
||
import ( | ||
"archive/tar" | ||
"bytes" | ||
"context" | ||
"crypto/tls" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
|
||
"github.com/google/go-containerregistry/pkg/authn" | ||
"github.com/google/go-containerregistry/pkg/crane" | ||
v1 "github.com/google/go-containerregistry/pkg/v1" | ||
"github.com/google/go-containerregistry/pkg/v1/mutate" | ||
) | ||
|
||
const ( | ||
opmCachePrefix = "/tmp/cache" | ||
opmBinarySuffix = "opm" | ||
opmBinaryDir = "usr/bin/registry" | ||
configsDir = "/configs" //taking a shortcut, this should come from a label normally | ||
) | ||
|
||
func createRT(insecure bool) http.RoundTripper { | ||
return &http.Transport{ | ||
Proxy: http.ProxyFromEnvironment, | ||
DialContext: (&net.Dialer{ | ||
// By default, we wrap the transport in retries, so reduce the | ||
// default dial timeout to 5s to avoid 5x 30s of connection | ||
// timeouts when doing the "ping" on certain http registries. | ||
Timeout: 5 * time.Second, | ||
KeepAlive: 30 * time.Second, | ||
}).DialContext, | ||
ForceAttemptHTTP2: true, | ||
MaxIdleConns: 100, | ||
IdleConnTimeout: 90 * time.Second, | ||
TLSHandshakeTimeout: 10 * time.Second, | ||
ExpectContinueTimeout: 1 * time.Second, | ||
TLSClientConfig: &tls.Config{ | ||
InsecureSkipVerify: insecure, | ||
MinVersion: tls.VersionTLS12, | ||
}, | ||
} | ||
} | ||
|
||
func getCraneOpts(ctx context.Context, insecure bool) []crane.Option { | ||
opts := []crane.Option{ | ||
crane.WithAuthFromKeychain(authn.DefaultKeychain), | ||
crane.WithTransport(createRT(insecure)), | ||
crane.WithContext(ctx), | ||
} | ||
if insecure { | ||
opts = append(opts, crane.Insecure) | ||
} | ||
return opts | ||
} | ||
|
||
func extractResource(img v1.Image, resource string, outDir string) error { | ||
tr := tar.NewReader(mutate.Extract(img)) | ||
|
||
resourceExtracted := "" | ||
for { | ||
header, err := tr.Next() | ||
|
||
// break the infinite loop when EOF | ||
if errors.Is(err, io.EOF) { | ||
break | ||
} | ||
|
||
// skip the file if it is a directory or doesn't correspond to the resource | ||
if resource == opmBinarySuffix { | ||
if !strings.HasSuffix(header.Name, resource) || header.FileInfo().IsDir() { | ||
continue | ||
} | ||
} else { | ||
if !strings.HasPrefix(header.Name, resource) || header.FileInfo().IsDir() { | ||
continue | ||
} | ||
} | ||
|
||
var buf bytes.Buffer | ||
_, err = buf.ReadFrom(tr) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
targetFileName := filepath.Join(outDir, header.Name) | ||
bytes := buf.Bytes() | ||
|
||
baseDir := filepath.Dir(targetFileName) | ||
err = os.MkdirAll(baseDir, 0755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
f, err := os.Create(targetFileName) | ||
if err == nil { | ||
defer f.Close() | ||
} else { | ||
return err | ||
} | ||
|
||
_, err = f.Write(bytes) | ||
if err != nil { | ||
return err | ||
} | ||
resourceExtracted = targetFileName | ||
} | ||
// check for the folder (it should exist if we found something) | ||
_, err := os.Stat(resourceExtracted) | ||
if errors.Is(err, os.ErrNotExist) { | ||
return fmt.Errorf("unable to extract %q", resourceExtracted) | ||
} | ||
return nil | ||
} | ||
|
||
func main() { | ||
argsWithoutProg := os.Args[1:] | ||
var img v1.Image | ||
var err error | ||
|
||
remoteOpts := getCraneOpts(context.TODO(), true) | ||
img, err = crane.Pull(argsWithoutProg[0], remoteOpts...) | ||
if err != nil { | ||
fmt.Printf("unable to pull image from %s: %v", argsWithoutProg[0], err) | ||
} | ||
|
||
// if we get here and no image was found bail out | ||
if img == nil { | ||
fmt.Printf("unable to obtain image for %v", argsWithoutProg[0]) | ||
} | ||
err = extractResource(img, opmBinarySuffix, argsWithoutProg[1]) | ||
if err != nil { | ||
fmt.Printf("%v", err) | ||
} | ||
err = extractResource(img, opmCachePrefix, argsWithoutProg[1]) | ||
if err != nil { | ||
fmt.Printf("%v", err) | ||
} | ||
err = extractResource(img, configsDir, argsWithoutProg[1]) | ||
if err != nil { | ||
fmt.Printf("%v", err) | ||
} | ||
err = extractResource(img, opmCachePrefix, argsWithoutProg[1]) | ||
if err != nil { | ||
fmt.Printf("%v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.