Skip to content

Commit

Permalink
feat: Allow building on Darwin for both arm64 and amd64 architectures
Browse files Browse the repository at this point in the history
Create darwin specific equivalents of _linux code.

If possible, merge common parts into _unix suffixed files.
Move others into _linux.go and _darwin.go files.

Augment goreleaser's ytt templates to produce two additional targets:

- darwin amd64
- darwin arm64

Make it build a binary runnable on the host MacOS machine via make kraft (both with DOCKER variable set and not set)

GitHub-Fixes: unikraft#30
GitHub-Fixes: unikraft#266

Signed-off-by: Jakub Ciolek <[email protected]>
  • Loading branch information
Jakub Ciolek authored and jake-ciolek committed Jul 25, 2023
1 parent 0f3ebc3 commit 27da0d7
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 44 deletions.
9 changes: 6 additions & 3 deletions .goreleaser-stable.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,23 @@ nix:
cp -vr ./dist/kraft $out/bin/kraft
builds:
#@ targets = {"linuxu": {"os": "linux", "arch": "amd64"}, "darwin-arm64": {"os": "darwin", "arch": "arm64"}, "darwin-amd64": {"os": "darwin", "arch": "amd64"}}
#@ for binary in ["kraft"]:
- id: #@ "{}-linuxu".format(binary)
#@ for target, specs in targets.items():
- id: #@ "{}-{}".format(binary, target)
binary: #@ binary
main: #@ "./cmd/{}".format(binary)
env:
- CGO_ENABLED=0
- GOMOD=kraftkit.sh
goos:
- linux
- #@ specs["os"]
goarch:
- amd64
- #@ specs["arch"]
ldflags:
- -s -w
- -X {{ .Env.GOMOD }}/internal/version.version={{ .Version }}
- -X {{ .Env.GOMOD }}/internal/version.commit={{ .Commit }}
- -X {{ .Env.GOMOD }}/internal/version.buildTime={{ .Date }}
#@ end
#@ end
10 changes: 7 additions & 3 deletions .goreleaser-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,24 @@ nfpms:
- apk

builds:
#@ targets = {"linuxu": {"os": "linux", "arch": "amd64"}, "darwin-arm64": {"os": "darwin", "arch": "arm64"}, "darwin-amd64": {"os": "darwin", "arch": "amd64"}}
#@ for binary in ["kraft"]:
- id: #@ "{}-linuxu".format(binary)
#@ for target, specs in targets.items():
- id: #@ "{}-{}".format(binary, target)
binary: #@ binary
main: #@ "./cmd/{}".format(binary)
env:
- CGO_ENABLED=0
- GOMOD=kraftkit.sh
goos:
- linux
- #@ specs["os"]
goarch:
- amd64
- #@ specs["arch"]
ldflags:
- -s -w
- -X {{ .Env.GOMOD }}/internal/version.version={{ .Version }}
- -X {{ .Env.GOMOD }}/internal/version.commit={{ .Commit }}
- -X {{ .Env.GOMOD }}/internal/version.buildTime={{ .Date }}
#@ end
#@ end

40 changes: 34 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ GIT_SHA ?= $(shell git update-index -q --refresh && \
# Tools
DOCKER ?= docker
DOCKER_RUN ?= $(DOCKER) run --rm $(1) \
-e DOCKER= \
-w /go/src/$(GOMOD) \
-v $(WORKDIR):/go/src/$(GOMOD) \
$(REGISTRY)/$(2):$(IMAGE_TAG) \
$(3)
-e DOCKER= \
-e GOOS=$(GOOS) \
-e GOARCH=$(GOARCH) \
-w /go/src/$(GOMOD) \
--platform linux/amd64 \
-v $(WORKDIR):/go/src/$(GOMOD) \
$(REGISTRY)/$(2):$(IMAGE_TAG) \
$(3)
GO ?= go
GOFUMPT ?= gofumpt
GOCILINT ?= golangci-lint
Expand All @@ -55,6 +58,29 @@ CMAKE ?= cmake
# Misc
Q ?= @

MACHINE_OS ?= $(shell uname -s)
MACHINE_ARCH ?= $(shell uname -m)
GOOS ?= linux
GOARCH ?= amd64

# Don't try to pass the path to Darwin host's make into the container
ifeq ($(MACHINE_OS),Darwin)
MAKE_COMMAND = make
endif

# If on Darwin, we want to build a runnable binary.
# Check the OS and set GOOS/GOARCH flags accordingly.
# Note that we are still running a linux/amd64 container.
# TODO: For better performance, build an image for darwin/arm64 and darwin/amd64
ifeq ($(MACHINE_OS),Darwin)
GOOS = darwin
ifeq ($(MACHINE_ARCH),arm64)
GOARCH = arm64
else ifeq ($(MACHINE_ARCH),x86_64)
GOARCH = amd64
endif
endif

# If run with DOCKER= or within a container, unset DOCKER_RUN so all commands
# are not proxied via docker container.
ifeq ($(DOCKER),)
Expand All @@ -68,7 +94,7 @@ ifneq ($(DOCKER_RUN),)
$(BIN): ENVIRONMENT ?= myself-full
$(BIN):
$(info Running target via Docker...)
$(Q)$(call DOCKER_RUN,,$(ENVIRONMENT),$(MAKE) -e $@)
$(Q)$(call DOCKER_RUN,,$(ENVIRONMENT),$(MAKE) GOOS=$(GOOS) GOARCH=$(GOARCH) -e $@)
$(Q)exit 0
endif

Expand All @@ -87,6 +113,8 @@ $(addprefix $(.PROXY), $(BIN)): GO_LDFLAGS += -X "$(GOMOD)/internal/version.comm
$(addprefix $(.PROXY), $(BIN)): GO_LDFLAGS += -X "$(GOMOD)/internal/version.buildTime=$(shell date)"
$(addprefix $(.PROXY), $(BIN)): tidy
$(addprefix $(.PROXY), $(BIN)):
GOOS=$(GOOS) \
GOARCH=$(GOARCH) \
$(GO) build \
-gcflags=all='$(GO_GCFLAGS)' \
-ldflags='$(GO_LDFLAGS)' \
Expand Down
24 changes: 24 additions & 0 deletions machine/network/register_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package network

import (
"context"
"errors"

networkv1alpha1 "kraftkit.sh/api/network/v1alpha1"
)

// hostSupportedStrategies returns the map of known supported drivers for the
// given host.
func hostSupportedStrategies() map[string]*Strategy {
return map[string]*Strategy{
"bridge": {
NewNetworkV1alpha1: func(ctx context.Context, opts ...any) (networkv1alpha1.NetworkService, error) {
return nil, errors.New("network service is not supported on MacOS")
},
},
}
}
13 changes: 13 additions & 0 deletions machine/platform/register_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//go:build darwin
// +build darwin

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package platform

func unixVariantStrategies() map[Platform]*Strategy {
// Nothing added for Darwin
return map[Platform]*Strategy{}
}
36 changes: 4 additions & 32 deletions machine/platform/register_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,13 @@ import (
"path/filepath"

zip "api.zip"

machinev1alpha1 "kraftkit.sh/api/machine/v1alpha1"
"kraftkit.sh/config"
"kraftkit.sh/internal/set"
"kraftkit.sh/machine/firecracker"
"kraftkit.sh/machine/qemu"
"kraftkit.sh/machine/store"
)

var qemuV1alpha1Driver = func(ctx context.Context, opts ...any) (machinev1alpha1.MachineService, error) {
service, err := qemu.NewMachineV1alpha1Service(ctx, opts...)
if err != nil {
return nil, err
}

embeddedStore, err := store.NewEmbeddedStore[machinev1alpha1.MachineSpec, machinev1alpha1.MachineStatus](
filepath.Join(
config.G[config.KraftKit](ctx).RuntimeDir,
"machinev1alpha1",
),
)
if err != nil {
return nil, err
}

return machinev1alpha1.NewMachineServiceHandler(
ctx,
service,
zip.WithStore[machinev1alpha1.MachineSpec, machinev1alpha1.MachineStatus](embeddedStore, zip.StoreRehydrationSpecNil),
zip.WithBefore(storePlatformFilter(PlatformQEMU)),
)
}

var firecrackerV1alpha1Driver = func(ctx context.Context, opts ...any) (machinev1alpha1.MachineService, error) {
if set.NewStringSet("debug", "trace").Contains(config.G[config.KraftKit](ctx).Log.Level) {
opts = append(opts, firecracker.WithDebug(true))
Expand Down Expand Up @@ -69,13 +43,11 @@ var firecrackerV1alpha1Driver = func(ctx context.Context, opts ...any) (machinev
)
}

// hostSupportedStrategies returns the map of known supported drivers for the
// given host.
func hostSupportedStrategies() map[Platform]*Strategy {
func unixVariantStrategies() map[Platform]*Strategy {
// (jake-ciolek): The firecracker driver has a dependency on github.com/containernetworking/plugins/pkg/ns via
// github.com/firecracker-microvm/firecracker-go-sdk
// Unfortunately, it doesn't support darwin.
return map[Platform]*Strategy{
PlatformQEMU: {
NewMachineV1alpha1: qemuV1alpha1Driver,
},
PlatformFirecracker: {
NewMachineV1alpha1: firecrackerV1alpha1Driver,
},
Expand Down
58 changes: 58 additions & 0 deletions machine/platform/register_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package platform

import (
"context"
"path/filepath"

zip "api.zip"

machinev1alpha1 "kraftkit.sh/api/machine/v1alpha1"
"kraftkit.sh/config"
"kraftkit.sh/machine/qemu"
"kraftkit.sh/machine/store"
)

var qemuV1alpha1Driver = func(ctx context.Context, opts ...any) (machinev1alpha1.MachineService, error) {
service, err := qemu.NewMachineV1alpha1Service(ctx, opts...)
if err != nil {
return nil, err
}

embeddedStore, err := store.NewEmbeddedStore[machinev1alpha1.MachineSpec, machinev1alpha1.MachineStatus](
filepath.Join(
config.G[config.KraftKit](ctx).RuntimeDir,
"machinev1alpha1",
),
)
if err != nil {
return nil, err
}

return machinev1alpha1.NewMachineServiceHandler(
ctx,
service,
zip.WithStore[machinev1alpha1.MachineSpec, machinev1alpha1.MachineStatus](embeddedStore, zip.StoreRehydrationSpecNil),
zip.WithBefore(storePlatformFilter(PlatformQEMU)),
)
}

// hostSupportedStrategies returns the map of known supported drivers for the
// given host.
func hostSupportedStrategies() map[Platform]*Strategy {
s := map[Platform]*Strategy{
PlatformQEMU: {
NewMachineV1alpha1: qemuV1alpha1Driver,
},
}

// Merge OS-specific strategies
for k, v := range unixVariantStrategies() {
s[k] = v
}

return s
}
File renamed without changes.

0 comments on commit 27da0d7

Please sign in to comment.