From c21258b70ed91ab5ff8b1d345123fed1011a49c9 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Fri, 20 Mar 2020 10:55:23 +0100 Subject: Add podman static build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’re now able to build a static podman binary based on a custom nix derivation. This is integrated in cirrus as well, whereas a later target would be to provide a self-contained static binary bundle which can be installed on any Linux x64-bit system. Fixes: https://github.com/containers/libpod/issues/1399 Signed-off-by: Sascha Grunert --- .cirrus.yml | 16 +++++++++++ .gitignore | 1 + Containerfile-nix | 10 +++++++ Makefile | 26 +++++++++++++++++- README.md | 6 +++++ libpod/define/info.go | 1 + libpod/info.go | 2 ++ libpod/linkmode/linkmode_dynamic.go | 8 ++++++ libpod/linkmode/linkmode_static.go | 8 ++++++ nix/default.nix | 53 +++++++++++++++++++++++++++++++++++++ nix/nixpkgs.json | 9 +++++++ nix/nixpkgs.nix | 8 ++++++ 12 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 Containerfile-nix create mode 100644 libpod/linkmode/linkmode_dynamic.go create mode 100644 libpod/linkmode/linkmode_static.go create mode 100644 nix/default.nix create mode 100644 nix/nixpkgs.json create mode 100644 nix/nixpkgs.nix diff --git a/.cirrus.yml b/.cirrus.yml index 10e78404a..e53788c6c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -820,6 +820,7 @@ success_task: - "test_build_cache_images" - "verify_test_built_images" - "docs" + - "static_build" # FIXME remove when all v2 tests pass - "integration_test_temporary" @@ -835,3 +836,18 @@ success_task: memory: 1 success_script: '/usr/local/bin/entrypoint.sh ./$SCRIPT_BASE/success.sh |& ${TIMESTAMP}' + +static_build_task: + container: + image: quay.io/podman/nix-podman:1.0.0 + cpu: 8 + memory: 12 + timeout_in: 20m + depends_on: + - "gating" + build_script: + - nix build -f nix + binaries_artifacts: + path: "result-bin/bin/podman" + on_failure: + failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh |& ${TIMESTAMP}' diff --git a/.gitignore b/.gitignore index e60b8c03a..9af705caa 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ release.txt /test/copyimg/copyimg /test/goecho/goecho .vscode* +result-bin diff --git a/Containerfile-nix b/Containerfile-nix new file mode 100644 index 000000000..5eea71af6 --- /dev/null +++ b/Containerfile-nix @@ -0,0 +1,10 @@ +# vim: set syntax=dockerfile: +FROM nixos/nix:latest + +RUN apk add --no-cache bash git + +COPY . /work +WORKDIR work/nix +RUN nix-build +WORKDIR / +RUN rm -rf work diff --git a/Makefile b/Makefile index d1eb56aa8..e991d4b35 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ LDFLAGS_PODMAN ?= \ -X $(LIBPOD)/define.buildInfo=$(BUILD_INFO) \ -X $(LIBPOD)/config._installPrefix=$(PREFIX) \ -X $(LIBPOD)/config._etcDir=$(ETCDIR) \ - -extldflags "$(LDFLAGS)" + $(EXTRA_LDFLAGS) #Update to LIBSECCOMP_COMMIT should reflect in Dockerfile too. LIBSECCOMP_COMMIT := v2.3.3 # Rarely if ever should integration tests take more than 50min, @@ -217,6 +217,30 @@ bin/podman.cross.%: .gopathok GOARCH="$${TARGET##*.}" \ $(GO_BUILD) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags '$(BUILDTAGS_CROSS)' -o "$@" $(PROJECT)/cmd/podman +# Update nix/nixpkgs.json its latest master commit +.PHONY: nixpkgs +nixpkgs: + @nix run -f channel:nixpkgs-unstable nix-prefetch-git -c nix-prefetch-git \ + --no-deepClone https://github.com/nixos/nixpkgs > nix/nixpkgs.json + +NIX_IMAGE ?= quay.io/podman/nix-podman:1.0.0 + +# Build the nix image as base for static builds +.PHONY: nix-image +nix-image: + $(CONTAINER_RUNTIME) build -t $(NIX_IMAGE) -f Containerfile-nix . + +# Build podman statically linked based on the default nix container image +.PHONY: build-static +build-static: + $(CONTAINER_RUNTIME) run \ + --rm -it \ + -v $(shell pwd):/work \ + -w /work $(NIX_IMAGE) \ + sh -c "nix build -f nix && \ + mkdir -p bin && \ + cp result-*bin/bin/podman bin/podman-static" + .PHONY: run-docker-py-tests run-docker-py-tests: $(eval testLogs=$(shell mktemp)) diff --git a/README.md b/README.md index 194733cee..34b12b3a9 100644 --- a/README.md +++ b/README.md @@ -180,3 +180,9 @@ Podman offers a Varlink-based API for remote management of containers. However, this API has been deprecated by the REST API. Varlink support is in maintenance mode, and will be removed in a future release. For more details, you can see [this blog](https://podman.io/blogs/2020/01/17/podman-new-api.html). + +## Static Binary Builds +The Cirrus CI integration within this repository contains a `static_build` job +which produces a static Podman binary for testing purposes. Please note that +this binary is not officially supported with respect to feature-completeness +and functionality and should be only used for testing. diff --git a/libpod/define/info.go b/libpod/define/info.go index 2516cad77..906aa523f 100644 --- a/libpod/define/info.go +++ b/libpod/define/info.go @@ -33,6 +33,7 @@ type HostInfo struct { SwapFree int64 `json:"swapFree"` SwapTotal int64 `json:"swapTotal"` Uptime string `json:"uptime"` + Linkmode string `json:"linkmode"` } // SlirpInfo describes the slirp exectuable that diff --git a/libpod/info.go b/libpod/info.go index 4007e0ce7..51208a2b1 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -14,6 +14,7 @@ import ( "github.com/containers/buildah" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/libpod/linkmode" "github.com/containers/libpod/pkg/cgroups" registries2 "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/rootless" @@ -86,6 +87,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) { info := define.HostInfo{ Arch: runtime.GOARCH, BuildahVersion: buildah.Version, + Linkmode: linkmode.Linkmode(), CPUs: runtime.NumCPU(), Distribution: hostDistributionInfo, EventLogger: r.eventer.String(), diff --git a/libpod/linkmode/linkmode_dynamic.go b/libpod/linkmode/linkmode_dynamic.go new file mode 100644 index 000000000..6d51d60e0 --- /dev/null +++ b/libpod/linkmode/linkmode_dynamic.go @@ -0,0 +1,8 @@ +// +build !static + +package linkmode + +// Linkmode returns the linking mode (static/dynamic) for the build. +func Linkmode() string { + return "dynamic" +} diff --git a/libpod/linkmode/linkmode_static.go b/libpod/linkmode/linkmode_static.go new file mode 100644 index 000000000..2db083f4a --- /dev/null +++ b/libpod/linkmode/linkmode_static.go @@ -0,0 +1,8 @@ +// +build static + +package linkmode + +// Linkmode returns the linking mode (static/dynamic) for the build. +func Linkmode() string { + return "static" +} diff --git a/nix/default.nix b/nix/default.nix new file mode 100644 index 000000000..211caee93 --- /dev/null +++ b/nix/default.nix @@ -0,0 +1,53 @@ +let + pkgs = import ./nixpkgs.nix { + config = { + packageOverrides = pkg: { + go_1_12 = pkg.go_1_14; + }; + }; + }; + + static = pkg: pkg.overrideAttrs(old: { + configureFlags = (old.configureFlags or []) ++ + [ "--without-shared" "--disable-shared" ]; + dontDisableStatic = true; + enableSharedExecutables = false; + enableStatic = true; + }); + + patchLvm2 = pkg: pkg.overrideAttrs(old: { + configureFlags = [ + "--disable-cmdlib" "--disable-readline" "--disable-udev_rules" + "--disable-udev_sync" "--enable-pkgconfig" "--enable-static_link" + ]; + preConfigure = old.preConfigure + '' + substituteInPlace libdm/Makefile.in --replace \ + SUBDIRS=dm-tools SUBDIRS= + substituteInPlace tools/Makefile.in --replace \ + "TARGETS += lvm.static" "" + substituteInPlace tools/Makefile.in --replace \ + "INSTALL_LVM_TARGETS += install_tools_static" "" + ''; + postInstall = ""; + }); + + self = { + podman-static = (pkgs.podman.overrideAttrs(old: { + name = "podman-static"; + buildInputs = old.buildInputs ++ (with pkgs; [ + (static pkgs.libassuan) + (static pkgs.libgpgerror) + git + glibc + glibc.static + ]); + src = ./..; + EXTRA_LDFLAGS = ''-linkmode external -extldflags "-static -lm"''; + BUILDTAGS = ''static apparmor selinux seccomp systemd varlink containers_image_ostree_stub''; + })).override { + gpgme = (static pkgs.gpgme); + libseccomp = (static pkgs.libseccomp); + lvm2 = (patchLvm2 (static pkgs.lvm2)); + }; + }; +in self diff --git a/nix/nixpkgs.json b/nix/nixpkgs.json new file mode 100644 index 000000000..fbc774373 --- /dev/null +++ b/nix/nixpkgs.json @@ -0,0 +1,9 @@ +{ + "url": "https://github.com/nixos/nixpkgs", + "rev": "a08d4f605bca62c282ce9955d5ddf7d824e89809", + "date": "2020-03-20T10:10:15+01:00", + "sha256": "1bniq08dlmrmrz4aga1cj0d7rqbaq9xapm5ar15wdv2c6431z2m8", + "fetchSubmodules": false, + "deepClone": false, + "leaveDotGit": false +} diff --git a/nix/nixpkgs.nix b/nix/nixpkgs.nix new file mode 100644 index 000000000..21e7f17a2 --- /dev/null +++ b/nix/nixpkgs.nix @@ -0,0 +1,8 @@ +let + json = builtins.fromJSON (builtins.readFile ./nixpkgs.json); + nixpkgs = import (builtins.fetchTarball { + name = "nixos-unstable"; + url = "${json.url}/archive/${json.rev}.tar.gz"; + inherit (json) sha256; + }); +in nixpkgs -- cgit v1.2.3-54-g00ecf