go1.20+: Refuse to work if cgo is enabled

On go1.20+ it is no longer possible to directly copy a cgo-enabled
library into a docker container. For this reason, this commit adds a
flag to commands that automatically make them fail with an appropriate
message if cgo is enabled.
This commit is contained in:
Tom 2023-04-27 11:13:47 +02:00
parent 5e9795ad0c
commit 6362b2887b
9 changed files with 30 additions and 10 deletions

View file

@ -36,7 +36,7 @@ jobs:
go test ./... go test ./...
- name: Build executable - name: Build executable
run: | run: |
go build -o wdcli ./cmd/wdcli CGO_ENABLED=0 go build -o wdcli ./cmd/wdcli
- name: Upload Release - name: Upload Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')

View file

@ -4,7 +4,7 @@ all: wdcli
wdcli: wdcli:
go generate ./internal/dis/component/control/static/ go generate ./internal/dis/component/control/static/
go build -o ./wdcli ./cmd/wdcli CGO_ENABLED=0 go build -o ./wdcli ./cmd/wdcli
deps: internal/dis/component/server/assets/node_modules deps: internal/dis/component/server/assets/node_modules

View file

@ -58,7 +58,7 @@ To bootstrap a new distillery instance, the `wdcli bootstrap` command can be use
First copy the executable onto the server, using a command similar as: First copy the executable onto the server, using a command similar as:
```bash ```bash
GOOS=linux GOARCH=amd64 go build -o wdcli ./cmd/wdcli && scp ./wdcli distillery.example.com: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o wdcli ./cmd/wdcli && scp ./wdcli distillery.example.com:
``` ```
Next, access the server and run the `bootstrap` command: Next, access the server and run the `bootstrap` command:

View file

@ -31,6 +31,7 @@ func (systemupdate) Description() wisski_distillery.Description {
return wisski_distillery.Description{ return wisski_distillery.Description{
Requirements: cli.Requirements{ Requirements: cli.Requirements{
NeedsDistillery: true, NeedsDistillery: true,
FailOnCgo: true,
}, },
ParserConfig: parser.Config{ ParserConfig: parser.Config{
IncludeUnknown: true, IncludeUnknown: true,

2
go.mod
View file

@ -16,7 +16,7 @@ require (
github.com/pquerna/otp v1.4.0 github.com/pquerna/otp v1.4.0
github.com/rs/zerolog v1.29.0 github.com/rs/zerolog v1.29.0
github.com/tkw1536/goprogram v0.3.5 github.com/tkw1536/goprogram v0.3.5
github.com/tkw1536/pkglib v0.0.0-20230409110642-5f57240e294b github.com/tkw1536/pkglib v0.0.0-20230427085354-69b5e047c325
github.com/yuin/goldmark v1.5.4 github.com/yuin/goldmark v1.5.4
github.com/yuin/goldmark-meta v1.1.0 github.com/yuin/goldmark-meta v1.1.0
golang.org/x/crypto v0.8.0 golang.org/x/crypto v0.8.0

2
go.sum
View file

@ -117,6 +117,8 @@ github.com/tkw1536/goprogram v0.3.5 h1:S0axKo3R/vGa4zhYqYDKAZEPhAfwUSSeMtVwnAu4s
github.com/tkw1536/goprogram v0.3.5/go.mod h1:pYr4dMHOSVurbPQ4KTR0ett8XWNISbsRS6zlh9Nsxa8= github.com/tkw1536/goprogram v0.3.5/go.mod h1:pYr4dMHOSVurbPQ4KTR0ett8XWNISbsRS6zlh9Nsxa8=
github.com/tkw1536/pkglib v0.0.0-20230409110642-5f57240e294b h1:qeoY+XHCDx1fubOJkLuMSdz4xNWtgeLpxPfxBiEIj4c= github.com/tkw1536/pkglib v0.0.0-20230409110642-5f57240e294b h1:qeoY+XHCDx1fubOJkLuMSdz4xNWtgeLpxPfxBiEIj4c=
github.com/tkw1536/pkglib v0.0.0-20230409110642-5f57240e294b/go.mod h1:0A1B9Cc5+yJXR3eeB14CqD4dFSbEjjWRo5Pr9M3XYuI= github.com/tkw1536/pkglib v0.0.0-20230409110642-5f57240e294b/go.mod h1:0A1B9Cc5+yJXR3eeB14CqD4dFSbEjjWRo5Pr9M3XYuI=
github.com/tkw1536/pkglib v0.0.0-20230427085354-69b5e047c325 h1:A1XZyL73L+FI/r3P7OLnibAFDlCV0Q8dTU7bwFfAYvo=
github.com/tkw1536/pkglib v0.0.0-20230427085354-69b5e047c325/go.mod h1:0A1B9Cc5+yJXR3eeB14CqD4dFSbEjjWRo5Pr9M3XYuI=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=

View file

@ -9,6 +9,9 @@ import (
type Requirements struct { type Requirements struct {
// Do we need an installed distillery? // Do we need an installed distillery?
NeedsDistillery bool NeedsDistillery bool
// Automatically fail when cgo is enabled?
FailOnCgo bool
} }
// AllowsFlag checks if the provided flag may be passed to fullfill this requirement // AllowsFlag checks if the provided flag may be passed to fullfill this requirement

View file

@ -7,6 +7,7 @@ import (
"github.com/FAU-CDI/wisski-distillery/internal/config" "github.com/FAU-CDI/wisski-distillery/internal/config"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component" "github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/tkw1536/goprogram/exit" "github.com/tkw1536/goprogram/exit"
"github.com/tkw1536/pkglib/cgo"
) )
var errNoConfigFile = exit.Error{ var errNoConfigFile = exit.Error{
@ -19,8 +20,20 @@ var errOpenConfig = exit.Error{
Message: "error loading configuration file: %q", Message: "error loading configuration file: %q",
} }
// An error to be returned when cgo is enabled unexpectedly.
var CGoEnabled = exit.Error{
ExitCode: exit.ExitGeneralArguments,
Message: "this functionality is only available when cgo support is disabled. Set `CGO_ENABLED=0' at build time and try again",
}
// NewDistillery creates a new distillery from the provided flags // NewDistillery creates a new distillery from the provided flags
func NewDistillery(params cli.Params, flags cli.Flags, req cli.Requirements) (dis *Distillery, err error) { func NewDistillery(params cli.Params, flags cli.Flags, req cli.Requirements) (dis *Distillery, err error) {
// check cgo support to prevent weird error messages
// this has to happen either when we are inside docker, or when explicity requested by the command.
if cgo.Enabled && (flags.InternalInDocker || req.FailOnCgo) {
return nil, CGoEnabled
}
dis = new(Distillery) dis = new(Distillery)
dis.Still.Upstream = component.Upstream{ dis.Still.Upstream = component.Upstream{
SQL: component.HostPort{Host: "127.0.0.1", Port: 3306}, SQL: component.HostPort{Host: "127.0.0.1", Port: 3306},

View file

@ -12,6 +12,7 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/tkw1536/goprogram" "github.com/tkw1536/goprogram"
"github.com/tkw1536/goprogram/exit" "github.com/tkw1536/goprogram/exit"
"github.com/tkw1536/pkglib/cgo"
) )
// these define the ggman-specific program types // these define the ggman-specific program types
@ -59,12 +60,7 @@ var errUserIsNotRoot = exit.Error{
Message: "this command has to be executed as root. the current user is not root", Message: "this command has to be executed as root. the current user is not root",
} }
// an error when cgo is enabled const warnCGoEnabled = "Warning: This executable has been built with cgo enabled. This means certain commands may not work. \n"
var errCGoEnabled = exit.Error{
ExitCode: exit.ExitGeneralArguments,
Message: "this command has to be executed as root. the current user is not root",
}
const warnNoDeployWdcli = "Warning: Not using %q executable at %q. This might leave the distillery in an inconsistent state. \n" const warnNoDeployWdcli = "Warning: Not using %q executable at %q. This might leave the distillery in an inconsistent state. \n"
func NewProgram() Program { func NewProgram() Program {
@ -76,6 +72,11 @@ func NewProgram() Program {
return errUserIsNotRoot return errUserIsNotRoot
} }
// warn about cgo!
if cgo.Enabled {
context.Printf(warnCGoEnabled)
}
// when not running inside docker and we need a distillery // when not running inside docker and we need a distillery
// then we should warn if we are not using the distillery executable. // then we should warn if we are not using the distillery executable.
if dis := context.Environment; !context.Args.Flags.InternalInDocker && context.Description.Requirements.NeedsDistillery && !dis.Config.Paths.UsingDistilleryExecutable() { if dis := context.Environment; !context.Args.Flags.InternalInDocker && context.Description.Requirements.NeedsDistillery && !dis.Config.Paths.UsingDistilleryExecutable() {