Skip to content

Commit

Permalink
cmd/oci-cas: Add tar and zip support for file URIs
Browse files Browse the repository at this point in the history
This lets us extract blobs from layout archives.  For example:

  $ cat cas-engines.json
  [
    {
      "config": {
        "protocol": "oci-cas-template-v1",
        "uri": "blobs/{algorithm}/{encoded}"
      },
      "uri": "file:///"
    }
  ]
  $ unzip -l hello-world.zip
  Archive:  hello-world.zip
    Length      Date    Time    Name
  ---------  ---------- -----   ----
          0  10-14-2017 16:34   blobs/
          0  10-14-2017 16:34   blobs/sha256/
         14  10-14-2017 16:34   blobs/sha256/c98c24b677eff44860afea6f493bbaec5bb1c4cbb209c6fc2bbb47f66ff2ad31
  ---------                     -------
         14                     3 files
  $ oci-cas --zip-file hello-world.zip sha256:c98c24b677eff44860afea6f493bbaec5bb1c4cbb209c6fc2bbb47f66ff2ad31 <cas-engines.json
  Hello, World!

The tar implementation doesn't quite work:

  $ tar -tf hello-world.tar
  ./
  ./blobs/
  ./blobs/sha256/
  ./blobs/sha256/c98c24b677eff44860afea6f493bbaec5bb1c4cbb209c6fc2bbb47f66ff2ad31
  $ ./oci-cas --tar-file hello-world.tar sha256:c98c24b677eff44860afea6f493bbaec5bb1c4cbb209c6fc2bbb47f66ff2ad31 <cas-engines.json
  FATA[0000] failed to retrieve sha256:c98c24b677eff44860afea6f493bbaec5bb1c4cbb209c6fc2bbb47f66ff2ad31

I think omeid/go-tarfs needs some love.

Signed-off-by: W. Trevor King <wking@tremily.us>
  • Loading branch information
wking committed Oct 14, 2017
1 parent 098f4eb commit 252e064
Showing 1 changed file with 54 additions and 1 deletion.
55 changes: 54 additions & 1 deletion cmd/oci-cas/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package main

import (
"archive/zip"
_ "crypto/sha256"
_ "crypto/sha512"
"encoding/json"
Expand All @@ -24,13 +25,16 @@ import (
"net/http"
"os"

"github.com/omeid/go-tarfs"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/wking/casengine"
_ "github.com/wking/casengine/template"
"github.com/xiekeyang/oci-discovery/tools/engine"
"golang.org/x/net/context"
"golang.org/x/tools/godoc/vfs/httpfs"
"golang.org/x/tools/godoc/vfs/zipfs"
)

func main() {
Expand All @@ -48,7 +52,15 @@ func main() {
},
cli.StringFlag{
Name: "file",
Usage: "Effective root for file URIs. To allow access to your entire filesystem, use '--file /'. More restricted values are recommended to avoid accessing sensitive information. The default is to disable file URIs entirely; you must set this flag to enable them.",
Usage: "Effective root for file URIs. To allow access to your entire filesystem, use '--file /'. More restricted values are recommended to avoid accessing sensitive information. The default is to disable file URIs entirely; you must set this flag (or another --*-file flag) to enable them.",
},
cli.StringFlag{
Name: "tar-file",
Usage: "Effective root for file URIs in a tape archive file (tarball). As an alternative to --file, use the tape archive at this path as the root of the file URI filesystem.",
},
cli.StringFlag{
Name: "zip-file",
Usage: "Effective root for file URIs in a zip archive file. As an alternative to --file, use the zip archive at this path as the root of the file URI filesystem.",
},
}

Expand All @@ -67,11 +79,52 @@ func main() {
ctx := context.Background()

if c.GlobalIsSet("file") {
if c.GlobalIsSet("tar-file") {
return fmt.Errorf("setting both --file and --tar-file is invalid")
}
if c.GlobalIsSet("zip-file") {
return fmt.Errorf("setting both --file and --zip-file is invalid")
}
path := c.GlobalString("file")
transport := http.NewFileTransport(http.Dir(path))
http.DefaultTransport.(*http.Transport).RegisterProtocol("file", transport)
}

if c.GlobalIsSet("tar-file") {
if c.GlobalIsSet("zip-file") {
return fmt.Errorf("setting both --tar-file and --zip-file is invalid")
}
path := c.GlobalString("tar-file")
reader, err := os.Open(path)
if err != nil {
return err
}
tarFS, err := tarfs.New(reader)
if err != nil {
err2 := reader.Close()
if err2 != nil {
logrus.Warn("failed to close the tar reader")
}
return err
}
err = reader.Close()
if err != nil {
return err
}
transport := http.NewFileTransport(tarFS)
http.DefaultTransport.(*http.Transport).RegisterProtocol("file", transport)
}

if c.GlobalIsSet("zip-file") {
path := c.GlobalString("zip-file")
reader, err := zip.OpenReader(path)
if err != nil {
return err
}
transport := http.NewFileTransport(httpfs.New(zipfs.New(reader, path)))
http.DefaultTransport.(*http.Transport).RegisterProtocol("file", transport)
}

var configReferences []engine.Reference
err = json.NewDecoder(os.Stdin).Decode(&configReferences)
if err != nil {
Expand Down

0 comments on commit 252e064

Please sign in to comment.