Skip to content

Commit

Permalink
feat: rewrite linux build rules in Go (#1044)
Browse files Browse the repository at this point in the history
This diff rewrites Linux build rules in Go.

See ooni/probe#2401.
  • Loading branch information
bassosimone authored Jan 25, 2023
1 parent 35faf23 commit 7ab2370
Show file tree
Hide file tree
Showing 10 changed files with 625 additions and 129 deletions.
18 changes: 0 additions & 18 deletions CLI/go-build-alpine

This file was deleted.

94 changes: 0 additions & 94 deletions CLI/go-build-linux-static

This file was deleted.

2 changes: 1 addition & 1 deletion MONOREPO/tools/libgit.bash
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ clean_one_repo() {
if [[ $(basename $dirname) == "probe-cli" ]]; then
# Avoid completely removing all the cloned subrepos
# as well as the important local.bash config file
extraflags="-e MONOREPO/repo/ -e MONOREPO/tools/local.bash"
extraflags="-e MONOREPO/repo/ -e MONOREPO/tools/local.bash -e GOCACHE"
fi
run git clean -dffx $extraflags
)
Expand Down
25 changes: 10 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,36 @@ CLI/darwin:
#help: The `make CLI/linux-static-386` command builds and statically links the
#help: ooniprobe and miniooni binaries for linux/386.
.PHONY: CLI/linux-static-386
CLI/linux-static-386: search/for/docker maybe/copypsiphon
./CLI/go-build-linux-static $(OONI_GO_DOCKER_GOCACHE) 386 ./cmd/ooniprobe ./internal/cmd/miniooni
CLI/linux-static-386:
go run ./internal/cmd/buildtool linux docker 386

#help:
#help: The `make CLI/linux-static-amd64` command builds and statically links the
#help: ooniprobe and miniooni binaries for linux/amd64.
.PHONY: CLI/linux-static-amd64
CLI/linux-static-amd64: search/for/docker maybe/copypsiphon
./CLI/go-build-linux-static $(OONI_GO_DOCKER_GOCACHE) amd64 ./cmd/ooniprobe ./internal/cmd/miniooni
CLI/linux-static-amd64:
go run ./internal/cmd/buildtool linux docker amd64

#help:
#help: The `make CLI/linux-static-armv6` command builds and statically links the
#help: ooniprobe and miniooni binaries for linux/arm/v6.
.PHONY: CLI/linux-static-armv6
CLI/linux-static-armv6: search/for/docker maybe/copypsiphon
./CLI/go-build-linux-static $(OONI_GO_DOCKER_GOCACHE) armv6 ./cmd/ooniprobe ./internal/cmd/miniooni
CLI/linux-static-armv6:
go run ./internal/cmd/buildtool linux docker armv6

#help:
#help: The `make CLI/linux-static-armv7` command builds and statically links the
#help: ooniprobe and miniooni binaries for linux/arm/v7.
.PHONY: CLI/linux-static-armv7
CLI/linux-static-armv7: search/for/docker maybe/copypsiphon
./CLI/go-build-linux-static $(OONI_GO_DOCKER_GOCACHE) armv7 ./cmd/ooniprobe ./internal/cmd/miniooni
CLI/linux-static-armv7:
go run ./internal/cmd/buildtool linux docker armv7

#help:
#help: The `make CLI/linux-static-arm64` command builds and statically links the
#help: ooniprobe and miniooni binaries for linux/arm64.
.PHONY: CLI/linux-static-arm64
CLI/linux-static-arm64: search/for/docker maybe/copypsiphon
./CLI/go-build-linux-static $(OONI_GO_DOCKER_GOCACHE) arm64 ./cmd/ooniprobe ./internal/cmd/miniooni
CLI/linux-static-arm64:
go run ./internal/cmd/buildtool linux docker arm64

#help:
#help: The `make CLI/miniooni` command creates a build of miniooni, for the current
Expand Down Expand Up @@ -162,11 +162,6 @@ MOBILE/ios: search/for/go search/for/zip search/for/xcode maybe/copypsiphon
./MOBILE/ios/zipframework
./MOBILE/ios/createpodspec

.PHONY: search/for/docker
search/for/docker:
@printf "checking for docker... "
@command -v docker || { echo "not found"; exit 1; }

.PHONY: search/for/git
search/for/git:
@printf "checking for git... "
Expand Down
18 changes: 18 additions & 0 deletions internal/cmd/buildtool/linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

//
// Linux builds entry point
//

import "github.com/spf13/cobra"

// linuxSubcommand returns the linux [cobra.Command].
func linuxSubcommand() *cobra.Command {
cmd := &cobra.Command{
Use: "linux",
Short: "Builds ooniprobe and miniooni for linux",
}
cmd.AddCommand(linuxDockerSubcommand())
cmd.AddCommand(linuxStaticSubcommand())
return cmd
}
93 changes: 93 additions & 0 deletions internal/cmd/buildtool/linuxdocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
"fmt"
"os"
"os/user"
"path/filepath"
"time"

"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/cmd/buildtool/internal/buildtoolmodel"
"github.com/ooni/probe-cli/v3/internal/must"
"github.com/ooni/probe-cli/v3/internal/runtimex"
"github.com/spf13/cobra"
)

// linuxDockerSubcommand returns the linuxDocker sucommand.
func linuxDockerSubcommand() *cobra.Command {
return &cobra.Command{
Use: "docker {386|amd64|armv6|armv7|arm64}",
Short: "Builds ooniprobe and miniooni with static linking using docker",
Run: func(cmd *cobra.Command, args []string) {
linuxDockerBuildAll(&buildDeps{}, args[0])
},
Args: cobra.ExactArgs(1),
}
}

// main is the main function of the linuxDocker subcommand.
func linuxDockerBuildAll(deps buildtoolmodel.Dependencies, ooniArch string) {
defer log.Infof("done")
deps.PsiphonMaybeCopyConfigFiles()

golangVersion := string(must.FirstLineBytes(deps.LinuxReadGOVERSION("GOVERSION")))
golangDockerImage := "golang:" + golangVersion + "-alpine"

var (
goarm string
dockerArch string
)
switch ooniArch {
case "armv7":
goarm = "7"
dockerArch = "arm/v7"
case "armv6":
goarm = "6"
dockerArch = "arm/v6"
default:
goarm = "0"
dockerArch = ooniArch
}

user := runtimex.Try1(user.Current())

// Implementation note: we must run docker as the user that invokes
// it for actions/cache@v3 to be able to cache OOGOCACHEDIR. This
// constraint forces us to run all privileged operations early
// using a Dockerfile, so the build proper runs as $(id -u):$(id -g).
log.Infof("writing CLI/Dockerfile")
linuxDockerWriteDockerfile(deps, dockerArch, golangDockerImage, user.Uid)

image := fmt.Sprintf("oobuild-%s-%s", ooniArch, time.Now().Format("20060102"))

log.Infof("pull and build the correct docker image")
must.Run(log.Log, "docker", "pull", "--platform", "linux/"+dockerArch, golangDockerImage)
must.Run(log.Log, "docker", "build", "--platform", "linux/"+dockerArch, "-t", image, "CLI")

log.Infof("run the build inside docker")
curdir := runtimex.Try1(os.Getwd())

must.Run(
log.Log, "docker", "run",
"--platform", "linux/"+dockerArch,
"--user", user.Uid,
"-v", curdir+":/ooni",
"-w", "/ooni",
image,
"go", "run", "./internal/cmd/buildtool", "linux", "static", "--goarm", goarm,
)
}

// linuxDockerWwriteDockerfile writes the CLI/Dockerfile file.
func linuxDockerWriteDockerfile(deps buildtoolmodel.Dependencies, dockerArch, golangDockerImage, uid string) {
content := []byte(fmt.Sprintf(`
FROM --platform=linux/%s %s
RUN apk update
RUN apk upgrade
RUN apk add --no-progress gcc git linux-headers musl-dev
RUN adduser -D -h /home/oobuild -G nobody -u %s oobuild
ENV HOME=/home/oobuild`, dockerArch, golangDockerImage, uid,
))
deps.LinuxWriteDockerfile(filepath.Join("CLI", "Dockerfile"), content, 0600)
}
Loading

0 comments on commit 7ab2370

Please sign in to comment.