Skip to content

Commit

Permalink
Add Windows support - Fix tests, enable CI, and release Windows binar…
Browse files Browse the repository at this point in the history
…ies (#780)

* Allow Travis-CI to be run on a forked repo

* Enable Windows tests on Travis-CI

* Fix invalid cache filenames on Windows

* Fix incorrect path separators on Windows in layout tests

* Enable registry test shell script to run on Windows (Docker+Linux containers only)

* Add Windows x64 build for releases (#778)

* Fix tarball tests fail to clean up due to unclosed ReadClosers on Windows
  • Loading branch information
mterrel committed Oct 27, 2020
1 parent 919148f commit 0d898ee
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 16 deletions.
16 changes: 16 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,27 @@ builds:
- CGO_ENABLED=0
main: ./cmd/crane/main.go
binary: crane
goos:
- linux
- darwin
- windows
ignore:
- goos: windows
goarch: 386

- id: gcrane
env:
- CGO_ENABLED=0
main: ./cmd/gcrane/main.go
binary: gcrane
goos:
- linux
- darwin
- windows
ignore:
- goos: windows
goarch: 386

archives:
- replacements:
darwin: Darwin
Expand Down
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,25 @@ env:
- "GO111MODULE=off"
- "GO111MODULE=on"

os:
- windows
- linux

# Don't run all combos on Windows
jobs:
exclude:
- os: windows
go: "1.14"
- os: windows
go: "1.15"
env: "GO111MODULE=off"


git:
depth: 1
autocrlf: input

go_import_path: github.com/google/go-containerregistry

cache:
directories:
Expand Down
46 changes: 38 additions & 8 deletions cmd/registry/test.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
#!/bin/bash
set -ev
set -ex

CONTAINER_OS=$(docker info -f '{{ .OSType }}')

# crane can run on a Windows system, but doesn't currently support pulling Windows
# containers, so this test can only run if Docker is in Linux container mode.
if [[ ${CONTAINER_OS} = "windows" ]]; then
set +x
echo [TEST SKIPPED] Windows containers are not yet supported by crane
exit
fi

function cleanup {
[[ -n $PID ]] && kill $PID
[[ -n $CTR ]] && docker stop $CTR
rm -f ubuntu.tar debiand.tar debianc.tar
docker rmi -f \
localhost:1338/debianc:latest \
localhost:1338/debiand:latest \
localhost:1338/ubuntuc:foo \
localhost:1338/ubuntud:latest \
|| true
}
trap cleanup EXIT

case "$OSTYPE" in
# On Windows, Docker runs in a VM, so a registry running on the Windows
# host is not accessible via localhost for `docker pull|push`.
win*|msys*|cygwin*)
docker run -d --rm -p 1338:5000 --name test-reg registry:2
CTR=test-reg
;;

*)
registry &
PID=$!
;;
esac

go install ./cmd/registry
go install ./cmd/crane

registry &
PID=$!

crane pull debian:latest debianc.tar
crane push debianc.tar localhost:1338/debianc:latest
Expand All @@ -20,8 +55,3 @@ docker push localhost:1338/ubuntud:latest
crane pull localhost:1338/ubuntud:latest ubuntu.tar
crane push ubuntu.tar localhost:1338/ubuntuc:foo
docker pull localhost:1338/ubuntuc:foo
rm ubuntu.tar
rm debiand.tar
rm debianc.tar

kill $PID
18 changes: 15 additions & 3 deletions pkg/v1/cache/fs.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package cache

import (
"fmt"
"io"
"os"
"path/filepath"
"runtime"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/tarball"
Expand Down Expand Up @@ -45,7 +47,7 @@ func (l *layer) create(h v1.Hash) (io.WriteCloser, error) {
if err := os.MkdirAll(l.path, 0700); err != nil {
return nil, err
}
return os.Create(filepath.Join(l.path, h.String()))
return os.Create(cachepath(l.path, h))
}

func (l *layer) Compressed() (io.ReadCloser, error) {
Expand Down Expand Up @@ -101,7 +103,7 @@ func (rc *readcloser) Close() error {
}

func (fs *fscache) Get(h v1.Hash) (v1.Layer, error) {
l, err := tarball.LayerFromFile(filepath.Join(fs.path, h.String()))
l, err := tarball.LayerFromFile(cachepath(fs.path, h))
if os.IsNotExist(err) {
return nil, ErrNotFound
}
Expand All @@ -116,9 +118,19 @@ func (fs *fscache) Get(h v1.Hash) (v1.Layer, error) {
}

func (fs *fscache) Delete(h v1.Hash) error {
err := os.Remove(filepath.Join(fs.path, h.String()))
err := os.Remove(cachepath(fs.path, h))
if os.IsNotExist(err) {
return ErrNotFound
}
return err
}

func cachepath(path string, h v1.Hash) string {
var file string
if runtime.GOOS == "windows" {
file = fmt.Sprintf("%s-%s", h.Algorithm, h.Hex)
} else {
file = h.String()
}
return filepath.Join(path, file)
}
3 changes: 1 addition & 2 deletions pkg/v1/cache/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"io"
"io/ioutil"
"os"
"path"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"
Expand Down Expand Up @@ -167,7 +166,7 @@ func TestErrUnexpectedEOF(t *testing.T) {
if err != nil {
t.Fatalf("layer.Digest(): %v", err)
}
p := path.Join(dir, h.String())
p := cachepath(dir, h)

// Write only the first segment of the compressed layer to produce an
// UnexpectedEOF error when reading it
Expand Down
7 changes: 4 additions & 3 deletions pkg/v1/layout/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package layout

import (
"path/filepath"
"testing"

v1 "github.com/google/go-containerregistry/pkg/v1"
Expand All @@ -39,9 +40,9 @@ var (
Algorithm: "sha256",
Hex: "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
}
bogusPath = "testdata/does_not_exist"
testPath = "testdata/test_index"
testPathOneImage = "testdata/test_index_one_image"
bogusPath = filepath.Join("testdata", "does_not_exist")
testPath = filepath.Join("testdata", "test_index")
testPathOneImage = filepath.Join("testdata", "test_index_one_image")
)

func TestImage(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/v1/mutate/mutate.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func extract(img v1.Image, w io.Writer) error {
if err != nil {
return fmt.Errorf("reading layer contents: %v", err)
}
defer layerReader.Close()
tarReader := tar.NewReader(layerReader)
for {
header, err := tarReader.Next()
Expand Down Expand Up @@ -300,6 +301,7 @@ func layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) {
if err != nil {
return nil, fmt.Errorf("getting layer: %v", err)
}
defer layerReader.Close()
w := new(bytes.Buffer)
tarWriter := tar.NewWriter(w)
defer tarWriter.Close()
Expand Down
8 changes: 8 additions & 0 deletions pkg/v1/tarball/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
if err != nil {
return nil, err
}
close := true
defer func() {
if close {
f.Close()
}
}()

tf := tar.NewReader(f)
for {
hdr, err := tf.Next()
Expand All @@ -209,6 +216,7 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
return nil, err
}
if hdr.Name == filePath {
close = false
return tarFile{
Reader: tf,
Closer: f,
Expand Down
1 change: 1 addition & 0 deletions pkg/v1/tarball/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ func computeDiffID(opener Opener, compressed bool) (v1.Hash, error) {
if err != nil {
return v1.Hash{}, err
}
defer reader.Close()

diffID, _, err := v1.SHA256(reader)
return diffID, err
Expand Down
1 change: 1 addition & 0 deletions pkg/v1/validate/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ func computeLayer(layer v1.Layer) (*computedLayer, error) {
if err != nil {
return nil, err
}
defer ur.Close()
udiffid, usize, err := v1.SHA256(ur)
if err != nil {
return nil, err
Expand Down

0 comments on commit 0d898ee

Please sign in to comment.