Skip to content
Open
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ subo/docker/publish:
subo/smoketest: subo
./scripts/smoketest.sh

subo/toolchaintest: subo subo/docker
./scripts/toolchaintest.sh

mod/replace/atmo:
go mod edit -replace github.com/suborbital/atmo=$(HOME)/Workspaces/suborbital/atmo

Expand Down
15 changes: 13 additions & 2 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (b *Builder) BuildWithToolchain(tcn Toolchain) error {
}

if tcn == ToolchainNative {
b.log.LogStart(fmt.Sprintf("building runnable: %s (%s)", mod.Name, mod.Module.Lang))
b.log.LogStart(fmt.Sprintf("building module: %s (%s)", mod.Name, mod.Module.Lang))

result := &BuildResult{}

Expand Down Expand Up @@ -157,7 +157,18 @@ func (b *Builder) dockerBuildForLang(lang string) (*BuildResult, error) {

result := &BuildResult{}

outputLog, err := b.Config.CommandRunner.Run(fmt.Sprintf("docker run --rm --mount type=bind,source=%s,target=/root/runnable %s subo build %s --native --langs %s", b.Context.MountPath, img, b.Context.RelDockerPath, lang))
// Run the Docker toolchain as the current user
uid := os.Getuid()
gid := os.Getgid()

toolchainCmd := fmt.Sprintf("docker run --rm --mount type=bind,source=%s,target=/usr/src/runnable -u %d:%d --env HOME=/tmp %s subo build %s --native --langs %s", b.Context.MountPath, uid, gid, img, b.Context.RelDockerPath, lang)
Comment on lines +161 to +164
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great and obvious in hindsight!


// Show the toolchain command being run
if b.Context.LogLevel == "verbose" {
util.LogInfo(fmt.Sprintf("🐳 %s", toolchainCmd))
}

outputLog, err := b.Config.CommandRunner.Run(toolchainCmd)

result.OutputLog = outputLog

Expand Down
2 changes: 1 addition & 1 deletion builder/docker/assemblyscript/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM suborbital/subo:dev as subo

FROM node:16-buster-slim
WORKDIR /root/runnable
WORKDIR /usr/src/runnable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this path chosen? /usr/* paths are usually root owned as well and I don't see a chown anywhere for it. Does all of the writing happen in the /tmp dir set as $HOME in the Docker invocation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I...honestly don't remember where /usr/src came from, I definitely remember /root being an issue though.

The /tmp as HOME change came later for the Go/Swift images and I don't remember that being needed for other images, but I think this might vary depending on what's the UID/GID of the invoking user.

COPY --from=subo /go/bin/subo /usr/local/bin
RUN npm install -g npm@latest
2 changes: 1 addition & 1 deletion builder/docker/grain/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM suborbital/subo:dev as subo

FROM ghcr.io/grain-lang/grain:0.4-slim
WORKDIR /root/runnable
WORKDIR /usr/src/runnable
COPY --from=subo /go/bin/subo /usr/local/bin/subo
RUN mkdir /root/suborbital
3 changes: 1 addition & 2 deletions builder/docker/javascript/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ FROM ghcr.io/suborbital/javy:v0.3.0 as javy
FROM suborbital/subo:dev as subo

FROM node:16-bullseye-slim
WORKDIR /root/runnable
WORKDIR /usr/src/runnable
# Propagate our root permissions for our home folder to everyone. This allows
# npm scripts (which get run as whatever user owns the mounted runnable
# directory) to access common home folder resources (caches, etc.).
RUN mkdir /root/suborbital && chmod -R o=u /root

COPY --from=javy /usr/local/bin/javy /usr/local/bin
COPY --from=subo /go/bin/subo /usr/local/bin
17 changes: 10 additions & 7 deletions builder/docker/rust/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
FROM suborbital/subo:dev as subo

FROM rust:1.56.1-slim-buster
WORKDIR /root/runnable
COPY --from=subo /go/bin/subo /usr/local/bin
WORKDIR /usr/src/runnable

# install the wasm target and then force an update of the crates.io index
RUN rustup target install wasm32-wasi && \
cargo search suborbital

# install the wasm target and then install something that
# doesn't exist (and ignore the error) to update the crates.io index
RUN mkdir /root/suborbital && \
rustup target install wasm32-wasi
RUN cargo install lazy_static; exit 0
# make everything inside CARGO_HOME writable for anyone (again)
RUN chmod -R a+w $RUSTUP_HOME $CARGO_HOME

# embed subo
COPY --from=subo /go/bin/subo /usr/local/bin
2 changes: 1 addition & 1 deletion builder/docker/swift/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM suborbital/subo:dev as subo

FROM ghcr.io/swiftwasm/swift:focal
WORKDIR /root/runnable
WORKDIR /usr/src/runnable
COPY --from=subo /go/bin/subo /usr/local/bin
2 changes: 1 addition & 1 deletion builder/docker/tinygo/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN wget -O tinygo.tar.gz \
rm -rf tinygo/src/examples && \
rm -rf tinygo.tar.gz

WORKDIR /root/runnable
WORKDIR /usr/src/runnable

COPY --from=go /usr/local/go /usr/local/
COPY --from=subo /go/bin/subo /usr/local/bin
Expand Down
2 changes: 1 addition & 1 deletion builder/prereq.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (p Prereq) GetCommand(b BuildConfig, md project.ModuleDir) (string, error)
var fullCmd strings.Builder
err = cmdTmpl.Execute(&fullCmd, data)
if err != nil {
return "", errors.Wrap(err, "failed to execute prerequisite Command string with runnableDir")
return "", errors.Wrap(err, "failed to execute prerequisite Command string with moduleDir")
}

return fullCmd.String(), nil
Expand Down
29 changes: 15 additions & 14 deletions project/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,17 @@ var validLangs = map[string]struct{}{

// Context describes the context under which the tool is being run.
type Context struct {
Cwd string
CwdIsRunnable bool
Modules []ModuleDir
Bundle BundleRef
TenantConfig *tenant.Config
DeltavVersion string
Langs []string
MountPath string
RelDockerPath string
BuilderTag string
Cwd string
CwdIsRunnable bool
Modules []ModuleDir
Bundle BundleRef
TenantConfig *tenant.Config
RuntimeVersion string
Langs []string
MountPath string
RelDockerPath string
BuilderTag string
LogLevel string
}

// ModuleDir represents a directory containing a Runnable.
Expand All @@ -66,7 +67,7 @@ func ForDirectory(dir string) (*Context, error) {

modules, cwdIsRunnable, err := getModuleDirs(fullDir)
if err != nil {
return nil, errors.Wrap(err, "failed to getRunnableDirs")
return nil, errors.Wrap(err, "failed to getModuleDirs")
}

bundle, err := bundleTargetPath(fullDir)
Expand Down Expand Up @@ -189,11 +190,11 @@ func getModuleDirs(cwd string) ([]ModuleDir, bool, error) {
return nil, false, errors.Wrap(err, "failed to list directory")
}

// Check to see if we're running from within a Runnable directory
// Check to see if we're running from within a Module directory
// and return true if so.
moduleDir, err := getModuleFromFiles(cwd, topLvlFiles)
if err != nil {
return nil, false, errors.Wrap(err, "failed to getRunnableFromFiles")
return nil, false, errors.Wrap(err, "failed to getModuleFromFiles")
} else if moduleDir != nil {
modules = append(modules, *moduleDir)
return modules, true, nil
Expand All @@ -215,7 +216,7 @@ func getModuleDirs(cwd string) ([]ModuleDir, bool, error) {

moduleDir, err := getModuleFromFiles(dirPath, innerFiles)
if err != nil {
return nil, false, errors.Wrap(err, "failed to getRunnableFromFiles")
return nil, false, errors.Wrap(err, "failed to getModuleFromFiles")
} else if moduleDir == nil {
continue
}
Expand Down
4 changes: 2 additions & 2 deletions root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ including building WebAssembly Runnables and Atmo projects.`,
// create commands.
create := &cobra.Command{
Use: "create",
Short: "create a runnable, project, or handler",
Long: `create a new Atmo project, WebAssembly runnable or handler`,
Short: "create a module, project, or handler",
Long: `create a new E2Core project, WebAssembly module or handler`,
}

if features.EnableReleaseCommands {
Expand Down
10 changes: 5 additions & 5 deletions scripts/smoketest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ subo create project "$TEST_PROJECT"
pushd "$TEST_PROJECT" > /dev/null

# create a runnable for each supported language
subo create runnable rs-test --lang rust
subo create runnable swift-test --lang swift
subo create runnable as-test --lang assemblyscript
subo create runnable tinygo-test --lang tinygo
subo create runnable js-test --lang javascript
subo create module rs-test --lang rust
subo create module swift-test --lang swift
subo create module as-test --lang assemblyscript
subo create module tinygo-test --lang tinygo
subo create module js-test --lang javascript

# build project bundle
subo build .
53 changes: 53 additions & 0 deletions scripts/toolchaintest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash

set -eu

TEST_PROJECT="buildertest"

trap 'catch $? $LINENO' EXIT

catch() {
if [[ "$1" != "0" ]]; then
echo "An Error $1 occurred on $2"
fi

# return to origin, clear directory stack
pushd -0 > /dev/null && dirs -c

if [[ -d "$TEST_PROJECT" ]]; then
echo "Cleaning up test artifacts..."
rm -rf "$TEST_PROJECT" || echo "Failed to clean up test artifacts, if this was a permissions error try using 'sudo rm -rf $TEST_PROJECT'"
fi
}

# build local subo docker image
docker image ls -q suborbital/subo:dev
if [[ "$?" != "0" ]]; then
make subo/docker
fi

# rebuild local docker build tooling
docker build . -f builder/docker/assemblyscript/Dockerfile -t suborbital/builder-as:dev
docker build . -f builder/docker/grain/Dockerfile --platform linux/amd64 -t suborbital/builder-gr:dev
docker build . -f builder/docker/javascript/Dockerfile -t suborbital/builder-js:dev
docker build . -f builder/docker/rust/Dockerfile -t suborbital/builder-rs:dev
docker build . -f builder/docker/swift/Dockerfile -t suborbital/builder-swift:dev
docker build . -f builder/docker/tinygo/Dockerfile --platform linux/amd64 --build-arg TARGETARCH=amd64 -t suborbital/builder-tinygo:dev
docker build . -f builder/docker/wat/Dockerfile -t suborbital/builder-wat:dev
Comment on lines +30 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have an explicit dev target for local builds (which is weird) but these can be replaced with calls to make like this:

make ver=dev builder/docker/tinygo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I'll change it around!



# create a new project
subo create project "$TEST_PROJECT"

# enter project directory
pushd "$TEST_PROJECT" > /dev/null

# create a runnable for each supported language
subo create module rs-test --lang rust
subo create module swift-test --lang swift
subo create module as-test --lang assemblyscript
subo create module tinygo-test --lang tinygo
subo create module js-test --lang javascript

# build project bundle
subo build . --builder-tag dev --verbose
20 changes: 14 additions & 6 deletions subo/command/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
func BuildCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "build [dir]",
Short: "build a WebAssembly runnable",
Long: `build a WebAssembly runnable and/or create a Runnable Bundle`,
Short: "build a WebAssembly module",
Long: `build a WebAssembly module and/or create an application bundle`,
RunE: func(cmd *cobra.Command, args []string) error {
dir := "."
if len(args) > 0 {
Expand All @@ -29,11 +29,11 @@ func BuildCmd() *cobra.Command {
}

if len(bdr.Context.Modules) == 0 {
return errors.New("🚫 no runnables found in current directory (no .runnable.yaml files found)")
return errors.New(fmt.Sprintf("🚫 build found no modules in %s (no .module.yaml files found)", bdr.Context.Cwd))
}

if bdr.Context.CwdIsRunnable {
util.LogInfo("building single Runnable (run from project root to create bundle)")
util.LogInfo("building a single module (run from project root to create bundle)")
}

langs, _ := cmd.Flags().GetStringSlice("langs")
Expand All @@ -44,7 +44,7 @@ func BuildCmd() *cobra.Command {
shouldDockerBuild, _ := cmd.Flags().GetBool("docker")

if bdr.Context.CwdIsRunnable && shouldDockerBuild {
return errors.New("🚫 cannot build Docker image for a single Runnable (must be a project)")
return errors.New("🚫 cannot build Docker image for a single module (must be a project)")
}

useNative, _ := cmd.Flags().GetBool("native")
Expand All @@ -69,6 +69,11 @@ func BuildCmd() *cobra.Command {
bdr.Context.BuilderTag = builderTag
}

verbose, _ := cmd.Flags().GetBool("verbose")
if verbose {
bdr.Context.LogLevel = "verbose"
}

if makeTarget != "" {
util.LogStart(fmt.Sprintf("make %s", makeTarget))
_, err = util.Command.Run(fmt.Sprintf("make %s", makeTarget))
Expand Down Expand Up @@ -113,10 +118,13 @@ func BuildCmd() *cobra.Command {
cmd.Flags().Bool("native", false, "use native (locally installed) toolchain rather than Docker")
cmd.Flags().String("make", "", "execute the provided Make target before building the project bundle")
cmd.Flags().Bool("docker", false, "build your project's Dockerfile. It will be tagged {identifier}:{appVersion}")
cmd.Flags().StringSlice("langs", []string{}, "build only Runnables for the listed languages (comma-seperated)")
cmd.Flags().StringSlice("langs", []string{}, "build only modules for the listed languages (comma-seperated)")
cmd.Flags().String("mountpath", "", "if passed, the Docker builders will mount their volumes at the provided path")
cmd.Flags().String("relpath", "", "if passed, the Docker builders will run `subo build` using the provided path, relative to '--mountpath'")
cmd.Flags().String("builder-tag", "", "use the provided tag for builder images")

cmd.Flags().BoolP("verbose", "v", false, "enable verbose logging")
cmd.Flags().Lookup("verbose").NoOptDefVal = "true"

return cmd
}
4 changes: 2 additions & 2 deletions subo/command/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/suborbital/subo/subo/util"
)

//CleanCmd removes all of the target/.build folders for Runnables and deletes the .wasm files.
// CleanCmd removes all of the target/.build folders for Runnables and deletes the .wasm files.
func CleanCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "clean",
Expand All @@ -32,7 +32,7 @@ func CleanCmd() *cobra.Command {
}

if len(bctx.Modules) == 0 {
return errors.New("🚫 no runnables found in current directory (no .runnable yaml files found)")
return errors.New("🚫 cleanup found no modules in current directory (no .module.yaml files found)")
}

util.LogStart(fmt.Sprintf("cleaning in %s", bctx.Cwd))
Expand Down
16 changes: 8 additions & 8 deletions subo/command/create_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const (
)

type projectData struct {
Name string
Environment string
APIVersion string
DeltavVersion string
Name string
Environment string
APIVersion string
RuntimeVersion string
}

// CreateProjectCmd returns the build command.
Expand Down Expand Up @@ -68,10 +68,10 @@ func CreateProjectCmd() *cobra.Command {
}

data := projectData{
Name: name,
Environment: environment,
APIVersion: release.FFIVersion,
DeltavVersion: release.DeltavVersion,
Name: name,
Environment: environment,
APIVersion: release.FFIVersion,
RuntimeVersion: release.RuntimeVersion,
}

if err := template.ExecTmplDir(bctx.Cwd, name, templatesPath, "project", data); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion subo/command/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func DevCmd() *cobra.Command {
util.LogInfo("Running DeltaV with debug logging")
}

dockerCmd := fmt.Sprintf("docker run -v=%s:/home/atmo -e=DELTAV_HTTP_PORT=%s %s -p=%s:%s suborbital/deltav:%s deltav start", bctx.Cwd, port, envvar, port, port, release.DeltavVersion)
dockerCmd := fmt.Sprintf("docker run -v=%s:/home/atmo -e=DELTAV_HTTP_PORT=%s %s -p=%s:%s suborbital/deltav:%s deltav start", bctx.Cwd, port, envvar, port, port, release.RuntimeVersion)

_, err = util.Command.Run(dockerCmd)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions subo/release/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ var SuboDotVersion = "0.5.4"
// FFIVersion is the FFI version used by this version of subo.
var FFIVersion = "0.15.1"

// DeltavVersion is the default version of Deltav that will be used for new projects.
var DeltavVersion = "0.4.7"
// RuntimeVersion is the default version of Deltav that will be used for new projects.
var RuntimeVersion = "0.4.7"

// SCCTag is the docker tag used for creating new compute core deployments.
var SCCTag = "v0.3.1"