Skip to content

Commit

Permalink
feat(internal): add logic from pkg-runtime (#221)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockopp authored Oct 26, 2021
1 parent bd78686 commit 5b1f57b
Show file tree
Hide file tree
Showing 7 changed files with 508 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.16

require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/docker/distribution v2.7.1+incompatible
github.com/gin-gonic/gin v1.7.4
github.com/go-vela/compiler v0.10.0
github.com/go-vela/mock v0.10.0
Expand Down
11 changes: 11 additions & 0 deletions internal/image/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) 2021 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

// Package image provides the ability for Vela to manage
// and manipulate an image provided for a container.
//
// Usage:
//
// import "github.com/go-vela/worker/internal/image"
package image
87 changes: 87 additions & 0 deletions internal/image/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) 2021 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package image

import (
"github.com/docker/distribution/reference"
)

// Parse digests the provided image into a fully
// qualified canonical reference. If an error
// occurs, it will return the provided image.
func Parse(_image string) string {
// parse the image provided into a fully qualified canonical reference
//
// https://pkg.go.dev/github.com/go-vela/worker/runtime/internal/image?tab=doc#ParseWithError
_canonical, err := ParseWithError(_image)
if err != nil {
return _image
}

return _canonical
}

// ParseWithError digests the provided image into a
// fully qualified canonical reference. If an error
// occurs, it will return the last digested form of
// the image.
func ParseWithError(_image string) (string, error) {
// parse the image provided into a
// named, fully qualified reference
//
// https://pkg.go.dev/github.com/docker/distribution/reference?tab=doc#ParseAnyReference
_reference, err := reference.ParseAnyReference(_image)
if err != nil {
return _image, err
}

// ensure we have the canonical form of the named reference
//
// https://pkg.go.dev/github.com/docker/distribution/reference?tab=doc#ParseNamed
_canonical, err := reference.ParseNamed(_reference.String())
if err != nil {
return _reference.String(), err
}

// ensure the canonical reference has a tag
//
// https://pkg.go.dev/github.com/docker/distribution/reference?tab=doc#TagNameOnly
return reference.TagNameOnly(_canonical).String(), nil
}

// IsPrivilegedImage digests the provided image with a
// privileged pattern to see if the image meets the criteria
// needed to allow a Docker Socket mount.
func IsPrivilegedImage(image, privileged string) (bool, error) {
// parse the image provided into a
// named, fully qualified reference
//
// https://pkg.go.dev/github.com/docker/distribution/reference?tab=doc#ParseAnyReference
_refImg, err := reference.ParseAnyReference(image)
if err != nil {
return false, err
}

// ensure we have the canonical form of the named reference
//
// https://pkg.go.dev/github.com/docker/distribution/reference?tab=doc#ParseNamed
_canonical, err := reference.ParseNamed(_refImg.String())
if err != nil {
return false, err
}

// add default tag "latest" when tag does not exist
_refImg = reference.TagNameOnly(_canonical)

// check if the image matches the privileged pattern
//
// https://pkg.go.dev/github.com/docker/distribution/reference#FamiliarMatch
match, err := reference.FamiliarMatch(privileged, _refImg)
if err != nil {
return false, err
}

return match, nil
}
188 changes: 188 additions & 0 deletions internal/image/image_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// Copyright (c) 2021 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package image

import (
"strings"
"testing"
)

func TestImage_Parse(t *testing.T) {
// setup tests
tests := []struct {
image string
want string
}{
{
image: "golang",
want: "docker.io/library/golang:latest",
},
{
image: "golang:latest",
want: "docker.io/library/golang:latest",
},
{
image: "library/golang",
want: "docker.io/library/golang:latest",
},
{
image: "library/golang:1.14",
want: "docker.io/library/golang:1.14",
},
{
image: "docker.io/library/golang",
want: "docker.io/library/golang:latest",
},
{
image: "docker.io/library/golang:latest",
want: "docker.io/library/golang:latest",
},
{
image: "index.docker.io/library/golang",
want: "docker.io/library/golang:latest",
},
{
image: "index.docker.io/library/golang:latest",
want: "docker.io/library/golang:latest",
},
{
image: "gcr.io/library/golang",
want: "gcr.io/library/golang:latest",
},
{
image: "gcr.io/library/golang:latest",
want: "gcr.io/library/golang:latest",
},
{
image: "!@#$%^&*()",
want: "!@#$%^&*()",
},
}

// run tests
for _, test := range tests {
got := Parse(test.image)

if !strings.EqualFold(got, test.want) {
t.Errorf("Parse is %s want %s", got, test.want)
}
}
}

func TestImage_ParseWithError(t *testing.T) {
// setup tests
tests := []struct {
failure bool
image string
want string
}{
{
failure: false,
image: "golang",
want: "docker.io/library/golang:latest",
},
{
failure: false,
image: "golang:latest",
want: "docker.io/library/golang:latest",
},
{
failure: false,
image: "golang:1.14",
want: "docker.io/library/golang:1.14",
},
{
failure: true,
image: "!@#$%^&*()",
want: "!@#$%^&*()",
},
{
failure: true,
image: "1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
want: "sha256:1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
},
}

// run tests
for _, test := range tests {
got, err := ParseWithError(test.image)

if test.failure {
if err == nil {
t.Errorf("ParseWithError should have returned err")
}

if !strings.EqualFold(got, test.want) {
t.Errorf("ParseWithError is %s want %s", got, test.want)
}

continue
}

if err != nil {
t.Errorf("ParseWithError returned err: %v", err)
}

if !strings.EqualFold(got, test.want) {
t.Errorf("ParseWithError is %s want %s", got, test.want)
}
}
}

func TestImage_IsPrivilegedImage(t *testing.T) {
// setup tests
tests := []struct {
name string
image string
pattern string
want bool
}{
{
name: "test privileged image without tag",
image: "docker.company.com/foo/bar",
pattern: "docker.company.com/foo/bar",
want: true,
},
{
name: "test privileged image with tag",
image: "docker.company.com/foo/bar:v0.1.0",
pattern: "docker.company.com/foo/bar",
want: true,
},
{
name: "test privileged image with tag",
image: "docker.company.com/foo/bar",
pattern: "docker.company.com/foo/bar:v0.1.0",
want: false,
},
{
name: "test privileged with bad image",
image: "!@#$%^&*()",
pattern: "docker.company.com/foo/bar",
want: false,
},
{
name: "test privileged with bad pattern",
image: "docker.company.com/foo/bar",
pattern: "!@#$%^&*()",
want: false,
},
{
name: "test privileged with on extended path image",
image: "docker.company.com/foo/bar",
pattern: "docker.company.com/foo",
want: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, _ := IsPrivilegedImage(test.image, test.pattern)
if got != test.want {
t.Errorf("IsPrivilegedImage is %v want %v", got, test.want)
}
})
}
}
11 changes: 11 additions & 0 deletions internal/volume/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) 2021 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

// Package volume provides the ability for Vela to manage
// and manipulate a volume provided for a container.
//
// Usage:
//
// import "github.com/go-vela/worker/internal/volume"
package volume
70 changes: 70 additions & 0 deletions internal/volume/volume.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2021 Target Brands, Inc. All rights reserved.
//
// Use of this source code is governed by the LICENSE file in this repository.

package volume

import (
"fmt"
"strings"
)

// Volume represents the volume definition used
// to create volumes for a container.
type Volume struct {
Source string `json:"source,omitempty"`
Destination string `json:"destination,omitempty"`
AccessMode string `json:"access_mode,omitempty"`
}

// Parse digests the provided volume into a fully
// qualified volume reference. If an error
// occurs, it will return a nil volume.
func Parse(_volume string) *Volume {
// parse the image provided into a fully qualified canonical reference
//
// https://pkg.go.dev/github.com/go-vela/worker/runtime/internal/image?tab=doc#ParseWithError
v, err := ParseWithError(_volume)
if err != nil {
return nil
}

return v
}

// ParseWithError digests the provided volume into a
// fully qualified volume reference. If an error
// occurs, it will return a nil volume and the
// produced error.
func ParseWithError(_volume string) (*Volume, error) {
// split each slice element into source, destination and access mode
parts := strings.Split(_volume, ":")

switch len(parts) {
case 1:
// return the read-only volume with the same source and destination
return &Volume{
Source: parts[0],
Destination: parts[0],
AccessMode: "ro",
}, nil
// nolint: gomnd // ignore magic number
case 2:
// return the read-only volume with different source and destination
return &Volume{
Source: parts[0],
Destination: parts[1],
AccessMode: "ro",
}, nil
// nolint: gomnd // ignore magic number
case 3:
// return the full volume with source, destination and access mode
return &Volume{
Source: parts[0],
Destination: parts[1],
AccessMode: parts[2],
}, nil
default:
return nil, fmt.Errorf("volume %s requires at least 1, but no more than 2, `:`", _volume)
}
}
Loading

0 comments on commit 5b1f57b

Please sign in to comment.