Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d24d0da7a | ||
|
|
d3efb410d0 | ||
| 1c46fb8617 | |||
| 4408a9e005 | |||
| 41baf180a3 | |||
| 4754869190 | |||
| ec62b65ecd | |||
| 0ff72b99d9 | |||
| e4c0d4d72a |
13
.build.yml
13
.build.yml
@@ -9,12 +9,11 @@ sources:
|
|||||||
tasks:
|
tasks:
|
||||||
- setup: |
|
- setup: |
|
||||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||||
- test: |
|
- built-test-lint: |
|
||||||
make -C undocker coverage.html
|
make -C undocker -O -j$(nproc) undocker coverage.html lint
|
||||||
- lint: |
|
- usage: |
|
||||||
make -C undocker -O -j$(nproc) lint
|
# like 'grep -q', but prints output too.
|
||||||
- binaries: |
|
# | tee /dev/stderr doesn't work on sourcehut workers; permission denied.
|
||||||
make -C undocker -O -j$(nproc) all
|
./undocker/undocker |& awk 'BEGIN{c=1};/Built with /{c=0};{print};END{exit c}'
|
||||||
cat undocker/sha256sum-*.txt
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- undocker/coverage.html
|
- undocker/coverage.html
|
||||||
|
|||||||
31
Makefile
31
Makefile
@@ -1,32 +1,15 @@
|
|||||||
SCRIPTS = $(shell awk '/#!\/bin\/(ba)?sh/&&FNR==1{print FILENAME}' $(shell git ls-files))
|
SCRIPTS = $(shell awk '/#!\/bin\/(ba)?sh/&&FNR==1{print FILENAME}' $(shell git ls-files))
|
||||||
GODEPS = $(shell git ls-files '*.go' go.mod go.sum)
|
GODEPS = $(shell git ls-files '*.go' go.mod go.sum)
|
||||||
GOOSARCHS = $(sort darwin/amd64 linux/amd64)
|
|
||||||
|
|
||||||
VSN ?= $(shell git describe --dirty)
|
VSN ?= $(shell git describe --dirty)
|
||||||
VSNHASH = $(shell git rev-parse --verify HEAD)
|
VSNHASH = $(shell git rev-parse --verify HEAD)
|
||||||
LDFLAGS = -ldflags "-X main.Version=$(VSN) -X main.VersionHash=$(VSNHASH)"
|
LDFLAGS = -ldflags "-X main.Version=$(VSN) -X main.VersionHash=$(VSNHASH)"
|
||||||
|
|
||||||
undocker: ## builds binary for the current architecture
|
undocker: ## builds binary for the current architecture
|
||||||
CGO_ENABLED=0 go build $(LDFLAGS) -o $@
|
go build $(LDFLAGS) -o $@
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test: coverage.out
|
||||||
go test -race -cover ./...
|
|
||||||
|
|
||||||
define undockertarget
|
|
||||||
UNDOCKERS += undocker-$(1)-$(2)-$(VSN)
|
|
||||||
undocker-$(1)-$(2)-$(VSN): $(GODEPS)
|
|
||||||
CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) go build $(LDFLAGS) -o $$@
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(foreach goosarch,$(GOOSARCHS),\
|
|
||||||
$(eval $(call undockertarget,$(word 1,$(subst /, ,$(goosarch))),$(word 2,$(subst /, ,$(goosarch))))))
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: $(UNDOCKERS) sha256sum-$(VSN).txt
|
|
||||||
|
|
||||||
.PHONY: sha256sum-asc
|
|
||||||
sha256sum-asc: sha256sum-$(VSN).txt.asc
|
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint:
|
lint:
|
||||||
@@ -36,17 +19,11 @@ lint:
|
|||||||
|
|
||||||
.INTERMEDIATE: coverage.out
|
.INTERMEDIATE: coverage.out
|
||||||
coverage.out: $(GODEPS)
|
coverage.out: $(GODEPS)
|
||||||
go test -coverprofile $@ ./...
|
go test -race -cover -coverprofile $@ ./...
|
||||||
|
|
||||||
coverage.html: coverage.out
|
coverage.html: coverage.out
|
||||||
go tool cover -html=$< -o $@
|
go tool cover -html=$< -o $@
|
||||||
|
|
||||||
sha256sum-$(VSN).txt: $(UNDOCKERS)
|
|
||||||
sha256sum $(UNDOCKERS) > $@
|
|
||||||
|
|
||||||
sha256sum-$(VSN).txt.asc: sha256sum-$(VSN).txt
|
|
||||||
gpg --clearsign $<
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f undocker-*-v* coverage.html sha256sum*.txt sha256sum*.txt.asc
|
rm -f undocker coverage.html
|
||||||
|
|||||||
@@ -18,17 +18,20 @@ and application isolation ("container") runtimes: once the docker image is
|
|||||||
extracted, it can be run with old-fashioned tools: lxc, systemd-nspawn,
|
extracted, it can be run with old-fashioned tools: lxc, systemd-nspawn,
|
||||||
systemd, FreeBSD Jails, and many others.
|
systemd, FreeBSD Jails, and many others.
|
||||||
|
|
||||||
Undocker has no dependencies outside Golang stdlib.
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
You may use [officially released binaries][3], or build it:
|
Build it like this for the "current" platform:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ make undocker
|
$ make undocker
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`make -B` will print the extra flags (`-X <...>`) for cross-compiling with
|
||||||
|
other archs. It's all `go build <...>` in the back, and depends only on Go's
|
||||||
|
compiler and stdlib.
|
||||||
|
|
||||||
Usage: convert docker image to rootfs
|
Usage: convert docker image to rootfs
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -28,7 +27,7 @@ func TestExecute(t *testing.T) {
|
|||||||
infile: "t10-in.txt",
|
infile: "t10-in.txt",
|
||||||
fixture: func(t *testing.T, dir string) {
|
fixture: func(t *testing.T, dir string) {
|
||||||
fname := filepath.Join(dir, "t10-in.txt")
|
fname := filepath.Join(dir, "t10-in.txt")
|
||||||
if err := ioutil.WriteFile(fname, _foo, 0644); err != nil {
|
if err := os.WriteFile(fname, _foo, 0644); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -39,7 +38,7 @@ func TestExecute(t *testing.T) {
|
|||||||
infile: "t20-in.txt",
|
infile: "t20-in.txt",
|
||||||
fixture: func(t *testing.T, dir string) {
|
fixture: func(t *testing.T, dir string) {
|
||||||
fname := filepath.Join(dir, "t20-in.txt")
|
fname := filepath.Join(dir, "t20-in.txt")
|
||||||
if err := ioutil.WriteFile(fname, _foo, 0644); err != nil {
|
if err := os.WriteFile(fname, _foo, 0644); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -50,7 +49,7 @@ func TestExecute(t *testing.T) {
|
|||||||
infile: "t30-in.txt",
|
infile: "t30-in.txt",
|
||||||
fixture: func(t *testing.T, dir string) {
|
fixture: func(t *testing.T, dir string) {
|
||||||
fname := filepath.Join(dir, "t30-in.txt")
|
fname := filepath.Join(dir, "t30-in.txt")
|
||||||
if err := ioutil.WriteFile(fname, _foo, 0644); err != nil {
|
if err := os.WriteFile(fname, _foo, 0644); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -122,7 +121,7 @@ func TestExecute(t *testing.T) {
|
|||||||
if tt.outfile == "-" {
|
if tt.outfile == "-" {
|
||||||
out = stdout.Bytes()
|
out = stdout.Bytes()
|
||||||
} else {
|
} else {
|
||||||
out, err = ioutil.ReadFile(tt.outfile)
|
out, err = os.ReadFile(tt.outfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
32
release
32
release
@@ -1,39 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
err() {
|
_err(){ >&2 echo "ERROR: $*"; exit 1; }
|
||||||
>&2 echo "ERROR: $*"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
git status --porcelain | grep -q "" &&
|
git status --porcelain | grep -q "" &&
|
||||||
err "working tree is dirty, commit your changes first."
|
_err "working tree is dirty, commit your changes first."
|
||||||
|
|
||||||
# https://raimue.blog/2010/09/09/bash-for-loop-with-glob-patterns/
|
[[ "$1" =~ ^v([0-9]+)\.([0-9]+)(\.([0-9]+))?(-rc([0-9]+))?$ ]] || \
|
||||||
shopt -s nullglob
|
_err "arg1 accepts the following formats: v1.0 v1.0.0 v1.0-rc1 v1.0.1-rc1"
|
||||||
for file in sha256sum-*; do
|
|
||||||
err "found $file from previous release, delete it first"
|
|
||||||
done
|
|
||||||
shopt -u nullglob
|
|
||||||
|
|
||||||
[[ "$1" =~ ^v([0-9]+)\.([0-9]+)(\.([0-9]+))?$ ]] || \
|
|
||||||
err "arg1 accepts the following formats: v1.0 v1.0.0"
|
|
||||||
|
|
||||||
git tag | grep -q "^$1$" &&
|
git tag | grep -q "^$1$" &&
|
||||||
err "tag $1 already exists"
|
_err "tag $1 already exists"
|
||||||
|
|
||||||
|
# sanity test: do the tests pass?
|
||||||
|
make -B -j"$(nproc)" test lint
|
||||||
|
|
||||||
last_tag=$(git tag | tail -1)
|
last_tag=$(git tag | tail -1)
|
||||||
|
|
||||||
make -B -j"$(nproc)" VSN="$1" sha256sum-asc
|
|
||||||
|
|
||||||
{
|
{
|
||||||
echo undocker "$1"
|
echo undocker "$1"
|
||||||
echo
|
echo
|
||||||
echo Changelog since "$last_tag":
|
echo Changelog since "$last_tag":
|
||||||
git log --pretty=format:"- [%cn] %s" "$last_tag"..HEAD
|
git log --pretty=format:"- [%an] %s" "$last_tag"..HEAD
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo sha256sums of released binaries:
|
|
||||||
cat sha256sum-*.txt
|
|
||||||
echo
|
|
||||||
} | git tag -u motiejus@jakstys.lt -F - "$1"
|
} | git tag -u motiejus@jakstys.lt -F - "$1"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ func Flatten(rd io.ReadSeeker, w io.Writer) (_err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
layerOffsets[hdr.Name] = here
|
layerOffsets[strings.TrimPrefix(hdr.Name, "./")] = here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ func Flatten(rd io.ReadSeeker, w io.Writer) (_err error) {
|
|||||||
for i, name := range manifest[0].Layers {
|
for i, name := range manifest[0].Layers {
|
||||||
layers[i] = nameOffset{
|
layers[i] = nameOffset{
|
||||||
name: name,
|
name: name,
|
||||||
offset: layerOffsets[name],
|
offset: layerOffsets[strings.TrimPrefix(name, "./")],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user