Skip to content

Commit

Permalink
feat: support writing os/arch info image config
Browse files Browse the repository at this point in the history
Signed-off-by: Ramkumar Chinchani <[email protected]>
  • Loading branch information
rchincha committed Nov 10, 2022
1 parent 227b5a9 commit 762b691
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 4 deletions.
5 changes: 2 additions & 3 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os/exec"
"os/user"
"path"
"runtime"
"strings"
"time"

Expand Down Expand Up @@ -210,8 +209,8 @@ func (b *Builder) updateOCIConfigForOutput(sf *types.Stackerfile, s types.Storag
author := fmt.Sprintf("%s@%s", username, host)

meta.Created = time.Now()
meta.Architecture = runtime.GOARCH
meta.OS = runtime.GOOS
meta.Architecture = *l.Arch
meta.OS = *l.OS
meta.Author = author

annotations, err := mutator.Annotations(context.Background())
Expand Down
2 changes: 1 addition & 1 deletion cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,5 @@ func TestCacheEntryChanged(t *testing.T) {
// This test works because the type information is included in the
// hashstructure hash above, so using a zero valued CacheEntry is
// enough to capture changes in types.
assert.Equal(uint64(0x98ab47c70ff0b70), h)
assert.Equal(uint64(0x1ec739cbb7ee4e77), h)
}
11 changes: 11 additions & 0 deletions doc/stacker_yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,14 @@ While `config` section supports a similar `labels`, it is more pertitent to the
image runtime. On the other hand, `annotations` is intended to be
image-specific metadata aligned with the
[annotations in the image spec](https://github.com/opencontainers/image-spec/blob/main/annotations.md).

##### `os`

`os` is a user-specified string value indicating which _operating system_ this image is being
built for, for example, `linux`, `darwin`, etc. It is an optional field and it
defaults to the host operating system if not specified.

##### `arch`
`arch` is a user-specified string value indicating which machine _architecture_ this image is being
built for, for example, `amd64`, `arm64`, etc. It is an optional field and it
defaults to the host machine architecture if not specified.
44 changes: 44 additions & 0 deletions test/multi-arch.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
load helpers

function setup() {
stacker_setup
}

function teardown() {
cleanup
}

@test "multi-arch/os support" {
cat > stacker.yaml <<EOF
centos:
os: darwin
arch: arm64
from:
type: oci
url: $CENTOS_OCI
import:
- https://www.cisco.com/favicon.ico
EOF
stacker build

# check OCI image generation
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
layer=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest)
config=$(cat oci/blobs/sha256/$manifest | jq -r .config.digest | cut -f2 -d:)
[ "$(cat oci/blobs/sha256/$config | jq -r '.architecture')" = "arm64" ]
[ "$(cat oci/blobs/sha256/$config | jq -r '.os')" = "darwin" ]
}

@test "multi-arch/os bad config fails" {
cat > stacker.yaml <<EOF
centos:
os:
from:
type: oci
url: $CENTOS_OCI
import:
- https://www.cisco.com/favicon.ico
EOF
bad_stacker build
[ "$status" -eq 1 ]
}
23 changes: 23 additions & 0 deletions types/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"path/filepath"
"reflect"
"regexp"
"runtime"
"strings"

"github.com/anmitsu/go-shlex"
Expand Down Expand Up @@ -192,6 +193,8 @@ type Layer struct {
Binds Binds `yaml:"binds"`
RuntimeUser string `yaml:"runtime_user"`
Annotations map[string]string `yaml:"annotations"`
OS *string `yaml:"os"`
Arch *string `yaml:"arch"`
}

func parseLayers(referenceDirectory string, lms yaml.MapSlice, requireHash bool) (map[string]Layer, error) {
Expand Down Expand Up @@ -227,6 +230,12 @@ func parseLayers(referenceDirectory string, lms yaml.MapSlice, requireHash bool)
}
}
}

if directive.Key.(string) == "os" || directive.Key.(string) == "arch" {
if directive.Value == nil {
return nil, errors.Errorf("stackerfile: %q value cannot be empty", directive.Key.(string))
}
}
}
}

Expand Down Expand Up @@ -257,6 +266,18 @@ func parseLayers(referenceDirectory string, lms yaml.MapSlice, requireHash bool)
}
}

if layer.OS == nil {
// if not specified, default to runtime
os := runtime.GOOS
layer.OS = &os
}

if layer.Arch == nil {
// if not specified, default to runtime
arch := runtime.GOARCH
layer.Arch = &arch
}

ret[name], err = layer.absolutify(referenceDirectory)
if err != nil {
return nil, err
Expand Down Expand Up @@ -467,6 +488,8 @@ func init() {
layerType := reflect.TypeOf(Layer{})
for i := 0; i < layerType.NumField(); i++ {
tag := layerType.Field(i).Tag.Get("yaml")
// some fields are ",omitempty"
tag = strings.Split(tag, ",")[0]
layerFields = append(layerFields, tag)
}
}

0 comments on commit 762b691

Please sign in to comment.