From 159202416c0e299d1d5b52503d5b15f825789ba7 Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Mon, 6 Mar 2017 21:25:11 +0000 Subject: [PATCH] Out with the old, in with the new Moby - remove remainder of editions code - add a new check container to run tests without Docker - switch over `make test` to use new command to build tests Signed-off-by: Justin Cormack --- .datakitci.json | 2 +- .gitignore | 1 + Makefile | 137 +- alpine/.gitignore | 1 - alpine/Dockerfile | 59 - alpine/Makefile | 85 -- alpine/containers/Makefile | 10 - alpine/containers/binfmt/Makefile | 14 - alpine/containers/rng-tools/Makefile | 14 - alpine/etc/dhcpcd.conf | 46 - alpine/etc/fstab | 2 - alpine/etc/init.d/fsck | 12 - alpine/etc/init.d/sysctl | 41 - alpine/etc/init.d/sysklogd | 76 - alpine/etc/inittab | 11 - alpine/etc/issue | 12 - alpine/etc/motd | 1 - alpine/etc/network/interfaces | 2 - alpine/etc/periodic/15min/trim | 11 - alpine/etc/periodic/weekly/trim | 4 - alpine/etc/sysctl.d/01-moby.conf | 22 - alpine/etc/sysctl.d/cloud/security.conf | 2 - alpine/etc/sysfs.d/01-moby.conf | 3 - alpine/etc/syslog.conf | 29 - alpine/init | 44 - alpine/packages/9pmount-vsock/.gitignore | 1 - alpine/packages/9pmount-vsock/9pmount-vsock.c | 248 ---- alpine/packages/9pmount-vsock/Makefile | 12 - alpine/packages/9pmount-vsock/hvsock.c | 37 - alpine/packages/9pmount-vsock/hvsock.h | 48 - alpine/packages/Makefile | 10 - .../packages/automount/etc/init.d/automount | 185 --- .../packages/chronyd/etc/chrony/chrony.conf | 5 - alpine/packages/chronyd/etc/init.d/chronyd | 91 -- .../packages/containerd/etc/init.d/containerd | 34 - alpine/packages/diagnostics/.gitignore | 1 - alpine/packages/diagnostics/Makefile | 14 - alpine/packages/diagnostics/capture.go | 214 --- .../diagnostics/etc/init.d/diagnostics | 11 - .../diagnostics/etc/init.d/diagnostics-server | 30 - alpine/packages/diagnostics/http.go | 225 --- alpine/packages/diagnostics/hvsock.go | 26 - alpine/packages/diagnostics/main.go | 63 - alpine/packages/diagnostics/rawtcp.go | 21 - .../diagnostics/system_log_capture.go | 90 -- alpine/packages/diagnostics/tar_respond.go | 40 - .../packages/diagnostics/usr/bin/diagnostics | 46 - alpine/packages/diagnostics/vsock.go | 25 - alpine/packages/docker/.gitignore | 1 - alpine/packages/docker/Makefile | 69 - alpine/packages/docker/etc/init.d/docker | 143 -- .../hostsettings/etc/init.d/hostsettings | 22 - alpine/packages/iptables/.gitignore | 1 - alpine/packages/iptables/Makefile | 13 - .../mobyconfig/etc/init.d/database-aws | 29 - .../mobyconfig/etc/init.d/database-gcp | 27 - .../mobyconfig/etc/init.d/database-mac | 24 - .../mobyconfig/etc/init.d/database-windows | 23 - alpine/packages/mobyconfig/usr/bin/mobyconfig | 80 -- .../mobyplatform/usr/bin/mobyplatform | 21 - alpine/packages/nc-vsock/.gitignore | 1 - alpine/packages/nc-vsock/COMMIT.txt | 20 - alpine/packages/nc-vsock/Makefile | 12 - alpine/packages/nc-vsock/nc-vsock.c | 491 ------- alpine/packages/nc-vsock/vm_sockets.h | 161 --- alpine/packages/oom/etc/init.d/oom | 21 - alpine/packages/proxy/.gitignore | 3 - alpine/packages/proxy/LICENSE | 202 --- alpine/packages/proxy/Makefile | 21 - alpine/packages/proxy/README.md | 11 - alpine/packages/proxy/etc/init.d/proxy | 46 - .../proxy/libproxy/network_proxy_test.go | 216 --- alpine/packages/proxy/libproxy/proxy.go | 73 - alpine/packages/proxy/libproxy/stub_proxy.go | 31 - alpine/packages/proxy/libproxy/tcp_proxy.go | 106 -- .../proxy/libproxy/udp_encapsulation.go | 202 --- alpine/packages/proxy/libproxy/udp_proxy.go | 165 --- alpine/packages/proxy/main.go | 14 - alpine/packages/proxy/many.go | 117 -- alpine/packages/proxy/one.go | 105 -- alpine/packages/proxy/proxy.go | 85 -- alpine/packages/tap-vsockd/.gitignore | 1 - alpine/packages/tap-vsockd/Makefile | 12 - .../packages/tap-vsockd/etc/init.d/tap-vsockd | 48 - alpine/packages/tap-vsockd/hvsock.c | 40 - alpine/packages/tap-vsockd/hvsock.h | 48 - alpine/packages/tap-vsockd/protocol.c | 231 --- alpine/packages/tap-vsockd/protocol.h | 59 - alpine/packages/tap-vsockd/ring.c | 269 ---- alpine/packages/tap-vsockd/ring.h | 35 - alpine/packages/tap-vsockd/tap-vsockd.c | 727 ---------- alpine/packages/test/etc/init.d/test | 25 - alpine/packages/transfused/.gitignore | 1 - alpine/packages/transfused/Makefile | 12 - .../packages/transfused/etc/init.d/transfused | 40 - alpine/packages/transfused/transfused.c | 1246 ----------------- alpine/packages/transfused/transfused.h | 86 -- alpine/packages/transfused/transfused_log.c | 257 ---- alpine/packages/transfused/transfused_log.h | 26 - .../packages/transfused/transfused_perfstat.c | 173 --- .../packages/transfused/transfused_perfstat.h | 29 - alpine/packages/transfused/transfused_vsock.c | 106 -- alpine/packages/transfused/transfused_vsock.h | 7 - alpine/packages/transfused/vm_sockets.h | 161 --- alpine/packages/userns/etc/subgid | 1 - alpine/packages/userns/etc/subuid | 1 - .../github.com/rneugeba/virtsock/go/LICENSE | 71 - .../rneugeba/virtsock/go/examples/client.go | 49 - .../rneugeba/virtsock/go/examples/hvgoecho.go | 131 -- .../virtsock/go/examples/hvgostress.go | 243 ---- .../rneugeba/virtsock/go/hvsock/hvsock.go | 414 ------ .../virtsock/go/hvsock/hvsock_darwin.go | 70 - .../virtsock/go/hvsock/hvsock_linux.go | 147 -- .../virtsock/go/hvsock/hvsock_windows.go | 309 ---- .../virtsock/go/hvsock/zsyscall_windows.go | 100 -- .../rneugeba/virtsock/go/vsock/vsock_linux.go | 195 --- alpine/packages/vendor/manifest | 14 - alpine/packages/vsudd/.gitignore | 1 - alpine/packages/vsudd/Makefile | 14 - alpine/packages/vsudd/etc/init.d/vsudd | 55 - alpine/packages/vsudd/main.go | 239 ---- alpine/packages/vsudd/vsyslog.go | 179 --- .../packages/windowsnet/etc/init.d/windowsnet | 30 - alpine/test/Makefile | 23 - alpine/usr/lib/dhcpcd/dhcpcd-hooks/10-mtu | 38 - base/init/etc/init.d/containers | 26 +- moby/config.go => config.go | 21 +- moby/main.go => main.go | 34 +- moby/moby.yaml => moby.yaml | 4 +- moby/output.go => output.go | 16 +- pkg/initrd/initrd.go | 8 +- scripts/hyperkit.sh | 15 +- test.yaml | 20 + tools/check/Dockerfile | 5 + tools/check/Makefile | 29 + tools/check/check-kernel-config.sh | 70 + tools/check/check.sh | 12 + tools/go-compile/Dockerfile | 10 +- tools/go-compile/Makefile | 4 +- tools/go-compile/compile.sh | 18 +- {base => tools}/qemu/Dockerfile | 0 {base => tools}/qemu/Makefile | 0 {base => tools}/qemu/qemu.sh | 2 +- 143 files changed, 280 insertions(+), 10651 deletions(-) delete mode 100644 alpine/.gitignore delete mode 100644 alpine/Dockerfile delete mode 100644 alpine/Makefile delete mode 100644 alpine/containers/Makefile delete mode 100644 alpine/containers/binfmt/Makefile delete mode 100644 alpine/containers/rng-tools/Makefile delete mode 100644 alpine/etc/dhcpcd.conf delete mode 100644 alpine/etc/fstab delete mode 100755 alpine/etc/init.d/fsck delete mode 100755 alpine/etc/init.d/sysctl delete mode 100755 alpine/etc/init.d/sysklogd delete mode 100644 alpine/etc/inittab delete mode 100644 alpine/etc/issue delete mode 100644 alpine/etc/motd delete mode 100644 alpine/etc/network/interfaces delete mode 100755 alpine/etc/periodic/15min/trim delete mode 100755 alpine/etc/periodic/weekly/trim delete mode 100644 alpine/etc/sysctl.d/01-moby.conf delete mode 100644 alpine/etc/sysctl.d/cloud/security.conf delete mode 100644 alpine/etc/sysfs.d/01-moby.conf delete mode 100644 alpine/etc/syslog.conf delete mode 100755 alpine/init delete mode 100644 alpine/packages/9pmount-vsock/.gitignore delete mode 100644 alpine/packages/9pmount-vsock/9pmount-vsock.c delete mode 100644 alpine/packages/9pmount-vsock/Makefile delete mode 100644 alpine/packages/9pmount-vsock/hvsock.c delete mode 100644 alpine/packages/9pmount-vsock/hvsock.h delete mode 100644 alpine/packages/Makefile delete mode 100755 alpine/packages/automount/etc/init.d/automount delete mode 100644 alpine/packages/chronyd/etc/chrony/chrony.conf delete mode 100755 alpine/packages/chronyd/etc/init.d/chronyd delete mode 100755 alpine/packages/containerd/etc/init.d/containerd delete mode 100644 alpine/packages/diagnostics/.gitignore delete mode 100644 alpine/packages/diagnostics/Makefile delete mode 100644 alpine/packages/diagnostics/capture.go delete mode 100755 alpine/packages/diagnostics/etc/init.d/diagnostics delete mode 100755 alpine/packages/diagnostics/etc/init.d/diagnostics-server delete mode 100644 alpine/packages/diagnostics/http.go delete mode 100644 alpine/packages/diagnostics/hvsock.go delete mode 100644 alpine/packages/diagnostics/main.go delete mode 100644 alpine/packages/diagnostics/rawtcp.go delete mode 100644 alpine/packages/diagnostics/system_log_capture.go delete mode 100644 alpine/packages/diagnostics/tar_respond.go delete mode 100755 alpine/packages/diagnostics/usr/bin/diagnostics delete mode 100644 alpine/packages/diagnostics/vsock.go delete mode 100644 alpine/packages/docker/.gitignore delete mode 100644 alpine/packages/docker/Makefile delete mode 100755 alpine/packages/docker/etc/init.d/docker delete mode 100755 alpine/packages/hostsettings/etc/init.d/hostsettings delete mode 100644 alpine/packages/iptables/.gitignore delete mode 100644 alpine/packages/iptables/Makefile delete mode 100755 alpine/packages/mobyconfig/etc/init.d/database-aws delete mode 100755 alpine/packages/mobyconfig/etc/init.d/database-gcp delete mode 100755 alpine/packages/mobyconfig/etc/init.d/database-mac delete mode 100755 alpine/packages/mobyconfig/etc/init.d/database-windows delete mode 100755 alpine/packages/mobyconfig/usr/bin/mobyconfig delete mode 100755 alpine/packages/mobyplatform/usr/bin/mobyplatform delete mode 100644 alpine/packages/nc-vsock/.gitignore delete mode 100644 alpine/packages/nc-vsock/COMMIT.txt delete mode 100644 alpine/packages/nc-vsock/Makefile delete mode 100644 alpine/packages/nc-vsock/nc-vsock.c delete mode 100644 alpine/packages/nc-vsock/vm_sockets.h delete mode 100755 alpine/packages/oom/etc/init.d/oom delete mode 100644 alpine/packages/proxy/.gitignore delete mode 100644 alpine/packages/proxy/LICENSE delete mode 100644 alpine/packages/proxy/Makefile delete mode 100644 alpine/packages/proxy/README.md delete mode 100755 alpine/packages/proxy/etc/init.d/proxy delete mode 100644 alpine/packages/proxy/libproxy/network_proxy_test.go delete mode 100644 alpine/packages/proxy/libproxy/proxy.go delete mode 100644 alpine/packages/proxy/libproxy/stub_proxy.go delete mode 100644 alpine/packages/proxy/libproxy/tcp_proxy.go delete mode 100644 alpine/packages/proxy/libproxy/udp_encapsulation.go delete mode 100644 alpine/packages/proxy/libproxy/udp_proxy.go delete mode 100644 alpine/packages/proxy/main.go delete mode 100644 alpine/packages/proxy/many.go delete mode 100644 alpine/packages/proxy/one.go delete mode 100644 alpine/packages/proxy/proxy.go delete mode 100644 alpine/packages/tap-vsockd/.gitignore delete mode 100644 alpine/packages/tap-vsockd/Makefile delete mode 100755 alpine/packages/tap-vsockd/etc/init.d/tap-vsockd delete mode 100644 alpine/packages/tap-vsockd/hvsock.c delete mode 100644 alpine/packages/tap-vsockd/hvsock.h delete mode 100644 alpine/packages/tap-vsockd/protocol.c delete mode 100644 alpine/packages/tap-vsockd/protocol.h delete mode 100644 alpine/packages/tap-vsockd/ring.c delete mode 100644 alpine/packages/tap-vsockd/ring.h delete mode 100644 alpine/packages/tap-vsockd/tap-vsockd.c delete mode 100755 alpine/packages/test/etc/init.d/test delete mode 100644 alpine/packages/transfused/.gitignore delete mode 100644 alpine/packages/transfused/Makefile delete mode 100755 alpine/packages/transfused/etc/init.d/transfused delete mode 100644 alpine/packages/transfused/transfused.c delete mode 100644 alpine/packages/transfused/transfused.h delete mode 100644 alpine/packages/transfused/transfused_log.c delete mode 100644 alpine/packages/transfused/transfused_log.h delete mode 100644 alpine/packages/transfused/transfused_perfstat.c delete mode 100644 alpine/packages/transfused/transfused_perfstat.h delete mode 100644 alpine/packages/transfused/transfused_vsock.c delete mode 100644 alpine/packages/transfused/transfused_vsock.h delete mode 100644 alpine/packages/transfused/vm_sockets.h delete mode 100644 alpine/packages/userns/etc/subgid delete mode 100644 alpine/packages/userns/etc/subuid delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/LICENSE delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/client.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go delete mode 100644 alpine/packages/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go delete mode 100644 alpine/packages/vendor/manifest delete mode 100644 alpine/packages/vsudd/.gitignore delete mode 100644 alpine/packages/vsudd/Makefile delete mode 100755 alpine/packages/vsudd/etc/init.d/vsudd delete mode 100644 alpine/packages/vsudd/main.go delete mode 100644 alpine/packages/vsudd/vsyslog.go delete mode 100755 alpine/packages/windowsnet/etc/init.d/windowsnet delete mode 100644 alpine/test/Makefile delete mode 100644 alpine/usr/lib/dhcpcd/dhcpcd-hooks/10-mtu rename moby/config.go => config.go (78%) rename moby/main.go => main.go (85%) rename moby/moby.yaml => moby.yaml (90%) rename moby/output.go => output.go (78%) create mode 100644 test.yaml create mode 100644 tools/check/Dockerfile create mode 100644 tools/check/Makefile create mode 100755 tools/check/check-kernel-config.sh create mode 100755 tools/check/check.sh rename {base => tools}/qemu/Dockerfile (100%) rename {base => tools}/qemu/Makefile (100%) rename {base => tools}/qemu/qemu.sh (94%) diff --git a/.datakitci.json b/.datakitci.json index 06927b10f..26a5cb992 100644 --- a/.datakitci.json +++ b/.datakitci.json @@ -1 +1 @@ -{"variants":["aufs", "lts4.4"]} +{"variants":[]} diff --git a/.gitignore b/.gitignore index ac89c7744..c3576d537 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ disk.img.* *.tar.gz *.vhdx *.efi +*-bzImage diff --git a/Makefile b/Makefile index b5838e8a0..b82ceadef 100644 --- a/Makefile +++ b/Makefile @@ -1,39 +1,39 @@ -.PHONY: test hyperkit-test qemu qemu-iso media ebpf ci ci-pr get get-regextract +.PHONY: default test hyperkit-test qemu qemu-iso media ebpf ci ci-pr -all: - $(MAKE) -C alpine +default: bin/moby -aufs: - $(MAKE) AUFS=true all +all: default -.PHONY: alpine/initrd.img -alpine/initrd.img: - $(MAKE) -C alpine initrd.img +GO_COMPILE=mobylinux/go-compile:236629d9fc0779db9e7573ceb8b0e92f08f553be@sha256:16020c2d90cecb1f1d2d731187e947535c23f38b62319dd386ae642b4b32e1fb -.PHONY: alpine/initrd-test.img -alpine/initrd-test.img: - $(MAKE) -C alpine initrd-test.img +MOBY_DEPS=$(wildcard *.go) pkg vendor +GOOS=$(shell uname -s | tr '[:upper:]' '[:lower:]') +GOARCH=amd64 +ifneq ($(GOOS),linux) +CROSS=-e GOOS=$(GOOS) -e GOARCH=$(GOARCH) +endif -.PHONY: kernel/x86_64/vmlinuz64 -kernel/x86_64/vmlinuz64: - $(MAKE) -C kernel +bin/moby: $(MOBY_DEPS) | bin + tar cf - $(MOBY_DEPS) | docker run --rm --net=none --log-driver=none -i $(CROSS) $(GO_COMPILE) --package github.com/docker/moby -o $@ | tar xf - -.PHONY: alpine/mobylinux-bios.iso -alpine/mobylinux-bios.iso: - $(MAKE) -C alpine mobylinux-bios.iso +QEMU_IMAGE=mobylinux/qemu:156d2160c2ccf4d5118221bc2708f6c0981d54cc@sha256:e1345ba0400d6c45bf3bdf4f4ed425c3d7596d11e6553b83f17f5893dfc49f7b -.PHONY: alpine/mobylinux-efi.iso -alpine/mobylinux-efi.iso: - $(MAKE) -C alpine mobylinux-efi.iso +moby-initrd.img: bin/moby moby.yaml + $^ -QEMU_IMAGE=mobylinux/qemu:0fb8c648e8ed9ef6b1ec449587aeab6c53872744@sha256:606f30d815102e73bc01c07915dc0d5f153b0252c63f5f0ed1e39621ec656eb5 +moby-bzImage: moby-initrd.img + +test-initrd.img: bin/moby test.yaml + $^ + +test-bzImage: test-initrd.img # interactive versions need to use volume mounts -qemu: alpine/initrd.img kernel/x86_64/vmlinuz64 - docker run -it --rm -v $(CURDIR)/alpine/initrd.img:/tmp/initrd.img -v $(CURDIR)/kernel/x86_64/vmlinuz64:/tmp/vmlinuz64 $(QEMU_IMAGE) +qemu: moby-initrd.img + docker run -it --rm -v $(CURDIR)/moby-initrd.img:/tmp/initrd.img -v $(CURDIR)/moby-bzImage:/tmp/vmlinuz64 $(QEMU_IMAGE) qemu-iso: alpine/mobylinux-bios.iso - docker run -it --rm -v $(CURDIR)/alpine/mobylinux-bios.iso:/tmp/mobylinux-bios.iso $(QEMU_IMAGE) + docker run -it --rm -v $(CURDIR)/mobylinux-bios.iso:/tmp/mobylinux-bios.iso $(QEMU_IMAGE) bin: mkdir -p $@ @@ -58,10 +58,6 @@ else touch $@ endif -bin/regextract: | bin - curl -fsSL https://circleci.com/api/v1/project/justincormack/regextract/latest/artifacts/0/\$$CIRCLE_ARTIFACTS/darwin/amd64/regextract > $@ - chmod a+x $@ - hyperkit: scripts/hyperkit.sh bin/com.docker.hyperkit bin/vpnkit alpine/initrd.img kernel/x86_64/vmlinuz64 ./scripts/hyperkit.sh @@ -69,54 +65,15 @@ define check_test_log @cat $1 |grep -q 'Moby test suite PASSED' endef -hyperkit-test: scripts/hyperkit.sh bin/com.docker.hyperkit bin/vpnkit alpine/initrd-test.img kernel/x86_64/vmlinuz64 +hyperkit-test: scripts/hyperkit.sh bin/com.docker.hyperkit bin/vpnkit test-initrd.img test-bzImage rm -f disk.img - INITRD=alpine/initrd-test.img script -q /dev/null ./scripts/hyperkit.sh | tee test.log + script -q /dev/null ./scripts/hyperkit.sh test | tee test.log $(call check_test_log, test.log) -test: alpine/initrd-test.img kernel/x86_64/vmlinuz64 +test: test-initrd.img test-bzImage tar cf - $^ | docker run --rm -i $(QEMU_IMAGE) 2>&1 | tee test.log $(call check_test_log, test.log) -ifeq ($(CI_TAG),) -TAG=$(shell git rev-parse HEAD) -else -TAG=$(CI_TAG) -endif - -STATUS=$(shell git status -s) -MOBYLINUX_TAG=alpine/mobylinux.tag -ifdef AUFS -AUFS_PREFIX=aufs- -endif -ifdef LTS4.4 -AUFS_PREFIX=lts4.4- -endif - -MEDIA_IMAGE=mobylinux/media:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) -INITRD_IMAGE=mobylinux/mobylinux:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) -KERNEL_IMAGE=mobylinux/kernel:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) - -MEDIA_TOYBOX=mobylinux/toybox-media:0a26fe5f574e444849983f9c4148ef74b3804d55@sha256:5ac38f77b66deb194c9016591b9b096e81fcdc9f7c3e6d01566294a6b4b4ebd2 - -Dockerfile.media: - printf "FROM $(MEDIA_TOYBOX)\nADD . /\n" > $@ - -MEDIA_TARBALL=Dockerfile.media -C alpine initrd.img initrd-test.img mobylinux-efi.iso mobylinux.efi -C ../kernel/x86_64 vmlinuz64 vmlinux kernel-headers.tar kernel-dev.tar - -media: Dockerfile.media alpine/initrd.img alpine/initrd-test.img kernel/x86_64/vmlinuz64 alpine/mobylinux-efi.iso -ifeq ($(STATUS),) - tar cf - $(MEDIA_TARBALL) | docker build -f Dockerfile.media -t $(MEDIA_IMAGE) - - docker push $(MEDIA_IMAGE) - [ -f $(MOBYLINUX_TAG) ] - docker tag $(shell cat $(MOBYLINUX_TAG)) $(INITRD_IMAGE) - docker push $(INITRD_IMAGE) - tar cf - Dockerfile.media -C kernel/x86_64 bzImage kernel.tar | docker build -f Dockerfile.media -t $(KERNEL_IMAGE) - - docker push $(KERNEL_IMAGE) -else - $(error "git not clean") -endif - EBPF_TAG=ebpf/ebpf.tag EBPF_IMAGE=mobylinux/ebpf:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) ebpf: alpine/initrd.img kernel/x86_64/vmlinuz64 @@ -128,54 +85,22 @@ else $(error "git not clean") endif -MEDIA_FILES=kernel/x86_64/vmlinuz64 kernel/x86_64/vmlinux alpine/initrd.img alpine/mobylinux-efi.iso alpine/mobylinux.efi -MEDIA_FILES_OPT=kernel/x86_64/kernel-headers.tar kernel/x86_64/kernel-dev.tar alpine/initrd-test.img - -get: -ifeq ($(STATUS),) - IMAGE=$$( docker create mobylinux/media:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) /dev/null ) && \ - mkdir -p kernel/x86_64 && \ - for FILE in $(MEDIA_FILES); do docker cp $$IMAGE:$$(basename $$FILE) $$FILE || exit; done; \ - for FILE in $(MEDIA_FILES_OPT); do docker cp $$IMAGE:$$(basename $$FILE) $$FILE; done; \ - docker rm $$IMAGE -else - $(error "git not clean") -endif - -# Get artifacts using regextract for cases where docker is not available -get-regextract: bin/regextract -ifeq ($(STATUS),) - TMP_EXTRACT=$$(mktemp -d) && \ - for FILE in $(MEDIA_FILES) $(MEDIA_FILES_OPT); do mkdir -p $$(dirname $$FILE); done; \ - bin/regextract mobylinux/media:$(MEDIA_PREFIX)$(AUFS_PREFIX)$(TAG) | tar xf - -C $$TMP_EXTRACT && \ - mkdir -p kernel/x86_64 && \ - for FILE in $(MEDIA_FILES); do cp $$TMP_EXTRACT/$$(basename $$FILE) $$FILE || exit; done; \ - for FILE in $(MEDIA_FILES_OPT); do cp $$TMP_EXTRACT/$$(basename $$FILE) $$FILE; done; \ - rm -Rf $$TMP_EXTRACT -else - $(error "git not clean") -endif - ci: $(MAKE) clean - $(MAKE) all + $(MAKE) $(MAKE) test - $(MAKE) media ci-tag: $(MAKE) clean - $(MAKE) all + $(MAKE) $(MAKE) test - $(MAKE) media ci-pr: $(MAKE) clean - $(MAKE) all + $(MAKE) $(MAKE) test .PHONY: clean clean: - $(MAKE) -C alpine clean - $(MAKE) -C kernel clean - rm -rf bin disk.img test.log Dockerfile.media + rm -rf bin disk.img test.log *-initrd.img *-bzImage *.iso diff --git a/alpine/.gitignore b/alpine/.gitignore deleted file mode 100644 index fdc7c4ef5..000000000 --- a/alpine/.gitignore +++ /dev/null @@ -1 +0,0 @@ -etc/moby-commit diff --git a/alpine/Dockerfile b/alpine/Dockerfile deleted file mode 100644 index e59447e7d..000000000 --- a/alpine/Dockerfile +++ /dev/null @@ -1,59 +0,0 @@ -FROM mobylinux/alpine-base:5837a236153f00bb215642e3e0639252eb49cdf9@sha256:f6f12aebe2af07c9250014ff283485dbdf082bd9cfbd74aad27a3d2dcf13e0b1 - -RUN \ - addgroup -g 50 docker && \ - adduser -G docker -u 1001 -s /bin/sh -D -g "Docker" docker && \ - passwd -d root && \ - adduser -D -H -s /sbin/nologin dockremap - -COPY . . -RUN cd /usr/bin && \ - ln -s docker-runc runc && \ - ln -s docker-containerd-shim containerd-shim && \ - ln -s docker-containerd-ctr containerd-ctr && \ - ln -s docker-containerd containerd - -RUN \ - rc-update add sysctl boot && \ - rc-update add bootmisc boot && \ - rc-update add urandom boot && \ - rc-update add hostname boot && \ - rc-update add vsudd boot && \ - rc-update add sysklogd boot && \ - rc-update add hwclock boot && \ - rc-update add tap-vsockd boot && \ - rc-update add networking boot && \ - rc-update add dhcpcd boot && \ - rc-update add acpid default && \ - rc-update add chronyd default && \ - rc-update add savecache shutdown && \ - rc-update add killprocs shutdown && \ - rc-update add mount-ro shutdown && \ - rc-update add dmesg sysinit && \ - rc-update add devfs sysinit && \ - rc-update add hwdrivers sysinit && \ - rc-update add sysfs && \ - rc-update add procfs && \ - rc-update add sysfsconf && \ - rc-update add fsck && \ - rc-update add crond && \ - rc-update add local && \ - rc-update add localmount && \ - rc-update add docker default && \ - rc-update add proxy default && \ - rc-update add transfused default && \ - rc-update add automount sysinit && \ - rc-update add diagnostics default && \ - rc-update add diagnostics-server boot && \ - rc-update add database-mac boot && \ - rc-update add database-windows boot && \ - rc-update add database-aws default && \ - rc-update add database-gcp default && \ - rc-update add hostsettings default && \ - rc-update add windowsnet boot && \ - rc-update add hv_kvp_daemon default && \ - rc-update add hv_vss_daemon default && \ - rc-update add oom default && \ - rc-update add test default && \ - rc-update add containerd default && \ - true diff --git a/alpine/Makefile b/alpine/Makefile deleted file mode 100644 index 540266773..000000000 --- a/alpine/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -all: initrd.img initrd-test.img mobylinux-efi.iso mobylinux-bios.iso - -TAG=$(shell git rev-parse HEAD) -STATUS=$(shell git status -s) -ifeq ($(STATUS),) -DIRTY= -else -DIRTY=-dirty -endif - -# By default we want to always auth to GCE to upload moby images -FORCE_GSUTIL_AUTH ?= 1 - -BIOS_IMAGE=mobylinux/mkimage-iso-bios:2a860edda12a44c8e141a924f29ea931dbc01110@sha256:974304cfff80524a37bf96d299de9b3163ba07df5feeb620c6bdcd132b46f16d - -EFI_IMAGE=mobylinux/mkimage-iso-efi:f81034d118744a42e8e93cfe0777dc3490c1f6a0@sha256:4bb10d794fd0fe58366c36ab0fabf7b6d22e5bd760a994900da3b910230519cc - -PAD4_IMAGE=mobylinux/pad4:1edffcbfa13d4795f006d38e871a778ffba03d8a@sha256:1ad26970698670373ee0bf374a06900f712a61b8038255e78271b840a1267b25 - -TAR2INITRD_IMAGE=mobylinux/tar2initrd:d5711601eb5b89de0f052d87365e18388ff3f1b5@sha256:58d377e65845f91400e173ce9fca93462f2f237947eef2b0d2c17bb4f2da5ee8 - -TARTAR2INITRD_IMAGE=mobylinux/tartar2initrd:d56cde1558e3080e59a32e3cd7c7141baa601811@sha256:e1ad4522ff906d339da5f250b9ef6bffa5a70b4dec7d2cf7f7dbd0447b79352f - -MKIMAGE_BASE=mobylinux/mkimage-base:870f7512498f2ce5feccebe15fb0d03c5c3ebac2@sha256:47d1ed872b6a44f13b61ea80b3eeab4519dc151c7d684a89a53aa26233b4e087 - -moby.img: Dockerfile etc usr init - $(MAKE) -j -C packages - printf $(TAG)$(DIRTY) > etc/moby-commit - BUILD=$$( tar cf - $^ \ - -C packages/proxy usr sbin etc -C ../.. \ - -C packages/transfused sbin etc -C ../.. \ - -C packages/tap-vsockd sbin etc -C ../.. \ - -C packages/docker usr etc -C ../.. \ - -C packages/diagnostics usr etc -C ../.. \ - -C packages/automount etc -C ../.. \ - -C packages/windowsnet etc -C ../.. \ - -C packages/hostsettings etc -C ../.. \ - -C packages/chronyd etc -C ../.. \ - -C packages/userns etc -C ../.. \ - -C packages/nc-vsock usr -C ../.. \ - -C packages/vsudd sbin etc -C ../.. \ - -C packages/mobyconfig etc usr -C ../.. \ - -C packages/mobyplatform usr -C ../.. \ - -C packages/oom etc -C ../.. \ - -C packages/9pmount-vsock sbin -C ../.. \ - -C packages/test etc -C ../.. \ - -C packages/iptables usr -C ../.. \ - -C packages/containerd etc -C ../.. \ - | \ - docker build -q - ) && [ -n "$$BUILD" ] && echo "Built $$BUILD" && \ - echo $$BUILD > mobylinux.tag && \ - docker run --rm --read-only --net=none --log-driver=none --tmpfs /tmp -v /var/run/docker.sock:/var/run/docker.sock $(MKIMAGE_BASE) $$BUILD | \ - docker run --rm --read-only --net=none --log-driver=none --tmpfs /tmp -i $(TAR2INITRD_IMAGE) > $@ - -container.img: - $(MAKE) -C containers - tar cf - containers/*/container.tar | \ - docker run --rm --read-only --net=none --log-driver=none --tmpfs /tmp -i $(TARTAR2INITRD_IMAGE) > $@ - -test/test.img: - $(MAKE) -C test - -../kernel/x86_64/kernel.img: - $(MAKE) -C ../kernel - -initrd.img: moby.img ../kernel/x86_64/kernel.img container.img - cat $^ > $@ - -initrd-test.img: initrd.img test/test.img - cat $^ > $@ - -# outputs tarball of mobylinux-efi.iso mobylinux.efi -mobylinux-efi.iso: initrd.img ../kernel/x86_64/vmlinuz64 - tar cf - initrd.img -C ../kernel/x86_64 vmlinuz64 | docker run --rm --net=none --log-driver=none -i $(EFI_IMAGE) | tar xf - - -mobylinux-bios.iso: initrd.img ../kernel/x86_64/vmlinuz64 - tar cf - initrd.img -C ../kernel/x86_64 vmlinuz64 | docker run --rm --net=none --log-driver=none -i $(BIOS_IMAGE) >$@ - -clean: - rm -f *.img *.vhd *.iso *.tag mobylinux.efi etc/moby-commit - $(MAKE) -C packages clean - $(MAKE) -C containers clean - $(MAKE) -C test clean - -.DELETE_ON_ERROR: diff --git a/alpine/containers/Makefile b/alpine/containers/Makefile deleted file mode 100644 index d83a72eec..000000000 --- a/alpine/containers/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -DIRS=$(wildcard */) -.PHONY: clean $(DIRS) - -default: $(DIRS) - -$(DIRS): - $(MAKE) -C $@ - -clean: - for f in $(DIRS); do $(MAKE) -C $$f clean; done diff --git a/alpine/containers/binfmt/Makefile b/alpine/containers/binfmt/Makefile deleted file mode 100644 index 4d0951a31..000000000 --- a/alpine/containers/binfmt/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -RIDDLER=mobylinux/riddler:7d4545d8b8ac2700971a83f12a3446a76db28c14@sha256:11b7310df6482fc38aa52b419c2ef1065d7b9207c633d47554e13aa99f6c0b72 - -BINFMT_IMAGE=mobylinux/binfmt:a94e0587b702edaa95cc6f303464959d0eb2311c@sha256:432732b90cbe0498f5ca148d75b90bb1eabd8fbfe8c872df8b23906c225091b1 - -default: container.tar - -container.tar: - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock $(RIDDLER) \ - $(BINFMT_IMAGE) /containers/binfmt --cap-drop all --read-only -v /proc/sys/fs/binfmt_misc:/binfmt_misc $(BINFMT_IMAGE) /usr/bin/binfmt -dir /etc/binfmt.d/ -mount /binfmt_misc >$@ - -clean: - rm -f container.tar - -.DELETE_ON_ERROR: diff --git a/alpine/containers/rng-tools/Makefile b/alpine/containers/rng-tools/Makefile deleted file mode 100644 index 144de3499..000000000 --- a/alpine/containers/rng-tools/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -RIDDLER=mobylinux/riddler:7d4545d8b8ac2700971a83f12a3446a76db28c14@sha256:11b7310df6482fc38aa52b419c2ef1065d7b9207c633d47554e13aa99f6c0b72 - -RNGD_IMAGE=mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9@sha256:1c93c1db7196f6f71f8e300bc1d15f0376dd18e8891c8789d77c8ff19f3a9a92 - -default: container.tar - -container.tar: - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock $(RIDDLER) \ - $(RNGD_IMAGE) /containers/rngd --cap-drop all --cap-add SYS_ADMIN --read-only --oom-score-adj -800 $(RNGD_IMAGE) /bin/tini /usr/sbin/rngd -f >$@ - -clean: - rm -f container.tar - -.DELETE_ON_ERROR: diff --git a/alpine/etc/dhcpcd.conf b/alpine/etc/dhcpcd.conf deleted file mode 100644 index e06ace538..000000000 --- a/alpine/etc/dhcpcd.conf +++ /dev/null @@ -1,46 +0,0 @@ -# Moby dhcpcd config - -# Only configure standard external ethernet -allowinterfaces eth* - -# Inform the DHCP server of our hostname for DDNS. -hostname - -# Use the hardware address of the interface for the Client ID. -clientid -# or -# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361. -# Some non-RFC compliant DHCP servers do not reply with this set. -# In this case, comment out duid and enable clientid above. -#duid - -# Persist interface configuration when dhcpcd exits. -persistent - -# Rapid commit support. -# Safe to enable by default because it requires the equivalent option set -# on the server to actually work. -option rapid_commit - -# A list of options to request from the DHCP server. -option domain_name_servers, domain_name, domain_search, host_name -option classless_static_routes -# Most distributions have NTP support. -# option ntp_servers -# Respect the network MTU. This is applied to DHCP routes. -option interface_mtu - -# A ServerID is required by RFC2131. -require dhcp_server_identifier - -# Generate Stable Private IPv6 Addresses instead of hardware based ones -slaac private - -# Do not wait -nodelay - -# Do not arp to check IP -noarp - -# Only fork when we have ipv4 -waitip 4 diff --git a/alpine/etc/fstab b/alpine/etc/fstab deleted file mode 100644 index aa5a6fbde..000000000 --- a/alpine/etc/fstab +++ /dev/null @@ -1,2 +0,0 @@ -tmpfs /run tmpfs defaults,nodev,nosuid,noexec,relatime,size=10%,mode=755 0 0 -tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec,relatime,size=10%,mode=1777 0 0 diff --git a/alpine/etc/init.d/fsck b/alpine/etc/init.d/fsck deleted file mode 100755 index 5a82b6aaa..000000000 --- a/alpine/etc/init.d/fsck +++ /dev/null @@ -1,12 +0,0 @@ -#!/sbin/openrc-run -# do nothing as we do this in automount script - -start() -{ - return 0 -} - -stop() -{ - return 0 -} diff --git a/alpine/etc/init.d/sysctl b/alpine/etc/init.d/sysctl deleted file mode 100755 index 421dd8e3d..000000000 --- a/alpine/etc/init.d/sysctl +++ /dev/null @@ -1,41 +0,0 @@ -#!/sbin/openrc-run -# Copyright (c) 2007-2015 The OpenRC Authors. -# See the Authors file at the top-level directory of this distribution and -# https://github.com/OpenRC/openrc/blob/master/AUTHORS -# -# This file is part of OpenRC. It is subject to the license terms in -# the LICENSE file found in the top-level directory of this -# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE -# This file may not be copied, modified, propagated, or distributed -# except according to the terms contained in the LICENSE file. - -depend() -{ - before bootmisc logger - keyword -prefix -systemd-nspawn -vserver -} - -start() -{ - local quiet rc=0 - yesno $rc_verbose || quiet=-q - - ebegin "Configuring kernel parameters" - set -- - # Do additional sysctl configuration for cloud editions - [ "$(mobyplatform)" != "mac" ] && [ "$(mobyplatform)" != "windows" ] && CLOUD=/etc/sysctl.d/cloud/*.conf - for i in /run/sysctl.d/*.conf \ - /etc/sysctl.d/*.conf \ - /usr/local/lib/sysctl.d/*.conf \ - /usr/lib/sysctl.d/*.conf \ - /lib/sysctl.d/*.conf \ - /etc/sysctl.conf \ - $CLOUD; do - if [ -e "$i" ]; then - sysctl ${quiet} -p "$i" - rc=$(( $rc + $? )) - fi - done - - eend $rc "Unable to configure some kernel parameters" -} \ No newline at end of file diff --git a/alpine/etc/init.d/sysklogd b/alpine/etc/init.d/sysklogd deleted file mode 100755 index 0945fa49b..000000000 --- a/alpine/etc/init.d/sysklogd +++ /dev/null @@ -1,76 +0,0 @@ -#!/sbin/openrc-run -# Copyright 1999-2011 Gentoo Foundation -# Distributed under the terms of the GNU General Public License, v2 or later -# $Header: /var/cvsroot/gentoo-x86/app-admin/sysklogd/files/sysklogd.rc7,v 1.1 2011/09/14 22:22:57 polynomial-c Exp $ - -extra_started_commands="reload" - -depend() { - need clock hostname localmount vsudd bootmisc - before net - provide logger -} - -start_daemon() { - local retval=0 - local daemon="$1" - local options="$2" - - [ -z "${daemon}" ] && return 1 - - ebegin "sysklogd -> start: ${daemon}" - start-stop-daemon --start --exec /usr/sbin/"${daemon}" \ - --pidfile /var/run/"${daemon}".pid -- ${options} - retval=$? - eend ${retval} "Failed to start ${daemon}" - - return ${retval} -} - -stop_daemon() { - local retval=0 - local daemon="$1" - - [ -z "${daemon}" ] && return 1 - - ebegin "sysklogd -> stop: ${daemon}" - # syslogd can be stubborn some times (--retry 15)... - start-stop-daemon --stop --retry 15 --quiet --pidfile /var/run/"${daemon}".pid - retval=$? - eend ${retval} "Failed to stop ${daemon}" - - return ${retval} -} - -start() { - start_daemon "syslogd" "${SYSLOGD}" || return 1 - - # klogd do not always start proper if started too early - sleep 1 - - if ! start_daemon "klogd" "${KLOGD}" ; then - stop_daemon "syslogd" - return 1 - fi - - return 0 -} - -stop() { - stop_daemon "klogd" || return 1 - stop_daemon "syslogd" || return 1 - return 0 -} - -reload() { - local ret=0 - - ebegin "Reloading configuration" - - start-stop-daemon --signal HUP --pidfile /var/run/syslogd.pid - ret=$((${ret} + $?)) - start-stop-daemon --signal USR1 --pidfile /var/run/klogd.pid - ret=$((${ret} + $?)) - - eend ${ret} -} diff --git a/alpine/etc/inittab b/alpine/etc/inittab deleted file mode 100644 index 547a1951f..000000000 --- a/alpine/etc/inittab +++ /dev/null @@ -1,11 +0,0 @@ -# /etc/inittab - -::sysinit:/sbin/openrc sysinit -::sysinit:/sbin/openrc boot -::wait:/sbin/openrc default - -# Stuff to do for the 3-finger salute -::ctrlaltdel:/sbin/reboot - -# Stuff to do before rebooting -::shutdown:/sbin/openrc shutdown diff --git a/alpine/etc/issue b/alpine/etc/issue deleted file mode 100644 index f5a95ea49..000000000 --- a/alpine/etc/issue +++ /dev/null @@ -1,12 +0,0 @@ - -Welcome to Moby - - ## . - ## ## ## == - ## ## ## ## ## === - /"""""""""""""""""\___/ === - ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~ - \______ o __/ - \ \ __/ - \____\_______/ - diff --git a/alpine/etc/motd b/alpine/etc/motd deleted file mode 100644 index dd7798d75..000000000 --- a/alpine/etc/motd +++ /dev/null @@ -1 +0,0 @@ -Welcome to Moby diff --git a/alpine/etc/network/interfaces b/alpine/etc/network/interfaces deleted file mode 100644 index f1bd92ed2..000000000 --- a/alpine/etc/network/interfaces +++ /dev/null @@ -1,2 +0,0 @@ -auto lo -iface lo inet loopback diff --git a/alpine/etc/periodic/15min/trim b/alpine/etc/periodic/15min/trim deleted file mode 100755 index b11ae6074..000000000 --- a/alpine/etc/periodic/15min/trim +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# Windows and Mac have TRIM support, clean out unused frequently -case "$(mobyplatform)" in - "windows") - /sbin/fstrim /var - ;; - "mac") - mobyconfig exists disk/trim && [ "$(mobyconfig get disk/trim)" = "true" ] && /sbin/fstrim /var - ;; -esac diff --git a/alpine/etc/periodic/weekly/trim b/alpine/etc/periodic/weekly/trim deleted file mode 100755 index 95c03d9f0..000000000 --- a/alpine/etc/periodic/weekly/trim +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# TODO check with hdparm if supports TRIM -/sbin/fstrim /var || true diff --git a/alpine/etc/sysctl.d/01-moby.conf b/alpine/etc/sysctl.d/01-moby.conf deleted file mode 100644 index 49ffed8ad..000000000 --- a/alpine/etc/sysctl.d/01-moby.conf +++ /dev/null @@ -1,22 +0,0 @@ -# general limits -vm.max_map_count = 262144 -vm.overcommit_memory = 1 -net.core.somaxconn = 1024 -net.ipv4.neigh.default.gc_thresh1 = 30000 -net.ipv4.neigh.default.gc_thresh2 = 32000 -net.ipv4.neigh.default.gc_thresh3 = 32768 -fs.aio-max-nr = 1048576 -fs.inotify.max_user_watches = 524288 -fs.file-max = 524288 -# for rngd -kernel.random.write_wakeup_threshold = 3072 -# security restrictions -kernel.kptr_restrict = 2 -net.ipv4.conf.all.send_redirects = 0 -net.ipv4.conf.default.accept_redirects = 0 -net.ipv4.conf.default.accept_source_route = 0 -net.ipv6.conf.all.accept_redirects = 0 -net.ipv6.conf.default.accept_redirects = 0 -kernel.perf_event_paranoid = 3 -fs.protected_hardlinks = 1 -fs.protected_symlinks = 1 diff --git a/alpine/etc/sysctl.d/cloud/security.conf b/alpine/etc/sysctl.d/cloud/security.conf deleted file mode 100644 index 248489374..000000000 --- a/alpine/etc/sysctl.d/cloud/security.conf +++ /dev/null @@ -1,2 +0,0 @@ -kernel.modules_disabled=1 -kernel.sysrq = 0 \ No newline at end of file diff --git a/alpine/etc/sysfs.d/01-moby.conf b/alpine/etc/sysfs.d/01-moby.conf deleted file mode 100644 index fe8a92b9c..000000000 --- a/alpine/etc/sysfs.d/01-moby.conf +++ /dev/null @@ -1,3 +0,0 @@ -fs/cgroup/memory/memory.use_hierarchy = 1 -kernel/mm/transparent_hugepage/enabled = madvise -kernel/mm/transparent_hugepage/defrag = madvise diff --git a/alpine/etc/syslog.conf b/alpine/etc/syslog.conf deleted file mode 100644 index b74275b6c..000000000 --- a/alpine/etc/syslog.conf +++ /dev/null @@ -1,29 +0,0 @@ -# /etc/syslog.conf Configuration file for syslogd. -# -# For more information see syslog.conf(5) -# manpage. - -# First some standard logfiles. Log by facility. -# - -auth,authpriv.* /var/log/auth.log -*.*;auth,authpriv.none -/var/log/syslog -cron.* /var/log/cron.log -daemon.* -/var/log/daemon.log -kern.* -/var/log/kern.log -lpr.* -/var/log/lpr.log -mail.* -/var/log/mail.log -user.* -/var/log/user.log - -# Local facilities for our programs -local0.* -/var/log/docker.log - -# Some `catch-all' logfiles. -# -*.=debug;\ - auth,authpriv.none;\ - news.none;mail.none -/var/log/debug -*.=info;*.=notice;*.=warning;\ - auth,authpriv.none;\ - cron,daemon.none;\ - mail,news.none -/var/log/messages diff --git a/alpine/init b/alpine/init deleted file mode 100755 index 46c52bceb..000000000 --- a/alpine/init +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh - -setup_console() { - tty=${1%,*} - speed=${1#*,} - inittab="$2" - securetty="$3" - line= - term="linux" - [ "$speed" = "$1" ] && speed=115200 - - case "$tty" in - ttyS*|ttyAMA*|ttyUSB*|ttyMFD*) - line="-L" - term="vt100" - ;; - tty0) - # skip current console - return 0 - ;; - esac - # skip consoles already in inittab - grep -q "^$tty:" "$inittab" && return - - echo "$tty::once:cat /etc/issue" >> "$inittab" - echo "$tty::respawn:/sbin/getty -n -l /bin/sh $line $speed $tty $term" >> "$inittab" - if ! grep -q -w "$tty" "$securetty"; then - echo "$tty" >> "$securetty" - fi -} - -/bin/mount -t tmpfs tmpfs /mnt - -/bin/cp -a / /mnt 2>/dev/null - -/bin/mount -t proc -o noexec,nosuid,nodev proc /proc -for opt in $(cat /proc/cmdline); do - case "$opt" in - console=*) - setup_console ${opt#console=} /mnt/etc/inittab /mnt/etc/securetty;; - esac -done - -exec /bin/busybox switch_root /mnt /sbin/init diff --git a/alpine/packages/9pmount-vsock/.gitignore b/alpine/packages/9pmount-vsock/.gitignore deleted file mode 100644 index 5b42612bc..000000000 --- a/alpine/packages/9pmount-vsock/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sbin/ diff --git a/alpine/packages/9pmount-vsock/9pmount-vsock.c b/alpine/packages/9pmount-vsock/9pmount-vsock.c deleted file mode 100644 index 4ecebb24a..000000000 --- a/alpine/packages/9pmount-vsock/9pmount-vsock.c +++ /dev/null @@ -1,248 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hvsock.h" - -#define NONE 0 -#define LISTEN 1 -#define CONNECT 2 - -int mode = NONE; - -char *default_sid = "C378280D-DA14-42C8-A24E-0DE92A1028E2"; -char *mount = "/bin/mount"; - -void fatal(const char *msg) -{ - syslog(LOG_CRIT, "%s Error: %d. %s", msg, errno, strerror(errno)); - exit(1); -} - -static int handle(int fd, char *tag, char *path) -{ - char *options = NULL; - int status; - pid_t pid; - int res; - - res = asprintf(&options, - "trans=fd,dfltuid=1001,dfltgid=50,version=9p2000,msize=4096,rfdno=%d,wfdno=%d", - fd, fd); - if (res < 0) - fatal("asprintf()"); - - char *argv[] = { - mount, - "-t", "9p", "-o", options, - tag, path, - NULL - }; - - pid = fork(); - if (pid == 0) { - execv(mount, argv); - fatal("execv()"); - } - - res = waitpid(pid, &status, 0); - if (res == -1) { - syslog(LOG_CRIT, - "waitpid failed: %d. %s", errno, strerror(errno)); - exit(1); - } - return WEXITSTATUS(status); -} - -static int create_listening_socket(GUID serviceid) -{ - SOCKADDR_HV sa; - int lsock; - int res; - - lsock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW); - if (lsock == -1) - fatal("socket()"); - - sa.Family = AF_HYPERV; - sa.Reserved = 0; - sa.VmId = HV_GUID_WILDCARD; - sa.ServiceId = serviceid; - - res = bind(lsock, (const struct sockaddr *)&sa, sizeof(sa)); - if (res == -1) - fatal("bind()"); - - res = listen(lsock, 1); - if (res == -1) - fatal("listen()"); - - return lsock; -} - -static int connect_socket(GUID serviceid) -{ - SOCKADDR_HV sa; - int sock; - int res; - - sock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW); - if (sock == -1) - fatal("socket()"); - - sa.Family = AF_HYPERV; - sa.Reserved = 0; - sa.VmId = HV_GUID_PARENT; - sa.ServiceId = serviceid; - - res = connect(sock, (const struct sockaddr *)&sa, sizeof(sa)); - if (res == -1) - fatal("connect()"); - - return sock; -} - -static int accept_socket(int lsock) -{ - SOCKADDR_HV sac; - socklen_t socklen = sizeof(sac); - int csock; - - csock = accept(lsock, (struct sockaddr *)&sac, &socklen); - if (csock == -1) - fatal("accept()"); - - syslog(LOG_INFO, "Connect from: " GUID_FMT ":" GUID_FMT "\n", - GUID_ARGS(sac.VmId), GUID_ARGS(sac.ServiceId)); - - return csock; -} - -void usage(char *name) -{ - printf("%s: mount a 9P filesystem from an hvsock connection\n", name); - printf("usage:\n"); - printf("\t[--serviceid ] \n"); - printf("where\n"); - printf("\t--serviceid : use as the well-known service GUID\n"); - printf("\t (defaults to %s)\n", default_sid); - printf("\t--listen: listen forever for incoming AF_HVSOCK connections\n"); - printf("\t--connect: connect to the parent partition\n"); -} - -int main(int argc, char **argv) -{ - int res = 0; - GUID sid; - int c; - /* Defaults to a testing GUID */ - char *serviceid = default_sid; - char *tag = NULL; - char *path = NULL; - - opterr = 0; - while (1) { - static struct option long_options[] = { - /* These options set a flag. */ - {"serviceid", required_argument, NULL, 's'}, - {0, 0, 0, 0} - }; - int option_index = 0; - - c = getopt_long(argc, argv, "s:", long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 's': - serviceid = optarg; - break; - case 0: - break; - default: - usage(argv[0]); - exit(1); - } - } - - if (optind < argc) { - if (strcmp(argv[optind], "listen") == 0) - mode = LISTEN; - else if (strcmp(argv[optind], "connect") == 0) - mode = CONNECT; - optind++; - } - if (mode == NONE) { - fprintf(stderr, "Please supply either listen or connect\n"); - usage(argv[0]); - exit(1); - } - - if (optind < argc) - tag = argv[optind++]; - - if (optind < argc) - path = argv[optind++]; - - if (!tag) { - fprintf(stderr, "Please supply a tag name\n"); - usage(argv[0]); - exit(1); - } - - if (!path) { - fprintf(stderr, "Please supply a path\n"); - usage(argv[0]); - exit(1); - } - - res = parseguid(serviceid, &sid); - if (res) { - fprintf(stderr, - "Failed to parse serviceid as GUID: %s\n", serviceid); - usage(argv[0]); - exit(1); - } - - openlog(argv[0], LOG_CONS | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - for (;;) { - int lsocket; - int sock; - int r; - - if (mode == LISTEN) { - syslog(LOG_INFO, "starting in listening mode with serviceid=%s, tag=%s, path=%s", serviceid, tag, path); - lsocket = create_listening_socket(sid); - sock = accept_socket(lsocket); - close(lsocket); - } else { - syslog(LOG_INFO, "starting in connect mode with serviceid=%s, tag=%s, path=%s", serviceid, tag, path); - sock = connect_socket(sid); - } - - r = handle(sock, tag, path); - close(sock); - - if (r == 0) { - syslog(LOG_INFO, "mount successful for serviceid=%s tag=%s path=%s", serviceid, tag, path); - exit(0); - } - - /* - * This can happen if the client times out the connection - * after we accept it - */ - syslog(LOG_CRIT, "mount failed with %d for serviceid=%s tag=%s path=%s", r, serviceid, tag, path); - sleep(1); /* retry */ - } -} diff --git a/alpine/packages/9pmount-vsock/Makefile b/alpine/packages/9pmount-vsock/Makefile deleted file mode 100644 index 690461cdc..000000000 --- a/alpine/packages/9pmount-vsock/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -C_COMPILE=mobylinux/c-compile:ac075fed7c87e4af30d8490ae0504166cceb0df3@sha256:0e82d441ce112d638f904a08199c76b022c065a2dbf8908bb366755267d4417f - -default: sbin/9pmount-vsock - -DEPS=$(wildcard *.c *.h) - -sbin/9pmount-vsock: $(DEPS) - mkdir -p $(dir $@) - tar cf - $(DEPS) | docker run --rm --net=none --log-driver=none -i $(C_COMPILE) -o $@ -lpthread | tar xf - - -clean: - rm -rf sbin diff --git a/alpine/packages/9pmount-vsock/hvsock.c b/alpine/packages/9pmount-vsock/hvsock.c deleted file mode 100644 index 94e23a292..000000000 --- a/alpine/packages/9pmount-vsock/hvsock.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include "hvsock.h" - -int parseguid(const char *s, GUID *g) -{ - int res; - int p0, p1, p2, p3, p4, p5, p6, p7; - - res = sscanf(s, GUID_FMT, - &g->Data1, &g->Data2, &g->Data3, - &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7); - if (res != 11) - return 1; - g->Data4[0] = p0; - g->Data4[1] = p1; - g->Data4[2] = p2; - g->Data4[3] = p3; - g->Data4[4] = p4; - g->Data4[5] = p5; - g->Data4[6] = p6; - g->Data4[7] = p7; - return 0; -} - -DEFINE_GUID(HV_GUID_ZERO, - 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -DEFINE_GUID(HV_GUID_BROADCAST, - 0xFFFFFFFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); -DEFINE_GUID(HV_GUID_WILDCARD, - 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -DEFINE_GUID(HV_GUID_CHILDREN, - 0x90db8b89, 0x0d35, 0x4f79, 0x8c, 0xe9, 0x49, 0xea, 0x0a, 0xc8, 0xb7, 0xcd); -DEFINE_GUID(HV_GUID_LOOPBACK, - 0xe0e16197, 0xdd56, 0x4a10, 0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38); -DEFINE_GUID(HV_GUID_PARENT, - 0xa42e7cda, 0xd03f, 0x480c, 0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78); diff --git a/alpine/packages/9pmount-vsock/hvsock.h b/alpine/packages/9pmount-vsock/hvsock.h deleted file mode 100644 index 1f532c2eb..000000000 --- a/alpine/packages/9pmount-vsock/hvsock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* AF_HYPERV definitions and utilities */ - -#include -#include -#include -#include - -/* GUID handling */ -typedef struct _GUID { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} GUID; - -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} - -/* Helper macros for parsing/printing GUIDs */ -#define GUID_FMT "%08x-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x" -#define GUID_ARGS(_g) \ - (_g).Data1, (_g).Data2, (_g).Data3, \ - (_g).Data4[0], (_g).Data4[1], (_g).Data4[2], (_g).Data4[3], \ - (_g).Data4[4], (_g).Data4[5], (_g).Data4[6], (_g).Data4[7] -#define GUID_SARGS(_g) \ - &(_g).Data1, &(_g).Data2, &(_g).Data3, \ - &(_g).Data4[0], &(_g).Data4[1], &(_g).Data4[2], &(_g).Data4[3], \ - &(_g).Data4[4], &(_g).Data4[5], &(_g).Data4[6], &(_g).Data4[7] - -extern int parseguid(const char *s, GUID *g); - -/* HV Socket definitions */ -#define AF_HYPERV 43 -#define HV_PROTOCOL_RAW 1 - -typedef struct _SOCKADDR_HV { - unsigned short Family; - unsigned short Reserved; - GUID VmId; - GUID ServiceId; -} SOCKADDR_HV; - -extern const GUID HV_GUID_ZERO; -extern const GUID HV_GUID_BROADCAST; -extern const GUID HV_GUID_WILDCARD; -extern const GUID HV_GUID_CHILDREN; -extern const GUID HV_GUID_LOOPBACK; -extern const GUID HV_GUID_PARENT; diff --git a/alpine/packages/Makefile b/alpine/packages/Makefile deleted file mode 100644 index b2166e303..000000000 --- a/alpine/packages/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -DEPS=proxy diagnostics transfused tap-vsockd docker nc-vsock vsudd 9pmount-vsock iptables -.PHONY: clean $(DEPS) - -default: $(DEPS) - -$(DEPS): - $(MAKE) -C $@ - -clean: - for f in $(DEPS); do $(MAKE) -C $$f clean; done diff --git a/alpine/packages/automount/etc/init.d/automount b/alpine/packages/automount/etc/init.d/automount deleted file mode 100755 index 78a7f04ca..000000000 --- a/alpine/packages/automount/etc/init.d/automount +++ /dev/null @@ -1,185 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - need dev -} - -do_fsck() -{ - # preen - /sbin/e2fsck -p $* - EXIT_CODE=$? - # exit code 1 is errors corrected - [ "${EXIT_CODE}" -eq 1 ] && EXIT_CODE=0 - # exit code 2 or 3 means need to reboot - [ "${EXIT_CODE}" -eq 2 -o "${EXIT_CODE}" -eq 3 ] && /sbin/reboot - # exit code 4 or over is fatal - [ "${EXIT_CODE}" -lt 4 ] && return "${EXIT_CODE}" - - # try harder - /sbin/e2fsck -y $* - # exit code 1 is errors corrected - [ "${EXIT_CODE}" -eq 1 ] && EXIT_CODE=0 - # exit code 2 or 3 means need to reboot - [ "${EXIT_CODE}" -eq 2 -o "${EXIT_CODE}" -eq 3 ] && /sbin/reboot - # exit code 4 or over is fatal - [ "${EXIT_CODE}" -ge 4 ] && printf "Filesystem unrecoverably corrupted, will reformat\n" - - return "${EXIT_CODE}" -} - -do_fsck_extend_mount() -{ - DRIVE="$1" - DATA="$2" - - do_fsck "$DATA" || return 1 - - # only try to extend if there is a single partition and free space - PARTITIONS=$(sfdisk -J "$DRIVE" | jq '.partitiontable.partitions | length') - - if [ "$PARTITIONS" -eq 1 ] && \ - sfdisk -F "$DRIVE" | grep -q 'Unpartitioned space' && - ! sfdisk -F "$DRIVE" | grep -q '0 B, 0 bytes, 0 sectors' - then - SPACE=$(sfdisk -F "$DRIVE" | grep 'Unpartitioned space') - printf "Resizing disk partition: $SPACE\n" - - START=$(sfdisk -J "$DRIVE" | jq -e '.partitiontable.partitions | map(select(.type=="83")) | .[0].start') - - sfdisk -q --delete "$DRIVE" 2> /dev/null - echo "${START},,83;" | sfdisk -q "$DRIVE" - - # set bootable flag - sfdisk -A "$DRIVE" 1 - - # update status - blockdev --rereadpt $diskdev 2> /dev/null - mdev -s - - # wait for device - for i in $(seq 1 50); do test -b "$DATA" && break || sleep .1; mdev -s; done - - # resize2fs fails unless we use -f here - do_fsck -f "$DATA" || return 1 - resize2fs "$DATA" - - do_fsck "$DATA" || return 1 - fi - - mount "$DATA" /var -} - -do_mkfs() -{ - diskdev="$1" - - # new disks does not have an DOS signature in sector 0 - # this makes sfdisk complain. We can workaround this by letting - # fdisk create that DOS signature, by just do a "w", a write. - # http://bugs.alpinelinux.org/issues/145 - echo "w" | fdisk $diskdev >/dev/null - - # format one large partition - echo ";" | sfdisk --quiet $diskdev - - # update status - blockdev --rereadpt $diskdev 2> /dev/null - mdev -s - - FSOPTS="-O resize_inode,has_journal,extent,huge_file,flex_bg,uninit_bg,64bit,dir_nlink,extra_isize" - - mkfs.ext4 -q -F $FSOPTS ${diskdev}1 - - mount ${diskdev}1 /var -} - -do_swapfile() -{ - DRIVE=$1 - SIZE=$(sfdisk -J "$DRIVE" | jq -e -r '.partitiontable.partitions | map(select(.type=="83")) | .[0].size') - SWAP=/var/spool/swap - MOUNT=$(mount | grep 'on /var type') - # Create swap on desktop platforms if disk size larger than 16GB - if [ "$(mobyplatform)" = "mac" -o "$(mobyplatform)" = "windows" ] && \ - [ ! -f $SWAP ] && [ "$SIZE" -gt 33554432 ] && \ - [ -n "$MOUNT" ] - then - mkdir -p "$(dirname $SWAP)" - dd if=/dev/zero of=$SWAP bs=1k count=1048576 - chmod 600 $SWAP - mkswap $SWAP - fi - [ -f "$SWAP" ] && swapon $SWAP -} - -start() -{ - ebegin "Configuring host block device" - - # We are being specific with Azure for now. Otherwise the subshell - # below will reference /dev/sdb, which is Azure's "local resource disk" - # (see - # https://blogs.msdn.microsoft.com/mast/2013/12/06/understanding-the-temporary-drive-on-windows-azure-virtual-machines/). - # - # Since attempting to format swap on that disk will cause Azure VHD - # validation to fail, we default to using /dev/sda. requirements - # including not allowing swap partitions. - # - # IMPORTANT: If this, or the root device (/dev/sda1) changes in the - # syslinux / bootloader config for Azure, they will need to be updated - # in parallel. - if [ "$(mobyplatform)" = "azure" ] - then - DEV="sda" - else - DEV="$(find /dev -maxdepth 1 -type b ! -name 'loop*' | grep -v '[0-9]$' | sed 's@.*/dev/@@' | sort | head -1 )" - fi - - [ -z "${DEV}" ] && exit 1 - - DRIVE="/dev/${DEV}" - - # see if it has a partition table already - if sfdisk -d "${DRIVE}" >/dev/null 2>/dev/null - then - DATA=$(sfdisk -J "$DRIVE" | jq -e -r '.partitiontable.partitions | map(select(.type=="83")) | .[0].node') - if [ $? -eq 0 ] - then - do_fsck_extend_mount "$DRIVE" "$DATA" || do_mkfs "$DRIVE" - else - do_mkfs "$DRIVE" - fi - else - do_mkfs "$DRIVE" - fi - - # Use existing swap partition of present; we do not create one now - SWAP_PART=$(fdisk -l "$DRIVE" | grep 'Linux swap' | head -1 | awk '{print $1}') - if [ -z "$SWAP_PART" ] - then - do_swapfile "$DRIVE" - else - swapon "$SWAP_PART" - fi - - # boot2docker compat, has /var and /tmp on partition - [ -d /var/var/lib/boot2docker/ ] && (mv /var/var/* /var && rm -rf /var/var) - - # add in directories under /var that are lost in formatting - [ -L /var/run ] || ln -s /run /var/run - [ -L /var/lock ] || ln -s /run/lock /var/lock - [ -d /var/log ] || mkdir -m 755 /var/log - [ -d /var/empty ] || mkdir -m 755 /var/empty - [ -d /var/spool ] || mkdir -m 755 /var/spool - [ -d /var/cache ] || mkdir -m 755 /var/cache - [ -d /var/cache/apk ] || mkdir -m 755 /var/cache/apk - [ -d /var/cache/misc ] || mkdir -m 755 /var/cache/misc - [ -d /var/local ] || mkdir -m 755 /var/local - [ -d /var/tmp ] || mkdir -m 1777 /var/tmp - - mount | grep -q ' on /var type ' - - eend $? "Failed to mount block device" -} diff --git a/alpine/packages/chronyd/etc/chrony/chrony.conf b/alpine/packages/chronyd/etc/chrony/chrony.conf deleted file mode 100644 index 95ca4ff24..000000000 --- a/alpine/packages/chronyd/etc/chrony/chrony.conf +++ /dev/null @@ -1,5 +0,0 @@ -pool pool.ntp.org iburst minpoll 2 -makestep 0.5 -1 -keyfile /etc/chrony/chrony.keys -driftfile /var/lib/chrony/chrony.drift -cmdport 0 diff --git a/alpine/packages/chronyd/etc/init.d/chronyd b/alpine/packages/chronyd/etc/init.d/chronyd deleted file mode 100755 index a637e432a..000000000 --- a/alpine/packages/chronyd/etc/init.d/chronyd +++ /dev/null @@ -1,91 +0,0 @@ -#!/sbin/openrc-run -# Copyright 1999-2007 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/net-misc/chrony/files/chronyd.rc,v 1.8 2007/03/22 14:32:09 tove Exp $ - -description="NTP daemon" - -depend() { - need net - after firewall - provide ntp-client ntp-server - use dns -} - -checkconfig() { - # Note that /etc/chrony/chrony.keys is *NOT* checked. This - # is because the user may have specified another key - # file, and we don't want to force the user to use that - # exact name for the key file. - if [ ! -f "${CFGFILE}" ] ; then - eerror "Please create ${CFGFILE} and the" - eerror "chrony key file (usually /etc/chrony/chrony.keys)" - eerror "by using the" - eerror "" - eerror " chrony.conf.example" - eerror " chrony.keys.example" - eerror "" - eerror "files (from the documentation directory)" - eerror "as templates." - return 1 - else - # Actually, I tried it, and chrony seems to ignore the pidfile - # option. I'm going to leave it here anyway, since you never - # know if it might be handy - PIDFILE=`awk '/^ *pidfile/{print $2}' "${CFGFILE}"` - fi - return 0 -} - -setxtrarg() { - if [ -c /dev/rtc ]; then - grep -q '^rtcfile' "${CFGFILE}" && ARGS="${ARGS} -s" - fi - grep -q '^dumponexit$' "${CFGFILE}" && ARGS="${ARGS} -r" - return 0 -} - -start() { - case "$(mobyplatform)" in - "windows") - exit 0 - ;; - "mac") - sed -i -e "s/^pool [^ ]\+/server 192.168.65.1 trust/g" /etc/chrony/chrony.conf - ;; - "aws") - sed -i -e "s/^pool [^ ]\+/pool 0.amazon.pool.ntp.org/g" /etc/chrony/chrony.conf - ;; - "gcp") - sed -i -e "s/^pool [^ ]\+/server metadata.google.internal trust/g" /etc/chrony/chrony.conf - ;; - "azure") - # TODO needs an ntp solution - ;; - esac - - checkconfig || return $? - setxtrarg - - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/chronyd.pid - - ebegin "Starting chronyd" - start-stop-daemon --start --quiet \ - --exec /usr/sbin/chronyd \ - --pidfile "${PIDFILE}" \ - -- -f "${CFGFILE}" ${ARGS} - eend $? "Failed to start chronyd" -} - -stop() { - [ "$(mobyplatform)" = "windows" ] && exit 0 - - checkconfig || return $? - - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/chronyd.pid - - ebegin "Stopping chronyd" - start-stop-daemon --stop --quiet \ - --pidfile "${PIDFILE}" - eend $? "Failed to stop chronyd" -} diff --git a/alpine/packages/containerd/etc/init.d/containerd b/alpine/packages/containerd/etc/init.d/containerd deleted file mode 100755 index 9f2fb9c4f..000000000 --- a/alpine/packages/containerd/etc/init.d/containerd +++ /dev/null @@ -1,34 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - before docker -} - -start() -{ - ebegin "Running system containerd" - - # set ulimits as high as possible - ulimit -n 1048576 - ulimit -p unlimited - - /usr/bin/containerd 1>&2 2>/var/log/containerd.log & - - ewaitfile 5 /var/run/containerd/containerd.sock - - eend $? "Failed to start system containerd" - - ebegin "Running system containers" - - LOG=/var/log/system-containers.log - touch $LOG - - for f in /containers/* - do - containerd-ctr containers start --no-pivot --attach "$(basename $f)" "$f" 2>$LOG >$LOG & - printf " $(basename $f)" - done - - eend $? "Failed to start system containers" -} diff --git a/alpine/packages/diagnostics/.gitignore b/alpine/packages/diagnostics/.gitignore deleted file mode 100644 index bb212fdf6..000000000 --- a/alpine/packages/diagnostics/.gitignore +++ /dev/null @@ -1 +0,0 @@ -usr/bin/diagnostics-server diff --git a/alpine/packages/diagnostics/Makefile b/alpine/packages/diagnostics/Makefile deleted file mode 100644 index c3e249653..000000000 --- a/alpine/packages/diagnostics/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -GO_COMPILE=mobylinux/go-compile:d2d25ac665b5148ad356d0eab3ff3762a68c633d@sha256:aab55d0c317460850e66a07dd94139cc11ea9e1c0bee88716a6a8c768740885f - -default: usr/bin/diagnostics-server - -DEPS=$(wildcard *.go) - -usr/bin/diagnostics-server: $(DEPS) ../vendor/manifest - mkdir -p $(dir $@) - tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - - -clean: - rm -f usr/bin/diagnostics-server - -.DELETE_ON_ERROR: diff --git a/alpine/packages/diagnostics/capture.go b/alpine/packages/diagnostics/capture.go deleted file mode 100644 index 5692fa859..000000000 --- a/alpine/packages/diagnostics/capture.go +++ /dev/null @@ -1,214 +0,0 @@ -package main - -import ( - "archive/tar" - "bytes" - "context" - "io/ioutil" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - "time" -) - -const ( - defaultCaptureTimeout = 5 * time.Second - defaultCommandTimeout = defaultCaptureTimeout - - // Might eventually have some pretty long (~30s) traces in here, so 35 - // seconds seems reasonable. - allCaptureTimeout = 35 * time.Second -) - -var ( - commonCmdCaptures = []CommandCapturer{ - {"/bin/date", nil, defaultCommandTimeout}, - {"/bin/uname", []string{"-a"}, defaultCommandTimeout}, - {"/bin/ps", []string{"uax"}, defaultCommandTimeout}, - {"/bin/netstat", []string{"-tulpn"}, defaultCommandTimeout}, - {"/sbin/apk", []string{"audit", "--system"}, defaultCommandTimeout}, // check if system binaries were modified - {"/sbin/iptables-save", nil, defaultCommandTimeout}, - {"/sbin/ifconfig", nil, defaultCommandTimeout}, - {"/sbin/route", nil, defaultCommandTimeout}, - {"/usr/sbin/brctl", []string{"show"}, defaultCommandTimeout}, - {"/bin/dmesg", nil, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"ps"}, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"version"}, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"info"}, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"network", "ls"}, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"node", "ls"}, defaultCommandTimeout}, - {"/usr/bin/docker", []string{"service", "ls"}, defaultCommandTimeout}, - {"/usr/bin/tail", []string{"-20000", "/var/log/docker.log"}, defaultCommandTimeout}, - {"/usr/bin/tail", []string{"-20000", "/var/log/messages"}, defaultCommandTimeout}, - {"/bin/mount", nil, defaultCommandTimeout}, - {"/bin/df", []string{"-h"}, defaultCommandTimeout}, - {"/bin/ls", []string{"-l", "/var"}, defaultCommandTimeout}, - {"/bin/ls", []string{"-l", "/var/lib"}, defaultCommandTimeout}, - {"/bin/ls", []string{"-l", "/var/lib/docker"}, defaultCommandTimeout}, - {"/usr/bin/diagnostics", nil, defaultCommandTimeout}, - {"/bin/ping", []string{"-w", "5", "8.8.8.8"}, 6 * time.Second}, - {"/bin/cat", []string{"/etc/docker/daemon.json"}, defaultCommandTimeout}, - {"/bin/cat", []string{"/etc/network/interfaces"}, defaultCommandTimeout}, - {"/bin/cat", []string{"/etc/resolv.conf"}, defaultCommandTimeout}, - {"/bin/cat", []string{"/etc/sysctl.conf"}, defaultCommandTimeout}, - {"/bin/cat", []string{"/proc/cpuinfo"}, defaultCommandTimeout}, - {"/usr/bin/nslookup", []string{"docker.com"}, defaultCommandTimeout}, - {"/usr/bin/nslookup", []string{"docker.com", "8.8.8.8"}, defaultCommandTimeout}, - {"/usr/bin/curl", []string{"http://www.docker.com/"}, defaultCommandTimeout}, - {"/usr/bin/curl", []string{"http://104.239.220.248/"}, defaultCommandTimeout}, // a www.docker.com address - {"/usr/bin/curl", []string{"http://216.58.213.68/"}, defaultCommandTimeout}, // a www.google.com address - {"/usr/bin/curl", []string{"http://91.198.174.192/"}, defaultCommandTimeout}, // a www.wikipedia.com address - {"/bin/cat", []string{"/var/lib/docker/volumes/metadata.db"}, defaultCommandTimeout}, // [docker/docker#29636] - {"/bin/cat", []string{"/var/lib/docker/network/files/local-kv.db"}, defaultCommandTimeout}, // [docker/docker#29636] - } - localCmdCaptures = []CommandCapturer{ - {"/usr/bin/tail", []string{"-100", "/var/log/proxy-vsockd.log"}, defaultCommandTimeout}, - {"/usr/bin/tail", []string{"-100", "/var/log/vsudd.log"}, defaultCommandTimeout}, - } - localCaptures = []Capturer{NewDatabaseCapturer()} -) - -func init() { - for _, c := range commonCmdCaptures { - localCaptures = append(localCaptures, c) - } - for _, c := range localCmdCaptures { - localCaptures = append(localCaptures, c) - } -} - -// Capturer defines behavior for structs which will capture arbitrary -// diagnostic information and write it to a tar archive with a timeout. -type Capturer interface { - Capture(context.Context, *tar.Writer) -} - -// CommandCapturer describes commands with its arguments and timeout to -// capture diagnostic information from -type CommandCapturer struct { - command string - args []string - timeout time.Duration -} - -// Capture writes output from a CommandCapturer to a tar archive -func (cc CommandCapturer) Capture(parentCtx context.Context, w *tar.Writer) { - stdout := &bytes.Buffer{} - stderr := &bytes.Buffer{} - done := make(chan struct{}) - - name := strings.Join(append([]string{path.Base(cc.command)}, cc.args...), " ") - ctx, cancel := context.WithTimeout(parentCtx, cc.timeout) - cmd := exec.CommandContext(ctx, cc.command, cc.args...) - cmd.Stdout = stdout - cmd.Stderr = stderr - - go runCmd(cmd, done) - - select { - case <-ctx.Done(): - log.Println("ERROR:", ctx.Err()) - case <-done: - tarWrite(w, stdout, name+".stdout") - tarWrite(w, stderr, name+".stderr") - } - - cancel() -} - -// TODO(nathanleclaire): Is the user of log.Fatalln in this function really the -// right choice? i.e., should the program really exit on failure here? -func tarWrite(w *tar.Writer, buf *bytes.Buffer, headerName string) { - contents, err := ioutil.ReadAll(buf) - if err != nil { - log.Fatalln(err) - } - - log.Println("HEADER:", headerName) - log.Println("{") - contentLines := strings.Split(string(contents), "\n") - for _, line := range contentLines { - log.Println(line) - } - log.Println("}") - - hdr := &tar.Header{ - Name: headerName, - Mode: 0644, - Size: int64(len(contents)), - } - if err := w.WriteHeader(hdr); err != nil { - log.Fatalln(err) - } - if _, err := w.Write(contents); err != nil { - log.Fatalln(err) - } -} - -func runCmd(cmd *exec.Cmd, done chan<- struct{}) { - if err := cmd.Run(); err != nil { - log.Println("ERROR:", err) - } - done <- struct{}{} -} - -// DatabaseCapturer defines behavior for capturing diagnostic -// information from dumping a database -type DatabaseCapturer struct { - *CommandCapturer -} - -// NewDatabaseCapturer creates a new DatabaseCapturer that cats -// the database's contents to a CommandCapturer -func NewDatabaseCapturer() DatabaseCapturer { - return DatabaseCapturer{ - &CommandCapturer{ - command: "/bin/cat", - timeout: defaultCommandTimeout, - }, - } -} - -// Capture writes output from a DatabaseCapturer to a tar archive -func (dc DatabaseCapturer) Capture(parentCtx context.Context, w *tar.Writer) { - // Dump the database - dbBase := "/Database" - filepath.Walk(dbBase, func(path string, f os.FileInfo, err error) error { - if f.Mode().IsRegular() { - dc.CommandCapturer.args = []string{path} - dc.CommandCapturer.Capture(parentCtx, w) - } - return nil - }) -} - -// Capture is the outer level wrapper function to trigger the capturing of -// information. Clients are expected to call it with a slice of Capturers -// which define the information to be captured. By using an interface we can -// flexibly define various capture actions for the various listeners. -// -// It is a passed a tar.Writer which the results of the capture will be written -// to. -func Capture(w *tar.Writer, captures []Capturer) { - allCaptureCtx, cancel := context.WithTimeout(context.Background(), allCaptureTimeout) - done := make(chan struct{}) - - go func(captures []Capturer, ctx context.Context, done chan<- struct{}) { - for _, c := range captures { - c.Capture(ctx, w) - } - done <- struct{}{} - }(captures, allCaptureCtx, done) - - select { - case <-allCaptureCtx.Done(): - log.Println("Global command context", allCaptureCtx.Err()) - case <-done: - log.Println("Captures all finished") - } - - cancel() -} diff --git a/alpine/packages/diagnostics/etc/init.d/diagnostics b/alpine/packages/diagnostics/etc/init.d/diagnostics deleted file mode 100755 index 5acd997b3..000000000 --- a/alpine/packages/diagnostics/etc/init.d/diagnostics +++ /dev/null @@ -1,11 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - after docker containerd -} - -start() -{ - /usr/bin/diagnostics -} diff --git a/alpine/packages/diagnostics/etc/init.d/diagnostics-server b/alpine/packages/diagnostics/etc/init.d/diagnostics-server deleted file mode 100755 index 10af04666..000000000 --- a/alpine/packages/diagnostics/etc/init.d/diagnostics-server +++ /dev/null @@ -1,30 +0,0 @@ -#!/sbin/openrc-run - -start() -{ - ebegin "Starting diagnostics server" - - DIAGNOSTICS_SERVER_FLAGS="" - - case "$(mobyplatform)" in - "aws") - DIAGNOSTICS_SERVER_FLAGS="-http" - ;; - "azure") - DIAGNOSTICS_SERVER_FLAGS="-http" - ;; - "gcp") - DIAGNOSTICS_SERVER_FLAGS="-http" - ;; - "windows") - DIAGNOSTICS_SERVER_FLAGS="-hvsock" - ;; - "mac") - DIAGNOSTICS_SERVER_FLAGS="-vsock" - ;; - esac - - /usr/bin/diagnostics-server ${DIAGNOSTICS_SERVER_FLAGS} & - - eend 0 -} diff --git a/alpine/packages/diagnostics/http.go b/alpine/packages/diagnostics/http.go deleted file mode 100644 index 9f71aa7fa..000000000 --- a/alpine/packages/diagnostics/http.go +++ /dev/null @@ -1,225 +0,0 @@ -package main - -import ( - "archive/tar" - "bytes" - "context" - "errors" - "fmt" - "io" - "io/ioutil" - "log" - "net" - "net/http" - "net/http/httputil" - "os" - "strconv" - "strings" - "time" -) - -var ( - errDockerRespNotOK = errors.New("Docker API call did not return OK") -) - -const ( - healthcheckTimeout = 5 * time.Second - dockerSock = "/var/run/docker.sock" - dockerPingOK = "LGTM" - httpMagicPort = ":44554" // chosen arbitrarily due to IANA availability -- might change - bucket = "editionsdiagnostics" - sessionIDField = "session" -) - -var ( - cloudCaptures = []Capturer{} -) - -func init() { - for _, c := range commonCmdCaptures { - cloudCaptures = append(cloudCaptures, c) - } - - cloudCaptures = append(cloudCaptures, SystemContainerCapturer{}) -} - -// HTTPDiagnosticListener sets a health check and optional diagnostic endpoint -// for cloud editions. -type HTTPDiagnosticListener struct{} - -func dockerHTTPGet(ctx context.Context, url string) (*http.Response, error) { - client := &http.Client{ - Transport: &UnixSocketRoundTripper{}, - } - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return nil, err - } - - req = req.WithContext(ctx) - - resp, err := client.Do(req) - if err != nil { - return resp, err - } - - if resp.StatusCode != http.StatusOK { - return resp, errDockerRespNotOK - } - - return resp, err -} - -// UnixSocketRoundTripper provides a way to make HTTP request to Docker socket -// directly. -type UnixSocketRoundTripper struct{} - -// RoundTrip dials the Docker UNIX socket to make a HTTP request. -func (u UnixSocketRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - dial, err := net.Dial("unix", dockerSock) - if err != nil { - return nil, err - } - conn := httputil.NewClientConn(dial, nil) - - return conn.Do(req) -} - -// Listen starts the HTTPDiagnosticListener and sets up handlers for its endpoints -func (h HTTPDiagnosticListener) Listen() { - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - ctx, cancel := context.WithTimeout(context.Background(), healthcheckTimeout) - defer cancel() - - errCh := make(chan error) - - go func() { - _, err := dockerHTTPGet(ctx, "/_ping") - errCh <- err - }() - - select { - case err := <-errCh: - if err != nil { - http.Error(w, "Docker daemon ping error", http.StatusInternalServerError) - return - } - case <-ctx.Done(): - http.Error(w, "Docker daemon ping timed out", http.StatusServiceUnavailable) - return - } - - if _, err := w.Write([]byte(dockerPingOK)); err != nil { - log.Println("Error writing HTTP success response:", err) - return - } - }) - - http.HandleFunc("/diagnose", func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - http.Error(w, "Invalid request type. Should be POST with form value 'session' set", http.StatusBadRequest) - return - } - - diagnosticsSessionID := r.FormValue(sessionIDField) - - if diagnosticsSessionID == "" { - http.Error(w, "No 'session' field specified for diagnostics run", http.StatusBadRequest) - return - } - - hostname, err := os.Hostname() - if err != nil { - http.Error(w, "Error getting hostname:"+err.Error(), http.StatusInternalServerError) - return - } - - // To keep URL cleaner - hostname = strings.Replace(hostname, ".", "-", -1) - - if _, err := w.Write([]byte("OK hostname=" + hostname + " session=" + diagnosticsSessionID + "\n")); err != nil { - http.Error(w, "Error writing: "+err.Error(), http.StatusInternalServerError) - return - } - - // Do the actual capture and uplaod to S3 in the background. - // No need to make caller sit and wait for the result. They - // probably have a lot of other things going on, like other - // servers to request diagnostics for. - // - // TODO(nathanleclaire): Potentially, endpoint to check the - // result of this capture and upload process as well. - go func() { - dir, err := ioutil.TempDir("", "diagnostics") - if err != nil { - log.Println("Error creating temp dir on diagnostic request:: ", err) - return - } - - file, err := ioutil.TempFile(dir, "diagnostics") - if err != nil { - log.Println("Error creating temp file on diagnostic request:", err) - return - } - - tarWriter := tar.NewWriter(file) - - Capture(tarWriter, cloudCaptures) - - if err := tarWriter.Close(); err != nil { - log.Println("Error closing archive writer: ", err) - return - } - - if err := file.Close(); err != nil { - log.Println("Error closing file: ", err) - return - } - - readFile, err := os.Open(file.Name()) - if err != nil { - log.Println("Error opening report file to upload: ", err) - return - } - defer readFile.Close() - - buf := &bytes.Buffer{} - contentLength, err := io.Copy(buf, readFile) - if err != nil { - log.Println("Error copying to buffer: ", err) - return - } - - reportURI := fmt.Sprintf("https://%s.s3.amazonaws.com/%s-%s.tar", bucket, diagnosticsSessionID, hostname) - - uploadReq, err := http.NewRequest("PUT", reportURI, buf) - if err != nil { - log.Println("Error getting bucket request: ", err) - return - } - - uploadReq.Header.Set("x-amz-acl", "bucket-owner-full-control") - uploadReq.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) - uploadReq.Header.Set("Content-Length", strconv.Itoa(int(contentLength))) - - client := &http.Client{} - - if uploadResp, err := client.Do(uploadReq); err != nil { - log.Println("Error writing: ", err) - body, err := ioutil.ReadAll(uploadResp.Body) - if err != nil { - log.Println("Error reading response body: ", err) - } - log.Println(string(body)) - return - } - log.Println("No error sending S3 request") - log.Println("Diagnostics request finished") - }() - }) - - // Start HTTP server to indicate general Docker health. - // TODO: no magic port? - http.ListenAndServe(httpMagicPort, nil) -} diff --git a/alpine/packages/diagnostics/hvsock.go b/alpine/packages/diagnostics/hvsock.go deleted file mode 100644 index 2122fda16..000000000 --- a/alpine/packages/diagnostics/hvsock.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "log" - "syscall" - - "github.com/rneugeba/virtsock/go/hvsock" -) - -// HVSockDiagnosticListener is a diagnostic server using HVSock (Windows) -type HVSockDiagnosticListener struct{} - -// Listen sets up the diagnostic server to listen on an HVSock -func (l HVSockDiagnosticListener) Listen() { - svcid, _ := hvsock.GuidFromString("445BA2CB-E69B-4912-8B42-D7F494D007EA") - hvsock, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - if errno, ok := err.(syscall.Errno); !ok || errno != syscall.EAFNOSUPPORT { - log.Printf("Failed to bind to hvsock port: %s", err) - } - } - - for { - TarRespond(hvsock) - } -} diff --git a/alpine/packages/diagnostics/main.go b/alpine/packages/diagnostics/main.go deleted file mode 100644 index b184266de..000000000 --- a/alpine/packages/diagnostics/main.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "flag" - "log" - "log/syslog" -) - -func init() { - syslog, err := syslog.New(syslog.LOG_INFO|syslog.LOG_DAEMON, "diagnostics") - if err != nil { - log.Fatalln("Failed to open syslog", err) - } - - log.SetOutput(syslog) - log.SetFlags(0) -} - -// DiagnosticListener listens for starting diagnostics capture requests -type DiagnosticListener interface { - // Listen(), a blocking method intended to be invoked in its own - // goroutine, will listen for a diagnostic information request and - // capture the desired information if one is received. - Listen() -} - -// DiagnosticUploader uploads the collected information to the mothership. -type DiagnosticUploader interface { - Upload() error -} - -func main() { - flHTTP := flag.Bool("http", false, "Enable diagnostic HTTP listener") - flVSock := flag.Bool("vsock", false, "Enable vsock listener") - flHVSock := flag.Bool("hvsock", false, "Enable hvsock listener") - flRawTCP := flag.Bool("rawtcp", false, "Enable raw TCP listener") - - flag.Parse() - - listeners := make([]DiagnosticListener, 0) - - if *flHTTP { - listeners = append(listeners, HTTPDiagnosticListener{}) - } - - if *flVSock { - listeners = append(listeners, VSockDiagnosticListener{}) - } - - if *flHVSock { - listeners = append(listeners, HVSockDiagnosticListener{}) - } - - if *flRawTCP { - listeners = append(listeners, RawTCPDiagnosticListener{}) - } - - for _, l := range listeners { - go l.Listen() - } - forever := make(chan int) - <-forever -} diff --git a/alpine/packages/diagnostics/rawtcp.go b/alpine/packages/diagnostics/rawtcp.go deleted file mode 100644 index 26d09cfc4..000000000 --- a/alpine/packages/diagnostics/rawtcp.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "log" - "net" -) - -// RawTCPDiagnosticListener is a diagnostic server listening on a TCP port -type RawTCPDiagnosticListener struct{} - -// Listen for RawTCPDiagnosticListener listens on port 62374 -func (l RawTCPDiagnosticListener) Listen() { - ip, err := net.Listen("tcp", ":62374") - if err != nil { - log.Printf("Failed to bind to TCP port 62374: %s", err) - } - - for { - TarRespond(ip) - } -} diff --git a/alpine/packages/diagnostics/system_log_capture.go b/alpine/packages/diagnostics/system_log_capture.go deleted file mode 100644 index 2e5aeb2d7..000000000 --- a/alpine/packages/diagnostics/system_log_capture.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import ( - "archive/tar" - "bytes" - "context" - "encoding/json" - "io/ioutil" - "log" -) - -const ( - systemLogDir = "editionslogs" - systemContainerLabel = "com.docker.editions.system" -) - -// SystemContainerCapturer gets the logs from containers which are run -// specifically for Docker Editions. -type SystemContainerCapturer struct{} - -// Capture writes output from a CommandCapturer to a tar archive -func (s SystemContainerCapturer) Capture(parentCtx context.Context, w *tar.Writer) { - ctx, cancel := context.WithTimeout(context.Background(), defaultCaptureTimeout) - defer cancel() - - errCh := make(chan error) - - go func() { - // URL encoded. - // Reads more like this: - // /v1.25/containers/json?all=1&filters={"label":{"com.docker.editions.system":true}} - resp, err := dockerHTTPGet(ctx, "/containers/json?all=1&filters=%7B%22label%22%3A%7B%22"+systemContainerLabel+"%22%3Atrue%7D%7D") - if err != nil { - errCh <- err - return - } - - defer resp.Body.Close() - - names := []struct { - ID string `json:"id"` - Names []string - }{} - - if err := json.NewDecoder(resp.Body).Decode(&names); err != nil { - errCh <- err - return - } - - for _, c := range names { - resp, err := dockerHTTPGet(ctx, "/containers/"+c.ID+"/logs?stderr=1&stdout=1×tamps=1&tail=all") - if err != nil { - log.Println("ERROR (get request):", err) - continue - } - - defer resp.Body.Close() - - logLines, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Println("ERROR (reading response):", err) - continue - } - - // Docker API returns a Names array where the names are - // like this: ["/foobar", "/quux"] - // - // Use the first one from it. - // - // Additionally, the slash from it helps delimit a path - // separator in the tar archive. - // - // TODO(nathanleclaire): This seems fragile, but I'm - // not sure what approach would be much better. - tarWrite(w, bytes.NewBuffer(logLines), systemLogDir+c.Names[0]) - } - - errCh <- nil - }() - - select { - case <-ctx.Done(): - log.Println("System container log capture context error", ctx.Err()) - case err := <-errCh: - if err != nil { - log.Println("System container log capture error", err) - } - log.Println("System container log capture finished successfully") - } -} diff --git a/alpine/packages/diagnostics/tar_respond.go b/alpine/packages/diagnostics/tar_respond.go deleted file mode 100644 index 2992cd5e4..000000000 --- a/alpine/packages/diagnostics/tar_respond.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "archive/tar" - "log" - "net" -) - -// TarRespond is used to write back a tar archive over a connection for the -// lower-level listener types. -// -// In local virtualization (which this is for) we write back a tar file -// directly and the client takes care of shipping the result to the mothership. -// -// By contrast, in cloud editions we expect each node to ship the captured -// information on its own, so this function is not used. -// -// This is a deliberate design to choice to ensure that it is possible in the -// future for diagnostic information to be reported from nodes which have have -// been separated via network partition from the node which initiates -// diagnostic collection, and/or if we decide to automatically collect -// diagnostic information from nodes which deem *themselves* unhealthy at a -// future time. -func TarRespond(l net.Listener) { - conn, err := l.Accept() - if err != nil { - log.Printf("Error accepting connection: %s", err) - return - } - - w := tar.NewWriter(conn) - - Capture(w, localCaptures) - - if err := w.Close(); err != nil { - log.Println(err) - } - - conn.Close() -} diff --git a/alpine/packages/diagnostics/usr/bin/diagnostics b/alpine/packages/diagnostics/usr/bin/diagnostics deleted file mode 100755 index c98c1a6a3..000000000 --- a/alpine/packages/diagnostics/usr/bin/diagnostics +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -EXIT_STATUS=0 - -fail() -{ - printf "✗ $1" - EXIT_STATUS=1 -} - -ok() -{ - printf "✓ $1" -} - -DEV="$(find /dev -maxdepth 1 -type b ! -name 'loop*' | grep -v '[0-9]$' | sed 's@.*/dev/@@' | head -1 )" -[ $? -eq 0 ] && ok "Drive found: $DEV\n" || fail "No drive found\n" -DEV=$(mount | grep '/dev/.* on /var type') -[ $? -eq 0 ] && ok "Drive mounted: $DEV\n" || fail "No drive mounted\n" -INET=$(ifconfig eth0 2> /dev/null | grep 'inet addr') -[ $? -eq 0 ] && ok "Network connected: $INET\n" || fail "No network connection\n" -if [ "$(mobyplatform)" = "mac" ] -then - FUSE=$(ps -eo args | grep '^/sbin/transfused') - [ $? -eq 0 ] && ok "Process transfused running\n" || fail "No transfused process\n" -fi -if [ "$(mobyplatform)" = "windows" ] -then - TAPVS=$(ps -eo args | grep '^/sbin/tap-vsockd') - [ $? -eq 0 ] && ok "Process tap-vsockd running\n" || fail "No tap-vsockd process\n" -fi -DOCKER=$(ps -eo args | grep '^dockerd') -[ $? -eq 0 ] && ok "Process dockerd running: $DOCKER\n" || fail "No dockerd process\n" -CONTAINERD=$(ps -eo args | grep '^docker-containerd') -[ $? -eq 0 ] && ok "Process containerd running: $CONTAINERD\n" || fail "No containerd process\n" -DOCKERPS=$(docker ps 2>&1) -DOCKERDV=$(docker version --format '{{.Server.Version}}') -[ $? -eq 0 ] && ok "Docker daemon working: ${DOCKERDV}\n" || fail "Docker ps failed: $DOCKERPS\n" -DIAGNOSTICS=$(ps -eo args | grep '^/usr/bin/diagnostics-server') -[ $? -eq 0 ] && ok "Diagnostics server running: $DIAGNOSTICS\n" || fail "No diagnostics server\n" -CONTAINERD=$(ps -eo args | grep '^/usr/bin/containerd') -[ $? -eq 0 ] && ok "System containerd server running: $CONTAINERD\n" || fail "No containerd server\n" -CONTAINERPS=$(containerd-ctr containers 2>&1) -[ $? -eq 0 ] && ok "System containerd working\n" || fail "containerd failed: $CONTAINERPS\n" - -exit $EXIT_STATUS diff --git a/alpine/packages/diagnostics/vsock.go b/alpine/packages/diagnostics/vsock.go deleted file mode 100644 index c2969c44d..000000000 --- a/alpine/packages/diagnostics/vsock.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "log" - "syscall" - - "github.com/rneugeba/virtsock/go/vsock" -) - -// VSockDiagnosticListener is a diagnostic server listening on VSock -type VSockDiagnosticListener struct{} - -// Listen for VSockDiagnosticListener listens on a VSock's port 62374 -func (l VSockDiagnosticListener) Listen() { - vsock, err := vsock.Listen(uint(62374)) - if err != nil { - if errno, ok := err.(syscall.Errno); !ok || errno != syscall.EAFNOSUPPORT { - log.Printf("Failed to bind to vsock port 62374: %s", err) - } - } - - for { - TarRespond(vsock) - } -} diff --git a/alpine/packages/docker/.gitignore b/alpine/packages/docker/.gitignore deleted file mode 100644 index 1b91047ac..000000000 --- a/alpine/packages/docker/.gitignore +++ /dev/null @@ -1 +0,0 @@ -usr/ diff --git a/alpine/packages/docker/Makefile b/alpine/packages/docker/Makefile deleted file mode 100644 index 1833f87d7..000000000 --- a/alpine/packages/docker/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -DOCKER_BIN_URL?=https://s3.amazonaws.com/editions-stage-us-east-1-150610-005505/linux/static/stable/x86_64/docker-17.03.0-ce.tgz -DOCKER_VERSION?=17.03.0-ce -ARCH?=x86_64 -OS?=Linux - -AWS_CLI_IMAGE=mobylinux/aws-cli:9432b650794d38a70cf00be4da971367c52d1d5b@sha256:679f6f45fb8598cab90888733a07ddeeb26a27a7889114f89aaf712eaa3abe06 - -all: usr/bin/docker - -RELEASE_CANDIDATE=$(findstring -rc,$(DOCKER_VERSION)) -ifeq ($(RELEASE_CANDIDATE),-rc) -DOCKER_HOST=test.docker.com -else -DOCKER_HOST=get.docker.com -endif - -DOCKER_IMAGE?=docker:$(DOCKER_VERSION) - -ifeq ($(DOCKER_VERSION),master) -ifeq ($(OS),Linux) -OS=linux -endif -ifeq ($(ARCH),x86_64) -ARCH=amd64 -endif -MASTER_VERSION:=$(shell curl -fsSL https://master.dockerproject.org/version) -DOCKER_BIN_URL=https://master.dockerproject.org/$(OS)/$(ARCH)/docker-$(MASTER_VERSION).tgz -endif - -S3_PREFIX=s3:// - -usr/bin/docker: Makefile - mkdir -p usr/bin - rm -f usr/bin/* ok -ifdef DOCKER_BIN_URL -ifeq ($(filter $(S3_PREFIX)%, $(DOCKER_BIN_URL)),) - (curl -fsSL "${DOCKER_BIN_URL}" && touch ok) | tar xzf - -else - (docker run --rm -e AWS_SECRET_ACCESS_KEY -e AWS_ACCESS_KEY_ID $(AWS_CLI_IMAGE) s3 cp '$(DOCKER_BIN_URL)' -) | tar xzf - -endif -else - (curl -fsSL https://${DOCKER_HOST}/builds/${OS}/${ARCH}/docker-${DOCKER_VERSION}.tgz && touch ok) | tar xzf - -endif - rm ok - if [ -d "./bundles" ]; then \ - mv bundles/${DOCKER_VERSION}/binary-daemon/docker-containerd-ctr \ - bundles/${DOCKER_VERSION}/binary-client/docker \ - bundles/${DOCKER_VERSION}/binary-daemon/docker-containerd \ - bundles/${DOCKER_VERSION}/binary-daemon/dockerd \ - bundles/${DOCKER_VERSION}/binary-daemon/docker-proxy \ - bundles/${DOCKER_VERSION}/binary-daemon/docker-runc \ - bundles/${DOCKER_VERSION}/binary-daemon/docker-containerd-shim \ - usr/bin/ ;\ - else \ - mv docker/docker-containerd-ctr \ - docker/docker \ - docker/docker-containerd \ - docker/dockerd \ - docker/docker-proxy \ - docker/docker-runc \ - docker/docker-containerd-shim \ - usr/bin/ ; fi - ([ -e docker/docker-init ] && mv docker/docker-init usr/bin/) || true - ([ -d docker/completion ] && rm -rf docker/completion) || true - -clean: - rm -rf usr/ docker/ ok - -.DELETE_ON_ERROR: diff --git a/alpine/packages/docker/etc/init.d/docker b/alpine/packages/docker/etc/init.d/docker deleted file mode 100755 index c7efd53c8..000000000 --- a/alpine/packages/docker/etc/init.d/docker +++ /dev/null @@ -1,143 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - after transfused -} - -start() -{ - ebegin "Starting Docker" - - # check if overriding Docker with a dev bundle - if mobyconfig exists bundle - then - bundle=$(mobyconfig get bundle) - [ -n "$bundle" -a -d "$bundle" -a -h "$bundle/binary-client/docker" ] && \ - export PATH=$bundle/binary-client:$bundle/binary-daemon:$PATH && \ - printf "Overriding Docker with provided bundle: $bundle\n" - fi - - command="${DOCKER_BINARY:-dockerd}" - - pidfile="/run/docker.pid" - - # mount /run shared eg for volume drivers - mount --make-shared /run - - # create cgroups mount for systemd containers - if [ ! -d /sys/fs/cgroup/systemd ] - then - mkdir -p /sys/fs/cgroup/systemd - mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd - fi - - # Only start with networking on cloud editions - DOCKER_OPTS="${DOCKER_OPTS} -H unix:///var/run/docker.sock" - - # On desktop editions, force swarm advertise address to be on eth0 - # Currently we do not support multi node swarm on these editions - # for cloud plartforms the init scripts set this up - case "$(mobyplatform)" in - windows|mac) - DOCKER_OPTS="${DOCKER_OPTS} --swarm-default-advertise-addr=eth0" - ;; - esac - - # some config is always in /etc/docker cannot specify alternative eg certs - mkdir -p /etc/docker - if mobyconfig exists etc/docker - then - for f in $(mobyconfig find etc/docker) - do - mkdir -p $(dirname $f) - mobyconfig get $f > $f - done - fi - - [ -f /etc/docker/daemon.json ] || printf '{}' > /etc/docker/daemon.json - - if mobyconfig exists network - then - NETWORK_MODE="$(mobyconfig get network | tr -d '[[:space:]]')" - NATIVE_PORT_FORWARDING="$(mobyconfig get native/port-forwarding | tr -d '[[:space:]]')" - if [ "${NETWORK_MODE}" = "slirp" -o "${NATIVE_PORT_FORWARDING}" = "true" ]; then - if dockerd --help | grep -q -- --userland-proxy-path; then - DOCKER_OPTS="${DOCKER_OPTS} --userland-proxy-path /usr/bin/slirp-proxy" - else - cp /usr/bin/slirp-proxy /usr/bin/docker-proxy - fi - fi - fi - - if mobyconfig exists proxy - then - export http_proxy="$(mobyconfig get proxy/http)" - export https_proxy="$(mobyconfig get proxy/https)" - export no_proxy="$(mobyconfig get proxy/exclude)" - fi - - # Set Docker to debug debug if not specified in daemon.json - cat /etc/docker/daemon.json | jq -e 'has("debug")' > /dev/null || DOCKER_OPTS="${DOCKER_OPTS} --debug" - - # On GCP, send logs to Google Cloud Logging - # Disabled because of https://github.com/docker/docker/issues/29344 - # [ $(mobyplatform) = "gcp" ] && DOCKER_OPTS="${DOCKER_OPTS} --log-driver=gcplogs" - - # choose storage driver - if ! $(cat /etc/docker/daemon.json | jq -e '."storage-driver"' > /dev/null) - then - STORAGE_DRIVER="overlay2" - [ -d /var/lib/docker/aufs ] && grep -q aufs /proc/filesystems && STORAGE_DRIVER="aufs" - DOCKER_OPTS="${DOCKER_OPTS} --storage-driver ${STORAGE_DRIVER}" - fi - - # set ulimits as high as possible - ulimit -n 1048576 - ulimit -p unlimited - # set locked memory higher for varnish - ulimit -l 82000 - - DOCKER_LOGFILE="/var/log/docker.log" - - case "$(mobyplatform)" in - windows|mac) - # Allow iptables to be overriden - export PATH=/usr/local/sbin:$PATH - ;; - esac - - start-stop-daemon --start --quiet \ - --background \ - --startas /bin/sh \ - --pidfile ${pidfile} \ - -- -c "exec ${command} --pidfile=${pidfile} ${DOCKER_OPTS} 2>&1 | logger -p local0.info" - - ewaitfile 20 ${pidfile} /var/run/docker.sock /var/run/docker/libcontainerd/docker-containerd.sock - - # On desktop forward metrics to host if enabled in daemon.json - case "$(mobyplatform)" in - windows|mac) - METRICS_ADDR=$(cat /etc/docker/daemon.json | jq -e -r '."metrics-addr"') - if [ $? -eq 0 ] - then - METRICS_IP="$(echo "$METRICS_ADDR" | cut -d: -f1)" - METRICS_PORT="$(echo "$METRICS_ADDR" | cut -d: -f2)" - /usr/bin/slirp-proxy -proto tcp -host-ip 0.0.0.0 -host-port "$METRICS_PORT" -container-ip "$METRICS_IP" -container-port "$METRICS_PORT" -i -no-local-ip & - fi - ;; - esac - - - eend $? "Failed to start docker" -} - -stop() -{ - # stop docker - einfo "Stopping docker" - pidfile="/run/docker.pid" - start-stop-daemon --stop --quiet --pidfile ${pidfile} --retry 15 - - return 0 -} diff --git a/alpine/packages/hostsettings/etc/init.d/hostsettings b/alpine/packages/hostsettings/etc/init.d/hostsettings deleted file mode 100755 index 5d6f869f3..000000000 --- a/alpine/packages/hostsettings/etc/init.d/hostsettings +++ /dev/null @@ -1,22 +0,0 @@ -#!/sbin/openrc-run - -description="Configuring settings from database." - -depend() { - # AWS gets settings via network - need net - before docker -} - -start() { - ebegin "Configuring host settings from database" - - mobyconfig exists random-seed && mobyconfig get random-seed > /dev/urandom - - mobyconfig exists etc/resolv.conf && mobyconfig get etc/resolv.conf > /etc/resolv.conf - mobyconfig exists etc/hosts && mobyconfig get etc/hosts >> /etc/hosts - - mobyconfig exists etc/ssl/certs/ca-certificates.crt && mobyconfig get etc/ssl/certs/ca-certificates.crt >> /etc/ssl/certs/ca-certificates.crt - - eend 0 -} diff --git a/alpine/packages/iptables/.gitignore b/alpine/packages/iptables/.gitignore deleted file mode 100644 index 73752c9ae..000000000 --- a/alpine/packages/iptables/.gitignore +++ /dev/null @@ -1 +0,0 @@ -usr diff --git a/alpine/packages/iptables/Makefile b/alpine/packages/iptables/Makefile deleted file mode 100644 index 786ca40e8..000000000 --- a/alpine/packages/iptables/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# This image is currently just tagged latest as non reproducible -IPTABLES_IMAGE=mobylinux/pinata-iptables@sha256:c94aa6902e858712058d0550320564ecb03d1f8f6370f91cdbc3f18b87662411 - -all: usr/local/sbin/iptables - -usr/local/sbin/iptables: - mkdir -p $(dir $@) - docker run --rm --net=none --log-driver=none $(IPTABLES_IMAGE) | tar xf - -C $(dir $@) - -clean: - rm -rf usr - -.DELETE_ON_ERROR: diff --git a/alpine/packages/mobyconfig/etc/init.d/database-aws b/alpine/packages/mobyconfig/etc/init.d/database-aws deleted file mode 100755 index d0241923e..000000000 --- a/alpine/packages/mobyconfig/etc/init.d/database-aws +++ /dev/null @@ -1,29 +0,0 @@ -#!/sbin/openrc-run - -description="Set up database (AWS)." - -depend() { - before docker hostsettings windowsnet -} - -start() { - [ "$(mobyplatform)" = "aws" ] || exit 0 - - ebegin "Setting up database (AWS)" - - mkdir -p /Database - mount -t tmpfs tmpfs /Database - - ENDPOINT="http://169.254.169.254/latest/meta-data" - curl "${ENDPOINT}/local-hostname" 2> /dev/null | mobyconfig set etc/hostname - # as this is a bit late let us set it anyway - mobyconfig get etc/hostname > /etc/hostname - hostname -F /etc/hostname - # TODO should collect all keys - curl -f -I "${ENDPOINT}/public-keys/0/openssh-key" 2> /dev/null > /dev/null && \ - curl "${ENDPOINT}/public-keys/0/openssh-key" 2> /dev/null | mobyconfig set etc/ssh/authorized_keys - USERDATA="http://169.254.169.254/latest/user-data/" - curl "${USERDATA}" 2> /dev/null | mobyconfig set userdata - - eend 0 -} diff --git a/alpine/packages/mobyconfig/etc/init.d/database-gcp b/alpine/packages/mobyconfig/etc/init.d/database-gcp deleted file mode 100755 index 1bff4b1be..000000000 --- a/alpine/packages/mobyconfig/etc/init.d/database-gcp +++ /dev/null @@ -1,27 +0,0 @@ -#!/sbin/openrc-run - -description="Set up database (GCP)." - -depend() { - before docker hostsettings windowsnet -} - -start() { - [ "$(mobyplatform)" = "gcp" ] || exit 0 - - ebegin "Setting up database (GCP)" - - mkdir -p /Database - mount -t tmpfs tmpfs /Database - - PROJECT=http://metadata.google.internal/computeMetadata/v1/project - INSTANCE=http://metadata.google.internal/computeMetadata/v1/instance - curl "${INSTANCE}/hostname" 2> /dev/null | mobyconfig set etc/hostname - # as this is a bit late let us set it anyway - mobyconfig get etc/hostname > /etc/hostname - hostname -F /etc/hostname - curl -f -I "${PROJECT}/attributes/sshKeys" 2> /dev/null > /dev/null && \ - curl "${PROJECT}/attributes/sshKeys" 2> /dev/null | mobyconfig set etc/ssh/authorized_keys - - eend 0 -} diff --git a/alpine/packages/mobyconfig/etc/init.d/database-mac b/alpine/packages/mobyconfig/etc/init.d/database-mac deleted file mode 100755 index 4ef9b57f2..000000000 --- a/alpine/packages/mobyconfig/etc/init.d/database-mac +++ /dev/null @@ -1,24 +0,0 @@ -#!/sbin/openrc-run - -description="Set up database (OSX)." - -depend() { - before docker hostsettings windowsnet -} - -start() { - [ "$(mobyplatform)" = "mac" ] || exit 0 - - ebegin "Setting up database (OSX)" - - mkdir -p /Database - mount -t tmpfs tmpfs /Database - mkdir -p /mnt/db - mount -t 9p -o trans=virtio,dfltuid=1001,dfltgid=50,version=9p2000 db /mnt/db - [ $? -ne 0 ] && rm -rf /Database && printf "Could not mount configuration database\n" 1>&2 && eend 1 - cp -a /mnt/db/branch/master/ro/com.docker.driver.amd64-linux/* /Database - umount /mnt/db - rmdir /mnt/db - - eend 0 -} diff --git a/alpine/packages/mobyconfig/etc/init.d/database-windows b/alpine/packages/mobyconfig/etc/init.d/database-windows deleted file mode 100755 index 387074929..000000000 --- a/alpine/packages/mobyconfig/etc/init.d/database-windows +++ /dev/null @@ -1,23 +0,0 @@ -#!/sbin/openrc-run - -description="Set up database (Windows)." - -depend() { - before docker hostsettings windowsnet -} - -start() { - [ "$(mobyplatform)" = "windows" ] || exit 0 - - ebegin "Setting up database (Windows)" - - mkdir -p /Database - mount -t tmpfs tmpfs /Database - mkdir -p /tmp/db - /sbin/9pmount-vsock listen db /tmp/db - [ $? -ne 0 ] && rm -rf /Database && printf "Could not mount configuration database\n" 1>&2 && eend 1 - cp -a /tmp/db/branch/master/ro/com.docker.driver.amd64-linux/* /Database - umount /tmp/db - - eend 0 -} diff --git a/alpine/packages/mobyconfig/usr/bin/mobyconfig b/alpine/packages/mobyconfig/usr/bin/mobyconfig deleted file mode 100755 index 034d00dd6..000000000 --- a/alpine/packages/mobyconfig/usr/bin/mobyconfig +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -if [ $# -ne 2 ] -then - printf "usage: $0 [get|set|wait|exists|path|dir|find] key\n" - exit 0 -fi - -BASE=/Database - -KEY=$(echo $2 | sed 's@^/@@') - -if [ $1 == "exists" ] -then - [ -d ${BASE}/${KEY} ] && exit 0 - [ -f ${BASE}/${KEY} ] || exit 1 - VALUE="$(cat ${BASE}/${KEY} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - [ -z "${VALUE}" ] && exit 1 - exit 0 -fi - -if [ $1 == "dir" ] -then - [ -d ${BASE}/${KEY} ] && exit 0 || exit 1 -fi - -if [ $1 == "get" ] -then - if [ -f ${BASE}/${KEY} ] - then - cat ${BASE}/${KEY} - exit 0 - else - printf "No such key: ${KEY}\n" 1>&2 - exit 1 - fi -fi - -if [ $1 == "set" ] -then - mkdir -p $(dirname "${BASE}/${KEY}") - cat - > ${BASE}/${KEY} - exit 0 -fi - -if [ $1 == "wait" ] -then - while [ ! -s ${BASE}/${KEY} ] - do - sleep 1 - done - exit 0 -fi - -if [ $1 == "path" ] -then - if [ -e ${BASE}/${KEY} ] - then - printf ${BASE}/${KEY} - exit 0 - else - printf "No such key: ${KEY}\n" 1>&2 - exit 1 - fi -fi - -if [ $1 == "find" ] -then - if [ -e ${BASE}/${KEY} ] - then - find ${BASE}/${KEY} -type f | sed "s@^${BASE}@@g" - exit 0 - else - printf "No such key: ${KEY}\n" 1>&2 - exit 1 - fi -fi - -printf "usage: $0 [get|set|wait|exists|path|dir|find] key\n" -exit 1 diff --git a/alpine/packages/mobyplatform/usr/bin/mobyplatform b/alpine/packages/mobyplatform/usr/bin/mobyplatform deleted file mode 100755 index b8e33aba7..000000000 --- a/alpine/packages/mobyplatform/usr/bin/mobyplatform +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# Returns the platform we are running on - -# return the value matching the kvpair in the command line -kvpair() -{ -awk -v flag=$1 '{ - for(i = 1; i <= NF; i++) { - split($i, kvpair, "="); - if(kvpair[1] == flag) { - printf kvpair[2]; - break; - } - } -}' /proc/cmdline -} - -PLATFORM=$(kvpair mobyplatform) - -[ -z ${PLATFORM} ] && printf unknown || printf ${PLATFORM} diff --git a/alpine/packages/nc-vsock/.gitignore b/alpine/packages/nc-vsock/.gitignore deleted file mode 100644 index 1b91047ac..000000000 --- a/alpine/packages/nc-vsock/.gitignore +++ /dev/null @@ -1 +0,0 @@ -usr/ diff --git a/alpine/packages/nc-vsock/COMMIT.txt b/alpine/packages/nc-vsock/COMMIT.txt deleted file mode 100644 index 6c7352f5c..000000000 --- a/alpine/packages/nc-vsock/COMMIT.txt +++ /dev/null @@ -1,20 +0,0 @@ -From https://github.com/stefanha/linux vsock-extras -f442d29db40a1999d139dccf110f3b590a0ed5b8:nc-vsock.c - -including include/uapi/linux/vm_sockets.h, patched with: - ---- /home/ijc/x 2016-03-17 09:31:23.288944691 +0000 -+++ alpine/packages/nc-vsock/include/uapi/linux/vm_sockets.h 2016-03-17 09:30:07.916069307 +0000 -@@ -16,7 +16,12 @@ - #ifndef _UAPI_VM_SOCKETS_H - #define _UAPI_VM_SOCKETS_H - -+#ifdef __KERNEL__ - #include -+#else -+#define __kernel_sa_family_t sa_family_t -+#include -+#endif - - /* Option name for STREAM socket buffer size. Use as the option name in - * setsockopt(3) or getsockopt(3) to set or get an unsigned long long that diff --git a/alpine/packages/nc-vsock/Makefile b/alpine/packages/nc-vsock/Makefile deleted file mode 100644 index 9c709af8b..000000000 --- a/alpine/packages/nc-vsock/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -C_COMPILE=mobylinux/c-compile:ac075fed7c87e4af30d8490ae0504166cceb0df3@sha256:0e82d441ce112d638f904a08199c76b022c065a2dbf8908bb366755267d4417f - -default: usr/bin/nc-vsock - -DEPS=$(wildcard *.c *.h) - -usr/bin/nc-vsock: $(DEPS) - mkdir -p $(dir $@) - tar cf - $(DEPS) | docker run --rm --net=none --log-driver=none -i $(C_COMPILE) -o $@ -luuid | tar xf - - -clean: - rm -rf usr diff --git a/alpine/packages/nc-vsock/nc-vsock.c b/alpine/packages/nc-vsock/nc-vsock.c deleted file mode 100644 index 184e74dce..000000000 --- a/alpine/packages/nc-vsock/nc-vsock.c +++ /dev/null @@ -1,491 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "vm_sockets.h" - -#define MODE_READ 1 /* From the vsock */ -#define MODE_WRITE 2 /* To the vsock */ -#define MODE_RDWR (MODE_READ|MODE_WRITE) - -/* - * Hyper-V Sockets headerfile pull in too much other stuff. Replicate - * the bits we need here. - */ -#ifndef AF_HYPERV -#define AF_HYPERV 42 -#endif - -struct sockaddr_hv { - unsigned short shv_family; /* Address family */ - unsigned short reserved; /* Must be Zero */ - uuid_t shv_vm_id; /* Not used. Must be Zero. */ - uuid_t shv_service_id; /* Service ID */ -}; -UUID_DEFINE(SHV_VMID_GUEST,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); -#define SHV_PROTO_RAW 1 - -/* - * MSFT's GUIDs are a bonkers mix of native and big endian byte - * order. The uuid library uses RFC 4122, which is always big endian. - * The Linux kernel uuid.h actually looks more like it should be - * called guid.h. We use the uuid library for ease of parsing/printing - * and then this function to convert between UUID and GUID. - * https://en.wikipedia.org/wiki/Globally_unique_identifier - */ -static void uuid2guid(uuid_t u) -{ -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - char t; - t = u[0]; u[0] = u[3]; u[3] = t; - t = u[1]; u[1] = u[2]; u[2] = t; - - t = u[4]; u[4] = u[5]; u[5] = t; - - t = u[6]; u[6] = u[7]; u[7] = t; -#endif -} - -static int parse_cid(const char *cid_str) -{ - char *end = NULL; - long cid = strtol(cid_str, &end, 10); - - if (cid_str != end && *end == '\0') { - return cid; - } else { - fprintf(stderr, "invalid cid: %s\n", cid_str); - return -1; - } -} - -static int parse_port(const char *port_str) -{ - char *end = NULL; - long port = strtol(port_str, &end, 10); - - if (port_str != end && *end == '\0') { - return port; - } else { - fprintf(stderr, "invalid port number: %s\n", port_str); - return -1; - } -} - -static int vsock_listen(const char *port_str) -{ - int listen_fd; - int client_fd; - struct sockaddr_vm sa_listen = { - .svm_family = AF_VSOCK, - .svm_cid = VMADDR_CID_ANY, - }; - struct sockaddr_vm sa_client; - socklen_t socklen_client = sizeof(sa_client); - int port; - int ret; - - port = parse_port(port_str); - if (port < 0) - return -1; - - sa_listen.svm_port = port; - - listen_fd = socket(AF_VSOCK, SOCK_STREAM, 0); - if (listen_fd < 0) { - perror("socket"); - return -1; - } - - ret = bind(listen_fd, (struct sockaddr*)&sa_listen, sizeof(sa_listen)); - if (ret != 0) { - perror("bind"); - close(listen_fd); - return -1; - } - - ret = listen(listen_fd, 1); - if (ret != 0) { - perror("listen"); - close(listen_fd); - return -1; - } - - client_fd = accept(listen_fd, - (struct sockaddr*)&sa_client, &socklen_client); - if (client_fd < 0) { - perror("accept"); - close(listen_fd); - return -1; - } - - fprintf(stderr, "Connection from cid %u port %u...\n", - sa_client.svm_cid, sa_client.svm_port); - - close(listen_fd); - return client_fd; -} - -static int hvsock_listen(const char *port_str) -{ - int listen_fd; - int client_fd; - struct sockaddr_hv sa_listen = { - .shv_family = AF_HYPERV, - .reserved = 0, - }; - struct sockaddr_hv sa_client; - socklen_t socklen_client = sizeof(sa_client); - char vm_str[128], svc_str[128]; - int ret; - - uuid_copy(sa_listen.shv_vm_id, SHV_VMID_GUEST); - - ret = uuid_parse(port_str, sa_listen.shv_service_id); - if (ret != 0) - return -1; - - uuid2guid(sa_listen.shv_service_id); - - listen_fd = socket(AF_HYPERV, SOCK_STREAM, SHV_PROTO_RAW); - if (listen_fd < 0) { - perror("socket"); - return -1; - } - - ret = bind(listen_fd, (struct sockaddr*)&sa_listen, sizeof(sa_listen)); - if (ret != 0) { - perror("bind"); - close(listen_fd); - return -1; - } - - ret = listen(listen_fd, 1); - if (ret != 0) { - perror("listen"); - close(listen_fd); - return -1; - } - - client_fd = accept(listen_fd, - (struct sockaddr*)&sa_client, &socklen_client); - if (client_fd < 0) { - perror("accept"); - close(listen_fd); - return -1; - } - - uuid_unparse(sa_client.shv_vm_id, vm_str); - uuid_unparse(sa_client.shv_service_id, svc_str); - fprintf(stderr, "Connection from %s port %s...\n", vm_str, svc_str); - - close(listen_fd); - return client_fd; -} - -static int tcp_connect(const char *node, const char *service) -{ - int fd = -1; - int ret; - const struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - }; - struct addrinfo *res = NULL; - struct addrinfo *addrinfo; - - ret = getaddrinfo(node, service, &hints, &res); - if (ret != 0) { - fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret)); - return -1; - } - - for (addrinfo = res; addrinfo; addrinfo = addrinfo->ai_next) { - fd = socket(addrinfo->ai_family, - addrinfo->ai_socktype, addrinfo->ai_protocol); - if (fd < 0) { - perror("socket"); - continue; - } - - ret = connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen); - if (ret != 0) { - perror("connect"); - close(fd); - continue; - } - - break; - } - - freeaddrinfo(res); - return fd; -} - -static int vsock_connect(const char *cid_str, const char *port_str) -{ - int fd; - int cid; - int port; - struct sockaddr_vm sa = { - .svm_family = AF_VSOCK, - }; - int ret; - - cid = parse_cid(cid_str); - if (cid < 0) - return -1; - - sa.svm_cid = cid; - - port = parse_port(port_str); - if (port < 0) - return -1; - - sa.svm_port = port; - - fd = socket(AF_VSOCK, SOCK_STREAM, 0); - if (fd < 0) { - perror("socket"); - return -1; - } - - ret = connect(fd, (struct sockaddr*)&sa, sizeof(sa)); - if (ret != 0) { - perror("connect"); - close(fd); - return -1; - } - - return fd; -} - -static int hvsock_connect(const char *vm_str, const char *svc_str) -{ - int fd; - int ret; - struct sockaddr_hv sa = { - .shv_family = AF_HYPERV, - .reserved = 0, - }; - - ret = uuid_parse(vm_str, sa.shv_vm_id); - if (ret != 0) { - fprintf(stderr, "VM GUID parse error: %s\n", vm_str); - return -1; - } - uuid2guid(sa.shv_vm_id); - - ret = uuid_parse(svc_str, sa.shv_service_id); - if (ret != 0) { - fprintf(stderr, "Service GUID parse error: %s\n", svc_str); - return -1; - } - uuid2guid(sa.shv_service_id); - - fd = socket(AF_HYPERV, SOCK_STREAM, SHV_PROTO_RAW); - if (fd < 0) { - perror("socket"); - return -1; - } - - ret = connect(fd, (struct sockaddr*)&sa, sizeof(sa)); - if (ret != 0) { - perror("connect"); - close(fd); - return -1; - } - - return fd; -} - -static int get_fds(int argc, char **argv, int fds[2]) -{ - fds[0] = STDIN_FILENO; - fds[1] = -1; - - if (argc >= 3 && strcmp(argv[1], "-l") == 0) { - if (strstr(argv[2], "-")) - fds[1] = hvsock_listen(argv[2]); - else - fds[1] = vsock_listen(argv[2]); - if (fds[1] < 0) - return -1; - - if (argc == 6 && strcmp(argv[3], "-t") == 0) { - fds[0] = tcp_connect(argv[4], argv[5]); - if (fds[0] < 0) { - return -1; - } - } - return 0; - } else if (argc == 3) { - if (strstr(argv[1], "-") || strstr(argv[2], "-")) - fds[1] = hvsock_connect(argv[1], argv[2]); - else - fds[1] = vsock_connect(argv[1], argv[2]); - if (fds[1] < 0) - return -1; - return 0; - } else { - fprintf(stderr, "usage: %s [-r|-w] [-l [-t ] | ]\n", argv[0]); - return -1; - } -} - -static void set_nonblock(int fd, bool enable) -{ - int ret; - int flags; - - ret = fcntl(fd, F_GETFL); - if (ret < 0) { - perror("fcntl"); - return; - } - - flags = ret & ~O_NONBLOCK; - if (enable) - flags |= O_NONBLOCK; - - fcntl(fd, F_SETFL, flags); -} - -static int xfer_data(int in_fd, int out_fd) -{ - char buf[256*1024]; - char *send_ptr = buf; - ssize_t nbytes; - ssize_t remaining; - int ret; - - if (out_fd == STDIN_FILENO) out_fd = STDOUT_FILENO; - - nbytes = read(in_fd, buf, sizeof(buf)); - if (nbytes < 0) - return -1; - - if (nbytes == 0) { - if (out_fd == STDOUT_FILENO) - return 0; - ret = shutdown(out_fd, SHUT_WR); - if (ret == 0) - return 0; - perror("shutdown"); - return -1; - } - - remaining = nbytes; - while (remaining > 0) { - nbytes = write(out_fd, send_ptr, remaining); - if (nbytes < 0 && errno == EAGAIN) - nbytes = 0; - else if (nbytes <= 0) - return -1; - - if (remaining > nbytes) { - /* Wait for fd to become writeable again */ - for (;;) { - fd_set wfds; - FD_ZERO(&wfds); - FD_SET(out_fd, &wfds); - ret = select(out_fd + 1, NULL, - &wfds, NULL, NULL); - if (ret < 0) { - if (errno == EINTR) { - continue; - } else { - perror("select"); - return -1; - } - } - - if (FD_ISSET(out_fd, &wfds)) - break; - } - } - - send_ptr += nbytes; - remaining -= nbytes; - } - return 1; -} - -static void main_loop(int fds[2], int mode) -{ - fd_set rfds; - int nfds = fds[fds[0] > fds[1] ? 0 : 1] + 1; - /* Which fd's are readable */ - bool rfd0 = !!(mode&MODE_WRITE), rfd1 = !!(mode&MODE_READ); - int ret; - - set_nonblock(fds[0], true); - set_nonblock(fds[1], true); - - for (;;) { - if (!rfd0 && !rfd1) - return; - - FD_ZERO(&rfds); - if (rfd0) - FD_SET(fds[0], &rfds); - if (rfd1) - FD_SET(fds[1], &rfds); - - ret = select(nfds, &rfds, NULL, NULL, NULL); - if (ret < 0) { - if (errno == EINTR) { - continue; - } else { - perror("select"); - return; - } - } - - if (rfd0 && FD_ISSET(fds[0], &rfds)) { - switch (xfer_data(fds[0], fds[1])) { - case -1: return; - case 0: rfd0 = false; break; - case 1: break; - } - } - - if (rfd1 && FD_ISSET(fds[1], &rfds)) { - switch (xfer_data(fds[1], fds[0])) { - case -1: return; - case 0: rfd1 = false; break; - case 1: break; - } - } - } -} - -int main(int argc, char **argv) -{ - int mode = MODE_RDWR; - int fds[2]; - - if (argc >= 2) { - if (!strcmp(argv[1], "-r")) { - mode = MODE_READ; - argv++; argc--; - } else if (!strcmp(argv[1], "-w")) { - mode = MODE_WRITE; - argv++; argc--; - } - } - - if (get_fds(argc, argv, fds) < 0) - return EXIT_FAILURE; - - main_loop(fds, mode); - return EXIT_SUCCESS; -} diff --git a/alpine/packages/nc-vsock/vm_sockets.h b/alpine/packages/nc-vsock/vm_sockets.h deleted file mode 100644 index 41934a185..000000000 --- a/alpine/packages/nc-vsock/vm_sockets.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * VMware vSockets Driver - * - * Copyright (C) 2007-2013 VMware, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation version 2 and no later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#ifndef _UAPI_VM_SOCKETS_H -#define _UAPI_VM_SOCKETS_H - -#ifdef __KERNEL__ -#include -#else -#define __kernel_sa_family_t sa_family_t -#include -#endif - -/* Option name for STREAM socket buffer size. Use as the option name in - * setsockopt(3) or getsockopt(3) to set or get an unsigned long long that - * specifies the size of the buffer underlying a vSockets STREAM socket. - * Value is clamped to the MIN and MAX. - */ - -#define SO_VM_SOCKETS_BUFFER_SIZE 0 - -/* Option name for STREAM socket minimum buffer size. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get an unsigned long long that - * specifies the minimum size allowed for the buffer underlying a vSockets - * STREAM socket. - */ - -#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1 - -/* Option name for STREAM socket maximum buffer size. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get an unsigned long long - * that specifies the maximum size allowed for the buffer underlying a - * vSockets STREAM socket. - */ - -#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2 - -/* Option name for socket peer's host-specific VM ID. Use as the option name - * in getsockopt(3) to get a host-specific identifier for the peer endpoint's - * VM. The identifier is a signed integer. - * Only available for hypervisor endpoints. - */ - -#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3 - -/* Option name for determining if a socket is trusted. Use as the option name - * in getsockopt(3) to determine if a socket is trusted. The value is a - * signed integer. - */ - -#define SO_VM_SOCKETS_TRUSTED 5 - -/* Option name for STREAM socket connection timeout. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get the connection - * timeout for a STREAM socket. - */ - -#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6 - -/* Option name for using non-blocking send/receive. Use as the option name - * for setsockopt(3) or getsockopt(3) to set or get the non-blocking - * transmit/receive flag for a STREAM socket. This flag determines whether - * send() and recv() can be called in non-blocking contexts for the given - * socket. The value is a signed integer. - * - * This option is only relevant to kernel endpoints, where descheduling the - * thread of execution is not allowed, for example, while holding a spinlock. - * It is not to be confused with conventional non-blocking socket operations. - * - * Only available for hypervisor endpoints. - */ - -#define SO_VM_SOCKETS_NONBLOCK_TXRX 7 - -/* The vSocket equivalent of INADDR_ANY. This works for the svm_cid field of - * sockaddr_vm and indicates the context ID of the current endpoint. - */ - -#define VMADDR_CID_ANY -1U - -/* Bind to any available port. Works for the svm_port field of - * sockaddr_vm. - */ - -#define VMADDR_PORT_ANY -1U - -/* Use this as the destination CID in an address when referring to the - * hypervisor. VMCI relies on it being 0, but this would be useful for other - * transports too. - */ - -#define VMADDR_CID_HYPERVISOR 0 - -/* This CID is specific to VMCI and can be considered reserved (even VMCI - * doesn't use it anymore, it's a legacy value from an older release). - */ - -#define VMADDR_CID_RESERVED 1 - -/* Use this as the destination CID in an address when referring to the host - * (any process other than the hypervisor). VMCI relies on it being 2, but - * this would be useful for other transports too. - */ - -#define VMADDR_CID_HOST 2 - -/* Invalid vSockets version. */ - -#define VM_SOCKETS_INVALID_VERSION -1U - -/* The epoch (first) component of the vSockets version. A single byte - * representing the epoch component of the vSockets version. - */ - -#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v) & 0xFF000000) >> 24) - -/* The major (second) component of the vSockets version. A single byte - * representing the major component of the vSockets version. Typically - * changes for every major release of a product. - */ - -#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v) & 0x00FF0000) >> 16) - -/* The minor (third) component of the vSockets version. Two bytes representing - * the minor component of the vSockets version. - */ - -#define VM_SOCKETS_VERSION_MINOR(_v) (((_v) & 0x0000FFFF)) - -/* Address structure for vSockets. The address family should be set to - * AF_VSOCK. The structure members should all align on their natural - * boundaries without resorting to compiler packing directives. The total size - * of this structure should be exactly the same as that of struct sockaddr. - */ - -struct sockaddr_vm { - __kernel_sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(sa_family_t) - - sizeof(unsigned short) - - sizeof(unsigned int) - sizeof(unsigned int)]; -}; - -#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) - -#endif /* _UAPI_VM_SOCKETS_H */ diff --git a/alpine/packages/oom/etc/init.d/oom b/alpine/packages/oom/etc/init.d/oom deleted file mode 100755 index 3a0833ee8..000000000 --- a/alpine/packages/oom/etc/init.d/oom +++ /dev/null @@ -1,21 +0,0 @@ -#!/sbin/openrc-run - -description="oom killer settings" - -depend() -{ - after docker -} - -start() -{ - ebegin "Adjusting oom killer settings" - - for f in $(find /run -name '*.pid') - do - PID=$(cat $f) - [ -f /proc/$PID/oom_score_adj ] && echo "-800" > /proc/$PID/oom_score_adj - done - - eend $? "Failed to adjust oom settings" -} diff --git a/alpine/packages/proxy/.gitignore b/alpine/packages/proxy/.gitignore deleted file mode 100644 index 5ae715395..000000000 --- a/alpine/packages/proxy/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -proxy -usr/ -sbin/ diff --git a/alpine/packages/proxy/LICENSE b/alpine/packages/proxy/LICENSE deleted file mode 100644 index e06d20818..000000000 --- a/alpine/packages/proxy/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/alpine/packages/proxy/Makefile b/alpine/packages/proxy/Makefile deleted file mode 100644 index 493fc032a..000000000 --- a/alpine/packages/proxy/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -GO_COMPILE=mobylinux/go-compile:d2d25ac665b5148ad356d0eab3ff3762a68c633d@sha256:aab55d0c317460850e66a07dd94139cc11ea9e1c0bee88716a6a8c768740885f - -all: usr/bin/slirp-proxy sbin/proxy-vsockd - -DEPS=$(wildcard *.go libproxy/*.go) - -proxy: $(DEPS) ../vendor/manifest - tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - - -usr/bin/slirp-proxy: proxy - mkdir -p usr/bin - cp proxy $@ - -sbin/proxy-vsockd: proxy - mkdir -p sbin - cp proxy $@ - -clean: - rm -rf proxy sbin usr - -.DELETE_ON_ERROR: diff --git a/alpine/packages/proxy/README.md b/alpine/packages/proxy/README.md deleted file mode 100644 index e325cf049..000000000 --- a/alpine/packages/proxy/README.md +++ /dev/null @@ -1,11 +0,0 @@ -docker-proxy which can set up tunnels into the VM -================================================= - -This is a replacement for the built-in `docker-proxy` command, which -proxies data from external ports to internal container ports. - -This program uses the 9P filesystem under /port to extend the port -forward from the host running the Moby VM all the way to the container. - -docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 8080 - diff --git a/alpine/packages/proxy/etc/init.d/proxy b/alpine/packages/proxy/etc/init.d/proxy deleted file mode 100755 index 28f22c2b1..000000000 --- a/alpine/packages/proxy/etc/init.d/proxy +++ /dev/null @@ -1,46 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - before docker -} - -start() -{ - [ "$(mobyplatform)" != "mac" ] && [ "$(mobyplatform)" != "windows" ] && exit 0 - - ebegin "Setting up proxy port service" - - mkdir -p /port - if [ "$(mobyplatform)" = "windows" ]; then - # Running on a Hyper-V hypervisor - /sbin/9pmount-vsock --serviceid 0B95756A-9985-48AD-9470-78E060895BE7 listen port /port - else - mount -t 9p -o trans=virtio,dfltuid=1001,dfltgid=50,version=9p2000 port /port - fi - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/proxy-vsockd.pid - [ -n "${LOGFILE}" ] || LOGFILE=/var/log/proxy-vsockd.log - - ulimit -n 1048576 - start-stop-daemon --start --quiet \ - --background \ - --exec /sbin/proxy-vsockd \ - --make-pidfile --pidfile ${PIDFILE} \ - --stderr "${LOGFILE}" --stdout "${LOGFILE}" \ - -- -vsockPort 62373 -hvGuid 0B95756A-9985-48AD-9470-78E060895BE7 - - eend $? "Failed to start proxy port service" -} - -stop() -{ - [ "$(mobyplatform)" != "mac" ] && [ "$(mobyplatform)" != "windows" ] && exit 0 - - ebegin "Stopping proxy port service" - - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/proxy-vsockd.pid - - start-stop-daemon --stop --quiet --pidfile ${PIDFILE} - - eend $? "Failed to stop proxy-vsockd" -} diff --git a/alpine/packages/proxy/libproxy/network_proxy_test.go b/alpine/packages/proxy/libproxy/network_proxy_test.go deleted file mode 100644 index f4458939f..000000000 --- a/alpine/packages/proxy/libproxy/network_proxy_test.go +++ /dev/null @@ -1,216 +0,0 @@ -package libproxy - -import ( - "bytes" - "fmt" - "io" - "net" - "strings" - "testing" - "time" -) - -var testBuf = []byte("Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo") -var testBufSize = len(testBuf) - -type EchoServer interface { - Run() - Close() - LocalAddr() net.Addr -} - -type TCPEchoServer struct { - listener net.Listener - testCtx *testing.T -} - -type UDPEchoServer struct { - conn net.PacketConn - testCtx *testing.T -} - -func NewEchoServer(t *testing.T, proto, address string) EchoServer { - var server EchoServer - if strings.HasPrefix(proto, "tcp") { - listener, err := net.Listen(proto, address) - if err != nil { - t.Fatal(err) - } - server = &TCPEchoServer{listener: listener, testCtx: t} - } else { - socket, err := net.ListenPacket(proto, address) - if err != nil { - t.Fatal(err) - } - server = &UDPEchoServer{conn: socket, testCtx: t} - } - return server -} - -func (server *TCPEchoServer) Run() { - go func() { - for { - client, err := server.listener.Accept() - if err != nil { - return - } - go func(client net.Conn) { - if _, err := io.Copy(client, client); err != nil { - server.testCtx.Logf("can't echo to the client: %v\n", err.Error()) - } - client.Close() - }(client) - } - }() -} - -func (server *TCPEchoServer) LocalAddr() net.Addr { return server.listener.Addr() } -func (server *TCPEchoServer) Close() { server.listener.Addr() } - -func (server *UDPEchoServer) Run() { - go func() { - readBuf := make([]byte, 1024) - for { - read, from, err := server.conn.ReadFrom(readBuf) - if err != nil { - return - } - for i := 0; i != read; { - written, err := server.conn.WriteTo(readBuf[i:read], from) - if err != nil { - break - } - i += written - } - } - }() -} - -func (server *UDPEchoServer) LocalAddr() net.Addr { return server.conn.LocalAddr() } -func (server *UDPEchoServer) Close() { server.conn.Close() } - -func testProxyAt(t *testing.T, proto string, proxy Proxy, addr string) { - defer proxy.Close() - go proxy.Run() - client, err := net.Dial(proto, addr) - if err != nil { - t.Fatalf("Can't connect to the proxy: %v", err) - } - defer client.Close() - client.SetDeadline(time.Now().Add(10 * time.Second)) - if _, err = client.Write(testBuf); err != nil { - t.Fatal(err) - } - recvBuf := make([]byte, testBufSize) - if _, err = client.Read(recvBuf); err != nil { - t.Fatal(err) - } - if !bytes.Equal(testBuf, recvBuf) { - t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf)) - } -} - -func testProxy(t *testing.T, proto string, proxy Proxy) { - testProxyAt(t, proto, proxy, proxy.FrontendAddr().String()) -} - -func TestTCP4Proxy(t *testing.T) { - backend := NewEchoServer(t, "tcp", "127.0.0.1:0") - defer backend.Close() - backend.Run() - frontendAddr := &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0} - proxy, err := NewProxy(frontendAddr, backend.LocalAddr()) - if err != nil { - t.Fatal(err) - } - testProxy(t, "tcp", proxy) -} - -func TestTCP6Proxy(t *testing.T) { - backend := NewEchoServer(t, "tcp", "[::1]:0") - defer backend.Close() - backend.Run() - frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0} - proxy, err := NewProxy(frontendAddr, backend.LocalAddr()) - if err != nil { - t.Fatal(err) - } - testProxy(t, "tcp", proxy) -} - -func TestTCPDualStackProxy(t *testing.T) { - // If I understand `godoc -src net favoriteAddrFamily` (used by the - // net.Listen* functions) correctly this should work, but it doesn't. - t.Skip("No support for dual stack yet") - backend := NewEchoServer(t, "tcp", "[::1]:0") - defer backend.Close() - backend.Run() - frontendAddr := &net.TCPAddr{IP: net.IPv6loopback, Port: 0} - proxy, err := NewProxy(frontendAddr, backend.LocalAddr()) - if err != nil { - t.Fatal(err) - } - ipv4ProxyAddr := &net.TCPAddr{ - IP: net.IPv4(127, 0, 0, 1), - Port: proxy.FrontendAddr().(*net.TCPAddr).Port, - } - testProxyAt(t, "tcp", proxy, ipv4ProxyAddr.String()) -} - -func TestUDP4Proxy(t *testing.T) { - backend := NewEchoServer(t, "udp", "127.0.0.1:0") - defer backend.Close() - backend.Run() - frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0} - proxy, err := NewProxy(frontendAddr, backend.LocalAddr()) - if err != nil { - t.Fatal(err) - } - testProxy(t, "udp", proxy) -} - -func TestUDP6Proxy(t *testing.T) { - backend := NewEchoServer(t, "udp", "[::1]:0") - defer backend.Close() - backend.Run() - frontendAddr := &net.UDPAddr{IP: net.IPv6loopback, Port: 0} - proxy, err := NewProxy(frontendAddr, backend.LocalAddr()) - if err != nil { - t.Fatal(err) - } - testProxy(t, "udp", proxy) -} - -func TestUDPWriteError(t *testing.T) { - frontendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0} - // Hopefully, this port will be free: */ - backendAddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 25587} - proxy, err := NewProxy(frontendAddr, backendAddr) - if err != nil { - t.Fatal(err) - } - defer proxy.Close() - go proxy.Run() - client, err := net.Dial("udp", "127.0.0.1:25587") - if err != nil { - t.Fatalf("Can't connect to the proxy: %v", err) - } - defer client.Close() - // Make sure the proxy doesn't stop when there is no actual backend: - client.Write(testBuf) - client.Write(testBuf) - backend := NewEchoServer(t, "udp", "127.0.0.1:25587") - defer backend.Close() - backend.Run() - client.SetDeadline(time.Now().Add(10 * time.Second)) - if _, err = client.Write(testBuf); err != nil { - t.Fatal(err) - } - recvBuf := make([]byte, testBufSize) - if _, err = client.Read(recvBuf); err != nil { - t.Fatal(err) - } - if !bytes.Equal(testBuf, recvBuf) { - t.Fatal(fmt.Errorf("Expected [%v] but got [%v]", testBuf, recvBuf)) - } -} diff --git a/alpine/packages/proxy/libproxy/proxy.go b/alpine/packages/proxy/libproxy/proxy.go deleted file mode 100644 index f9ad5fa03..000000000 --- a/alpine/packages/proxy/libproxy/proxy.go +++ /dev/null @@ -1,73 +0,0 @@ -// Package libproxy provides a network Proxy interface and implementations for TCP -// and UDP. -package libproxy - -import ( - "fmt" - "net" - - "github.com/rneugeba/virtsock/go/vsock" -) - -// Proxy defines the behavior of a proxy. It forwards traffic back and forth -// between two endpoints : the frontend and the backend. -// It can be used to do software port-mapping between two addresses. -// e.g. forward all traffic between the frontend (host) 127.0.0.1:3000 -// to the backend (container) at 172.17.42.108:4000. -type Proxy interface { - // Run starts forwarding traffic back and forth between the front - // and back-end addresses. - Run() - // Close stops forwarding traffic and close both ends of the Proxy. - Close() - // FrontendAddr returns the address on which the proxy is listening. - FrontendAddr() net.Addr - // BackendAddr returns the proxied address. - BackendAddr() net.Addr -} - -// NewVsockProxy creates a Proxy listening on Vsock -func NewVsockProxy(frontendAddr *vsock.VsockAddr, backendAddr net.Addr) (Proxy, error) { - switch backendAddr.(type) { - case *net.UDPAddr: - listener, err := vsock.Listen(frontendAddr.Port) - if err != nil { - return nil, err - } - return NewUDPProxy(frontendAddr, NewUDPListener(listener), backendAddr.(*net.UDPAddr)) - case *net.TCPAddr: - listener, err := vsock.Listen(frontendAddr.Port) - if err != nil { - return nil, err - } - return NewTCPProxy(listener, backendAddr.(*net.TCPAddr)) - default: - panic(fmt.Errorf("Unsupported protocol")) - } -} - -// NewIPProxy creates a Proxy according to the specified frontendAddr and backendAddr. -func NewIPProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) { - switch frontendAddr.(type) { - case *net.UDPAddr: - listener, err := net.ListenUDP("udp", frontendAddr.(*net.UDPAddr)) - if err != nil { - return nil, err - } - return NewUDPProxy(frontendAddr, listener, backendAddr.(*net.UDPAddr)) - case *net.TCPAddr: - listener, err := net.Listen("tcp", frontendAddr.String()) - if err != nil { - return nil, err - } - return NewTCPProxy(listener, backendAddr.(*net.TCPAddr)) - case *vsock.VsockAddr: - listener, err := vsock.Listen(frontendAddr.(*vsock.VsockAddr).Port) - if err != nil { - return nil, err - } - return NewTCPProxy(listener, backendAddr.(*net.TCPAddr)) - default: - panic(fmt.Errorf("Unsupported protocol")) - } -} diff --git a/alpine/packages/proxy/libproxy/stub_proxy.go b/alpine/packages/proxy/libproxy/stub_proxy.go deleted file mode 100644 index 97a4d3f58..000000000 --- a/alpine/packages/proxy/libproxy/stub_proxy.go +++ /dev/null @@ -1,31 +0,0 @@ -package libproxy - -import ( - "net" -) - -// StubProxy is a proxy that is a stub (does nothing). -type StubProxy struct { - frontendAddr net.Addr - backendAddr net.Addr -} - -// Run does nothing. -func (p *StubProxy) Run() {} - -// Close does nothing. -func (p *StubProxy) Close() {} - -// FrontendAddr returns the frontend address. -func (p *StubProxy) FrontendAddr() net.Addr { return p.frontendAddr } - -// BackendAddr returns the backend address. -func (p *StubProxy) BackendAddr() net.Addr { return p.backendAddr } - -// NewStubProxy creates a new StubProxy -func NewStubProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) { - return &StubProxy{ - frontendAddr: frontendAddr, - backendAddr: backendAddr, - }, nil -} diff --git a/alpine/packages/proxy/libproxy/tcp_proxy.go b/alpine/packages/proxy/libproxy/tcp_proxy.go deleted file mode 100644 index 04e0fa731..000000000 --- a/alpine/packages/proxy/libproxy/tcp_proxy.go +++ /dev/null @@ -1,106 +0,0 @@ -package libproxy - -import ( - "io" - "log" - "net" -) - -// Conn defines a network connection -type Conn interface { - io.Reader - io.Writer - io.Closer - CloseRead() error - CloseWrite() error -} - -// TCPProxy is a proxy for TCP connections. It implements the Proxy interface to -// handle TCP traffic forwarding between the frontend and backend addresses. -type TCPProxy struct { - listener net.Listener - frontendAddr net.Addr - backendAddr *net.TCPAddr -} - -// NewTCPProxy creates a new TCPProxy. -func NewTCPProxy(listener net.Listener, backendAddr *net.TCPAddr) (*TCPProxy, error) { - // If the port in frontendAddr was 0 then ListenTCP will have a picked - // a port to listen on, hence the call to Addr to get that actual port: - return &TCPProxy{ - listener: listener, - frontendAddr: listener.Addr(), - backendAddr: backendAddr, - }, nil -} - -// HandleTCPConnection forwards the TCP traffic to a specified backend address -func HandleTCPConnection(client Conn, backendAddr *net.TCPAddr, quit chan bool) { - backend, err := net.DialTCP("tcp", nil, backendAddr) - if err != nil { - log.Printf("Can't forward traffic to backend tcp/%v: %s\n", backendAddr, err) - client.Close() - return - } - - event := make(chan int64) - var broker = func(to, from Conn) { - written, err := io.Copy(to, from) - if err != nil { - log.Println("error copying:", err) - } - err = from.CloseRead() - if err != nil { - log.Println("error CloseRead from:", err) - } - err = to.CloseWrite() - if err != nil { - log.Println("error CloseWrite to:", err) - } - event <- written - } - - go broker(client, backend) - go broker(backend, client) - - var transferred int64 - for i := 0; i < 2; i++ { - select { - case written := <-event: - transferred += written - case <-quit: - // Interrupt the two brokers and "join" them. - client.Close() - backend.Close() - for ; i < 2; i++ { - transferred += <-event - } - return - } - } - client.Close() - backend.Close() -} - -// Run starts forwarding the traffic using TCP. -func (proxy *TCPProxy) Run() { - quit := make(chan bool) - defer close(quit) - for { - client, err := proxy.listener.Accept() - if err != nil { - log.Printf("Stopping proxy on tcp/%v for tcp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err) - return - } - go HandleTCPConnection(client.(Conn), proxy.backendAddr, quit) - } -} - -// Close stops forwarding the traffic. -func (proxy *TCPProxy) Close() { proxy.listener.Close() } - -// FrontendAddr returns the TCP address on which the proxy is listening. -func (proxy *TCPProxy) FrontendAddr() net.Addr { return proxy.frontendAddr } - -// BackendAddr returns the TCP proxied address. -func (proxy *TCPProxy) BackendAddr() net.Addr { return proxy.backendAddr } diff --git a/alpine/packages/proxy/libproxy/udp_encapsulation.go b/alpine/packages/proxy/libproxy/udp_encapsulation.go deleted file mode 100644 index a34d090ab..000000000 --- a/alpine/packages/proxy/libproxy/udp_encapsulation.go +++ /dev/null @@ -1,202 +0,0 @@ -package libproxy - -import ( - "bytes" - "encoding/binary" - "io" - "log" - "net" - "sync" -) - -// UDPListener defines a listener interface to read, write and close a UDP connection -type UDPListener interface { - ReadFromUDP(b []byte) (int, *net.UDPAddr, error) - WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) - Close() error -} - -// udpEncapsulator encapsulates a UDP connection and listener -type udpEncapsulator struct { - conn *net.Conn - listener net.Listener - m *sync.Mutex - r *sync.Mutex - w *sync.Mutex -} - -func (u *udpEncapsulator) getConn() (net.Conn, error) { - u.m.Lock() - defer u.m.Unlock() - if u.conn != nil { - return *u.conn, nil - } - conn, err := u.listener.Accept() - if err != nil { - log.Printf("Failed to accept connection: %#v", err) - return nil, err - } - u.conn = &conn - return conn, nil -} - -// ReadFromUDP reads the bytestream from a udpEncapsulator, returning the -// number of bytes read and the unpacked UDPAddr struct -func (u *udpEncapsulator) ReadFromUDP(b []byte) (int, *net.UDPAddr, error) { - conn, err := u.getConn() - if err != nil { - return 0, nil, err - } - u.r.Lock() - defer u.r.Unlock() - datagram := &udpDatagram{payload: b} - length, err := datagram.Unmarshal(conn) - if err != nil { - return 0, nil, err - } - udpAddr := net.UDPAddr{IP: *datagram.IP, Port: int(datagram.Port), Zone: datagram.Zone} - return length, &udpAddr, nil -} - -// WriteToUDP writes a bytestream to a specified UDPAddr, returning the number -// of bytes successfully written -func (u *udpEncapsulator) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) { - conn, err := u.getConn() - if err != nil { - return 0, err - } - u.w.Lock() - defer u.w.Unlock() - datagram := &udpDatagram{payload: b, IP: &addr.IP, Port: uint16(addr.Port), Zone: addr.Zone} - return len(b), datagram.Marshal(conn) -} - -// Close closes the connection in the udpEncapsulator -func (u *udpEncapsulator) Close() error { - if u.conn != nil { - conn := *u.conn - conn.Close() - } - u.listener.Close() - return nil -} - -// NewUDPConn initializes a new UDP connection -func NewUDPConn(conn net.Conn) UDPListener { - var m sync.Mutex - var r sync.Mutex - var w sync.Mutex - return &udpEncapsulator{ - conn: &conn, - listener: nil, - m: &m, - r: &r, - w: &w, - } -} - -// NewUDPListener initializes a new UDP listener -func NewUDPListener(listener net.Listener) UDPListener { - var m sync.Mutex - var r sync.Mutex - var w sync.Mutex - return &udpEncapsulator{ - conn: nil, - listener: listener, - m: &m, - r: &r, - w: &w, - } -} - -type udpDatagram struct { - payload []byte - IP *net.IP - Port uint16 - Zone string -} - -// Marshal marshals data from the udpDatagram to the provided connection -func (u *udpDatagram) Marshal(conn net.Conn) error { - // marshal the variable length header to a temporary buffer - var header bytes.Buffer - var length uint16 - length = uint16(len(*u.IP)) - if err := binary.Write(&header, binary.LittleEndian, &length); err != nil { - return err - } - - if err := binary.Write(&header, binary.LittleEndian, u.IP); err != nil { - return err - } - - if err := binary.Write(&header, binary.LittleEndian, &u.Port); err != nil { - return err - } - - length = uint16(len(u.Zone)) - if err := binary.Write(&header, binary.LittleEndian, &length); err != nil { - return err - } - - if err := binary.Write(&header, binary.LittleEndian, []byte(u.Zone)); err != nil { - return nil - } - - length = uint16(len(u.payload)) - if err := binary.Write(&header, binary.LittleEndian, &length); err != nil { - return nil - } - - length = uint16(2 + header.Len() + len(u.payload)) - if err := binary.Write(conn, binary.LittleEndian, &length); err != nil { - return nil - } - _, err := io.Copy(conn, &header) - if err != nil { - return err - } - payload := bytes.NewBuffer(u.payload) - _, err = io.Copy(conn, payload) - if err != nil { - return err - } - return nil -} - -// Unmarshal unmarshals data from the connection to the udpDatagram -func (u *udpDatagram) Unmarshal(conn net.Conn) (int, error) { - var length uint16 - // frame length - if err := binary.Read(conn, binary.LittleEndian, &length); err != nil { - return 0, err - } - if err := binary.Read(conn, binary.LittleEndian, &length); err != nil { - return 0, err - } - var IP net.IP - IP = make([]byte, length) - if err := binary.Read(conn, binary.LittleEndian, &IP); err != nil { - return 0, err - } - u.IP = &IP - if err := binary.Read(conn, binary.LittleEndian, &u.Port); err != nil { - return 0, err - } - if err := binary.Read(conn, binary.LittleEndian, &length); err != nil { - return 0, err - } - Zone := make([]byte, length) - if err := binary.Read(conn, binary.LittleEndian, &Zone); err != nil { - return 0, err - } - u.Zone = string(Zone) - if err := binary.Read(conn, binary.LittleEndian, &length); err != nil { - return 0, err - } - _, err := io.ReadFull(conn, u.payload[0:length]) - if err != nil { - return 0, err - } - return int(length), nil -} diff --git a/alpine/packages/proxy/libproxy/udp_proxy.go b/alpine/packages/proxy/libproxy/udp_proxy.go deleted file mode 100644 index 29b722c92..000000000 --- a/alpine/packages/proxy/libproxy/udp_proxy.go +++ /dev/null @@ -1,165 +0,0 @@ -package libproxy - -import ( - "encoding/binary" - "log" - "net" - "strings" - "sync" - "syscall" - "time" -) - -const ( - // UDPConnTrackTimeout is the timeout used for UDP connection tracking - UDPConnTrackTimeout = 90 * time.Second - // UDPBufSize is the buffer size for the UDP proxy - UDPBufSize = 65507 -) - -// A net.Addr where the IP is split into two fields so you can use it as a key -// in a map: -type connTrackKey struct { - IPHigh uint64 - IPLow uint64 - Port int -} - -func newConnTrackKey(addr *net.UDPAddr) *connTrackKey { - if len(addr.IP) == net.IPv4len { - return &connTrackKey{ - IPHigh: 0, - IPLow: uint64(binary.BigEndian.Uint32(addr.IP)), - Port: addr.Port, - } - } - return &connTrackKey{ - IPHigh: binary.BigEndian.Uint64(addr.IP[:8]), - IPLow: binary.BigEndian.Uint64(addr.IP[8:]), - Port: addr.Port, - } -} - -type connTrackMap map[connTrackKey]*net.UDPConn - -// UDPProxy is proxy for which handles UDP datagrams. It implements the Proxy -// interface to handle UDP traffic forwarding between the frontend and backend -// addresses. -type UDPProxy struct { - listener UDPListener - frontendAddr net.Addr - backendAddr *net.UDPAddr - connTrackTable connTrackMap - connTrackLock sync.Mutex -} - -// NewUDPProxy creates a new UDPProxy. -func NewUDPProxy(frontendAddr net.Addr, listener UDPListener, backendAddr *net.UDPAddr) (*UDPProxy, error) { - - return &UDPProxy{ - listener: listener, - frontendAddr: frontendAddr, - backendAddr: backendAddr, - connTrackTable: make(connTrackMap), - }, nil -} - -func (proxy *UDPProxy) replyLoop(proxyConn *net.UDPConn, clientAddr *net.UDPAddr, clientKey *connTrackKey) { - defer func() { - proxy.connTrackLock.Lock() - delete(proxy.connTrackTable, *clientKey) - proxy.connTrackLock.Unlock() - proxyConn.Close() - }() - - readBuf := make([]byte, UDPBufSize) - for { - proxyConn.SetReadDeadline(time.Now().Add(UDPConnTrackTimeout)) - again: - read, err := proxyConn.Read(readBuf) - if err != nil { - if err, ok := err.(*net.OpError); ok && err.Err == syscall.ECONNREFUSED { - // This will happen if the last write failed - // (e.g: nothing is actually listening on the - // proxied port on the container), ignore it - // and continue until UDPConnTrackTimeout - // expires: - goto again - } - return - } - for i := 0; i != read; { - written, err := proxy.listener.WriteToUDP(readBuf[i:read], clientAddr) - if err != nil { - return - } - i += written - } - } -} - -// Run starts forwarding the traffic using UDP. -func (proxy *UDPProxy) Run() { - readBuf := make([]byte, UDPBufSize) - for { - read, from, err := proxy.listener.ReadFromUDP(readBuf) - if err != nil { - // NOTE: Apparently ReadFrom doesn't return - // ECONNREFUSED like Read do (see comment in - // UDPProxy.replyLoop) - if !isClosedError(err) { - log.Printf("Stopping proxy on %v for udp/%v (%s)", proxy.frontendAddr, proxy.backendAddr, err) - } - break - } - - fromKey := newConnTrackKey(from) - proxy.connTrackLock.Lock() - proxyConn, hit := proxy.connTrackTable[*fromKey] - if !hit { - proxyConn, err = net.DialUDP("udp", nil, proxy.backendAddr) - if err != nil { - log.Printf("Can't proxy a datagram to udp/%s: %s\n", proxy.backendAddr, err) - proxy.connTrackLock.Unlock() - continue - } - proxy.connTrackTable[*fromKey] = proxyConn - go proxy.replyLoop(proxyConn, from, fromKey) - } - proxy.connTrackLock.Unlock() - for i := 0; i != read; { - written, err := proxyConn.Write(readBuf[i:read]) - if err != nil { - log.Printf("Can't proxy a datagram to udp/%s: %s\n", proxy.backendAddr, err) - break - } - i += written - } - } -} - -// Close stops forwarding the traffic. -func (proxy *UDPProxy) Close() { - proxy.listener.Close() - proxy.connTrackLock.Lock() - defer proxy.connTrackLock.Unlock() - for _, conn := range proxy.connTrackTable { - conn.Close() - } -} - -// FrontendAddr returns the UDP address on which the proxy is listening. -func (proxy *UDPProxy) FrontendAddr() net.Addr { return proxy.frontendAddr } - -// BackendAddr returns the proxied UDP address. -func (proxy *UDPProxy) BackendAddr() net.Addr { return proxy.backendAddr } - -func isClosedError(err error) bool { - /* This comparison is ugly, but unfortunately, net.go doesn't export errClosing. - * See: - * http://golang.org/src/pkg/net/net.go - * https://code.google.com/p/go/issues/detail?id=4337 - * https://groups.google.com/forum/#!msg/golang-nuts/0_aaCvBmOcM/SptmDyX1XJMJ - */ - return strings.HasSuffix(err.Error(), "use of closed network connection") -} diff --git a/alpine/packages/proxy/main.go b/alpine/packages/proxy/main.go deleted file mode 100644 index 6eb68d43c..000000000 --- a/alpine/packages/proxy/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "os" - "path" -) - -func main() { - if path.Base(os.Args[0]) == "proxy-vsockd" { - manyPorts() - return - } - onePort() -} diff --git a/alpine/packages/proxy/many.go b/alpine/packages/proxy/many.go deleted file mode 100644 index 1b769277f..000000000 --- a/alpine/packages/proxy/many.go +++ /dev/null @@ -1,117 +0,0 @@ -package main - -import ( - "encoding/binary" - "flag" - "log" - "net" - "proxy/libproxy" - - "github.com/rneugeba/virtsock/go/hvsock" - "github.com/rneugeba/virtsock/go/vsock" -) - -// Listen on virtio-vsock and AF_HYPERV for multiplexed connections -func manyPorts() { - var ( - vsockPort = flag.Int("vsockPort", 62373, "virtio-vsock port") - hvGUID = flag.String("hvGuid", "0B95756A-9985-48AD-9470-78E060895BE7", "Hyper-V service GUID") - ) - flag.Parse() - - listeners := make([]net.Listener, 0) - - vsock, err := vsock.Listen(uint(*vsockPort)) - if err != nil { - log.Printf("Failed to bind to vsock port %d: %#v", vsockPort, err) - } else { - listeners = append(listeners, vsock) - } - svcid, _ := hvsock.GuidFromString(*hvGUID) - hvsock, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - log.Printf("Failed to bind hvsock guid: %s: %#v", *hvGUID, err) - } else { - listeners = append(listeners, hvsock) - } - - quit := make(chan bool) - defer close(quit) - - for _, l := range listeners { - go func(l net.Listener) { - for { - conn, err := l.Accept() - if err != nil { - log.Printf("Error accepting connection: %#v", err) - return // no more listening - } - go func(conn net.Conn) { - // Read header which describes TCP/UDP and destination IP:port - d, err := unmarshalDestination(conn) - if err != nil { - log.Printf("Failed to unmarshal header: %#v", err) - conn.Close() - return - } - switch d.Proto { - case TCP: - backendAddr := net.TCPAddr{IP: d.IP, Port: int(d.Port), Zone: ""} - libproxy.HandleTCPConnection(conn.(libproxy.Conn), &backendAddr, quit) - break - case UDP: - backendAddr := &net.UDPAddr{IP: d.IP, Port: int(d.Port), Zone: ""} - - proxy, err := libproxy.NewUDPProxy(backendAddr, libproxy.NewUDPConn(conn), backendAddr) - if err != nil { - log.Printf("Failed to setup UDP proxy for %s: %#v", backendAddr, err) - conn.Close() - return - } - proxy.Run() - break - default: - log.Printf("Unknown protocol: %d", d.Proto) - conn.Close() - return - } - }(conn) - } - }(l) - } - forever := make(chan int) - <-forever -} - -const ( - // TCP protocol const - TCP = 1 - // UDP protocol const - UDP = 2 -) - -type destination struct { - Proto uint8 - IP net.IP - Port uint16 -} - -func unmarshalDestination(conn net.Conn) (destination, error) { - d := destination{} - if err := binary.Read(conn, binary.LittleEndian, &d.Proto); err != nil { - return d, err - } - var length uint16 - // IP length - if err := binary.Read(conn, binary.LittleEndian, &length); err != nil { - return d, err - } - d.IP = make([]byte, length) - if err := binary.Read(conn, binary.LittleEndian, &d.IP); err != nil { - return d, err - } - if err := binary.Read(conn, binary.LittleEndian, &d.Port); err != nil { - return d, err - } - return d, nil -} diff --git a/alpine/packages/proxy/one.go b/alpine/packages/proxy/one.go deleted file mode 100644 index 690972426..000000000 --- a/alpine/packages/proxy/one.go +++ /dev/null @@ -1,105 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "log" - "net" - "os" - "proxy/libproxy" - "strings" - "syscall" -) - -func onePort() { - host, _, container, localIP := parseHostContainerAddrs() - - var ipP libproxy.Proxy - var err error - - if localIP { - ipP, err = listenInVM(host, container) - if err != nil { - sendError(err) - } - } - - ctl, err := exposePort(host, container) - if err != nil { - sendError(err) - } - - go handleStopSignals() - // TODO: avoid this line if we are running in a TTY - sendOK() - if ipP != nil { - ipP.Run() - } else { - select {} // sleep forever - } - ctl.Close() // ensure ctl remains alive and un-GCed until here - os.Exit(0) -} - -// Best-effort attempt to listen on the address in the VM. This is for -// backwards compatibility with software that expects to be able to listen on -// 0.0.0.0 and then connect from within a container to the external port. -// If the address doesn't exist in the VM (i.e. it exists only on the host) -// then this is not a hard failure. -func listenInVM(host net.Addr, container net.Addr) (libproxy.Proxy, error) { - ipP, err := libproxy.NewIPProxy(host, container) - if err == nil { - return ipP, nil - } - if opError, ok := err.(*net.OpError); ok { - if syscallError, ok := opError.Err.(*os.SyscallError); ok { - if syscallError.Err == syscall.EADDRNOTAVAIL { - log.Printf("Address %s doesn't exist in the VM: only binding on the host", host) - return nil, nil // Non-fatal error - } - } - } - return nil, err -} - -func exposePort(host net.Addr, container net.Addr) (*os.File, error) { - name := host.Network() + ":" + host.String() + ":" + container.Network() + ":" + container.String() - log.Printf("exposePort %s\n", name) - err := os.Mkdir("/port/"+name, 0) - if err != nil { - log.Printf("Failed to mkdir /port/%s: %#v\n", name, err) - return nil, err - } - ctl, err := os.OpenFile("/port/"+name+"/ctl", os.O_RDWR, 0) - if err != nil { - log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err) - return nil, err - } - _, err = ctl.WriteString(fmt.Sprintf("%s", name)) - if err != nil { - log.Printf("Failed to open /port/%s/ctl: %#v\n", name, err) - return nil, err - } - _, err = ctl.Seek(0, 0) - if err != nil { - log.Printf("Failed to seek on /port/%s/ctl: %#v\n", name, err) - return nil, err - } - results := make([]byte, 100) - count, err := ctl.Read(results) - if err != nil { - log.Printf("Failed to read from /port/%s/ctl: %#v\n", name, err) - return nil, err - } - // We deliberately keep the control file open since 9P clunk - // will trigger a shutdown on the host side. - - response := string(results[0:count]) - if strings.HasPrefix(response, "ERROR ") { - os.Remove("/port/" + name + "/ctl") - response = strings.Trim(response[6:], " \t\r\n") - return nil, errors.New(response) - } - // Hold on to a reference to prevent premature GC and close - return ctl, nil -} diff --git a/alpine/packages/proxy/proxy.go b/alpine/packages/proxy/proxy.go deleted file mode 100644 index 5f1083a6d..000000000 --- a/alpine/packages/proxy/proxy.go +++ /dev/null @@ -1,85 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "log" - "net" - "os" - "os/signal" - "syscall" -) - -var interactiveMode bool - -// sendError signals the error to the parent and quits the process. -func sendError(err error) { - if interactiveMode { - log.Fatal("Failed to set up proxy", err) - } - f := os.NewFile(3, "signal-parent") - - fmt.Fprintf(f, "1\n%s", err) - f.Close() - os.Exit(1) -} - -// sendOK signals the parent that the forward is running. -func sendOK() { - if interactiveMode { - log.Println("Proxy running") - return - } - f := os.NewFile(3, "signal-parent") - fmt.Fprint(f, "0\n") - f.Close() -} - -// Map dynamic TCP ports onto vsock ports over this offset -var vSockTCPPortOffset = 0x10000 - -// Map dynamic UDP ports onto vsock ports over this offset -var vSockUDPPortOffset = 0x20000 - -// From docker/libnetwork/portmapper/proxy.go: - -// parseHostContainerAddrs parses the flags passed on reexec to create the TCP or UDP -// net.Addrs to map the host and container ports -func parseHostContainerAddrs() (host net.Addr, port int, container net.Addr, localIP bool) { - var ( - proto = flag.String("proto", "tcp", "proxy protocol") - hostIP = flag.String("host-ip", "", "host ip") - hostPort = flag.Int("host-port", -1, "host port") - containerIP = flag.String("container-ip", "", "container ip") - containerPort = flag.Int("container-port", -1, "container port") - interactive = flag.Bool("i", false, "print success/failure to stdout/stderr") - noLocalIP = flag.Bool("no-local-ip", false, "bind only on the Host, not in the VM") - ) - - flag.Parse() - interactiveMode = *interactive - - switch *proto { - case "tcp": - host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort} - port = vSockTCPPortOffset + *hostPort - container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort} - case "udp": - host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort} - port = vSockUDPPortOffset + *hostPort - container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort} - default: - log.Fatalf("unsupported protocol %s", *proto) - } - localIP = !*noLocalIP - return host, port, container, localIP -} - -func handleStopSignals() { - s := make(chan os.Signal, 10) - signal.Notify(s, os.Interrupt, syscall.SIGTERM, syscall.SIGSTOP) - - for range s { - os.Exit(0) - } -} diff --git a/alpine/packages/tap-vsockd/.gitignore b/alpine/packages/tap-vsockd/.gitignore deleted file mode 100644 index e1ae85e07..000000000 --- a/alpine/packages/tap-vsockd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sbin diff --git a/alpine/packages/tap-vsockd/Makefile b/alpine/packages/tap-vsockd/Makefile deleted file mode 100644 index d6bdf6f7f..000000000 --- a/alpine/packages/tap-vsockd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -C_COMPILE=mobylinux/c-compile:ac075fed7c87e4af30d8490ae0504166cceb0df3@sha256:0e82d441ce112d638f904a08199c76b022c065a2dbf8908bb366755267d4417f - -default: sbin/tap-vsockd - -DEPS=$(wildcard *.c *.h) - -sbin/tap-vsockd: $(DEPS) - mkdir -p $(dir $@) - tar cf - $(DEPS) | docker run --rm --net=none --log-driver=none -i $(C_COMPILE) -o $@ -lpthread | tar xf - - -clean: - rm -rf sbin diff --git a/alpine/packages/tap-vsockd/etc/init.d/tap-vsockd b/alpine/packages/tap-vsockd/etc/init.d/tap-vsockd deleted file mode 100755 index 6278c440f..000000000 --- a/alpine/packages/tap-vsockd/etc/init.d/tap-vsockd +++ /dev/null @@ -1,48 +0,0 @@ -#!/sbin/openrc-run - -description="VPN proxy" - -depend() -{ - need database-windows - before net -} - -start() -{ - [ "$(mobyplatform)" != "windows" ] && exit 0 - - mobyconfig exists network || exit 0 - NETWORK_MODE="$(mobyconfig get network | tr -d '[[:space:]]')" - [ "${NETWORK_MODE}" = "hybrid" ] || exit 0 - - ebegin "Starting VPN proxy" - - PIDFILE=/var/run/tap-vsockd.pid - start-stop-daemon --start \ - --exec /sbin/tap-vsockd \ - --background \ - --pidfile ${PIDFILE} \ - -- \ - --tap eth0 \ - --message-size 8192 \ - --buffer-size 262144 \ - --pidfile "${PIDFILE}" \ - --listen - - eend $? "Failed to start VPN proxy" -} - -stop() -{ - [ "$(mobyplatform)" != "windows" ] && exit 0 - - ebegin "Stopping VPN proxy" - - PIDFILE=/var/run/tap-vsockd.pid - - start-stop-daemon --stop --quiet \ - --pidfile "${PIDFILE}" - - eend $? "Failed to stop VPN proxy" -} diff --git a/alpine/packages/tap-vsockd/hvsock.c b/alpine/packages/tap-vsockd/hvsock.c deleted file mode 100644 index 59251bab2..000000000 --- a/alpine/packages/tap-vsockd/hvsock.c +++ /dev/null @@ -1,40 +0,0 @@ -#include - -#include "hvsock.h" - -int parseguid(const char *s, GUID *g) -{ - int res; - int p0, p1, p2, p3, p4, p5, p6, p7; - - res = sscanf(s, GUID_FMT, - &g->Data1, &g->Data2, &g->Data3, - &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7); - if (res != 11) - return 1; - - g->Data4[0] = p0; - g->Data4[1] = p1; - g->Data4[2] = p2; - g->Data4[3] = p3; - g->Data4[4] = p4; - g->Data4[5] = p5; - g->Data4[6] = p6; - g->Data4[7] = p7; - - return 0; -} - -DEFINE_GUID(HV_GUID_ZERO, - 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); -DEFINE_GUID(HV_GUID_BROADCAST, - 0xFFFFFFFF, 0xFFFF, 0xFFFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); -DEFINE_GUID(HV_GUID_WILDCARD, -0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - -DEFINE_GUID(HV_GUID_CHILDREN, - 0x90db8b89, 0x0d35, 0x4f79, 0x8c, 0xe9, 0x49, 0xea, 0x0a, 0xc8, 0xb7, 0xcd); -DEFINE_GUID(HV_GUID_LOOPBACK, - 0xe0e16197, 0xdd56, 0x4a10, 0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38); -DEFINE_GUID(HV_GUID_PARENT, - 0xa42e7cda, 0xd03f, 0x480c, 0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78); diff --git a/alpine/packages/tap-vsockd/hvsock.h b/alpine/packages/tap-vsockd/hvsock.h deleted file mode 100644 index bf680a7a2..000000000 --- a/alpine/packages/tap-vsockd/hvsock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* AF_HYPERV definitions and utilities */ - -#include -#include -#include -#include - -/* GUID handling */ -typedef struct _GUID { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} GUID; - -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} - -/* Helper macros for parsing/printing GUIDs */ -#define GUID_FMT "%08x-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x" -#define GUID_ARGS(_g) \ - (_g).Data1, (_g).Data2, (_g).Data3, \ - (_g).Data4[0], (_g).Data4[1], (_g).Data4[2], (_g).Data4[3], \ - (_g).Data4[4], (_g).Data4[5], (_g).Data4[6], (_g).Data4[7] -#define GUID_SARGS(_g) \ - &(_g).Data1, &(_g).Data2, &(_g).Data3, \ - &(_g).Data4[0], &(_g).Data4[1], &(_g).Data4[2], &(_g).Data4[3], \ - &(_g).Data4[4], &(_g).Data4[5], &(_g).Data4[6], &(_g).Data4[7] - -extern int parseguid(const char *s, GUID *g); - -/* HV Socket definitions */ -#define AF_HYPERV 43 -#define HV_PROTOCOL_RAW 1 - -typedef struct _SOCKADDR_HV { - unsigned short Family; - unsigned short Reserved; - GUID VmId; - GUID ServiceId; -} SOCKADDR_HV; - -extern const GUID HV_GUID_ZERO; -extern const GUID HV_GUID_BROADCAST; -extern const GUID HV_GUID_WILDCARD; -extern const GUID HV_GUID_CHILDREN; -extern const GUID HV_GUID_LOOPBACK; -extern const GUID HV_GUID_PARENT; diff --git a/alpine/packages/tap-vsockd/protocol.c b/alpine/packages/tap-vsockd/protocol.c deleted file mode 100644 index 6604e65ec..000000000 --- a/alpine/packages/tap-vsockd/protocol.c +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "protocol.h" - -/* Version 0 of the protocol used this */ -char expected_hello_old[5] = {'V', 'M', 'N', 'E', 'T'}; - -/* Version 1 and later of the protocol used this */ -char expected_hello[5] = {'V', 'M', 'N', '3', 'T'}; - -int really_read(int fd, uint8_t *buffer, size_t total) -{ - size_t remaining = total; - ssize_t n; - - while (remaining > 0) { - n = read(fd, buffer, remaining); - if (n == 0) { - syslog(LOG_CRIT, "EOF reading from socket: closing\n"); - goto err; - } - if (n < 0) { - syslog(LOG_CRIT, - "Failure reading from socket: closing: %s", - strerror(errno)); - goto err; - } - remaining -= (size_t) n; - buffer = buffer + n; - } - return 0; -err: - /* - * On error: stop reading from the socket and trigger a clean - * shutdown - */ - shutdown(fd, SHUT_RD); - return -1; -} - -int really_write(int fd, uint8_t *buffer, size_t total) -{ - size_t remaining = total; - ssize_t n; - - while (remaining > 0) { - n = write(fd, buffer, remaining); - if (n == 0) { - syslog(LOG_CRIT, "EOF writing to socket: closing"); - goto err; - } - if (n < 0) { - syslog(LOG_CRIT, - "Failure writing to socket: closing: %s", - strerror(errno)); - goto err; - } - remaining -= (size_t) n; - buffer = buffer + n; - } - return 0; -err: - /* On error: stop listening to the socket */ - shutdown(fd, SHUT_WR); - return -1; -} - -struct init_message *create_init_message() -{ - struct init_message *m; - - m = malloc(sizeof(struct init_message)); - if (!m) - return NULL; - - bzero(m, sizeof(struct init_message)); - memcpy(&m->hello[0], &expected_hello[0], sizeof(m->hello)); - m->version = CURRENT_VERSION; - memset(&m->commit[0], 0, sizeof(m->commit)); - - return m; -} - -char *print_init_message(struct init_message *m) -{ - char tmp[41]; - - memcpy(&tmp[0], &m->commit[0], 40); - tmp[40] = '\000'; - char *buffer; - int n; - - buffer = malloc(80); - if (!buffer) - return NULL; - - n = snprintf(buffer, 80, "version %d, commit %s", m->version, tmp); - if (n < 0) { - perror("Failed to format init_message"); - exit(1); - } - return buffer; -} - -int read_init_message(int fd, struct init_message *ci) -{ - int res; - - bzero(ci, sizeof(struct init_message)); - - res = really_read(fd, (uint8_t *)&ci->hello[0], sizeof(ci->hello)); - if (res == -1) { - syslog(LOG_CRIT, "Failed to read hello from client"); - return -1; - } - - res = memcmp(&ci->hello[0], - &expected_hello_old[0], sizeof(expected_hello_old)); - if (res == 0) { - ci->version = 0; - return 0; - } - - res = memcmp(&ci->hello[0], - &expected_hello[0], sizeof(expected_hello)); - if (res != 0) { - syslog(LOG_CRIT, "Failed to read header magic from client"); - return -1; - } - - res = really_read(fd, (uint8_t *)&ci->version, sizeof(ci->version)); - if (res == -1) { - syslog(LOG_CRIT, "Failed to read header version from client"); - return -1; - } - - res = really_read(fd, (uint8_t *)&ci->commit[0], sizeof(ci->commit)); - if (res == -1) { - syslog(LOG_CRIT, "Failed to read header hash from client"); - return -1; - } - - return 0; -} - -int write_init_message(int fd, struct init_message *ci) -{ - int res; - - res = really_write(fd, (uint8_t *)&ci->hello[0], sizeof(ci->hello)); - if (res == -1) { - syslog(LOG_CRIT, "Failed to write hello to client"); - return -1; - } - if (ci->version > 0) { - res = really_write(fd, (uint8_t *)&ci->version, - sizeof(ci->version)); - if (res == -1) { - syslog(LOG_CRIT, "Failed to write version to client"); - return -1; - } - res = really_write(fd, (uint8_t *)&ci->commit[0], - sizeof(ci->commit)); - if (res == -1) { - syslog(LOG_CRIT, - "Failed to write header hash to client"); - return -1; - } - } - return 0; -} - -int read_vif_info(int fd, struct vif_info *vif) -{ - uint8_t buffer[10]; - - if (really_read(fd, &buffer[0], sizeof(buffer)) == -1) { - syslog(LOG_CRIT, "Failed to read vif info from client"); - return -1; - } - - vif->mtu = (size_t)(buffer[0] | (buffer[1] << 8)); - vif->max_packet_size = (size_t)(buffer[2] | (buffer[3] << 8)); - memcpy(vif->mac, &buffer[4], 6); - return 0; -} - - -int write_vif_info(int fd, struct vif_info *vif) -{ - uint8_t buffer[10]; - - buffer[0] = (uint8_t) ((vif->mtu >> 0) & 0xff); - buffer[1] = (uint8_t) ((vif->mtu >> 8) & 0xff); - buffer[2] = (uint8_t) ((vif->max_packet_size >> 0) & 0xff); - buffer[3] = (uint8_t) ((vif->max_packet_size >> 8) & 0xff); - memcpy(&buffer[0] + 4, &(vif->mac)[0], 6); - - if (really_write(fd, &buffer[0], sizeof(buffer)) == -1) { - syslog(LOG_CRIT, "Failed to write vif into to client"); - return -1; - } - return 0; -} - -int write_command(int fd, enum command *c) -{ - uint8_t command = *c; - - if (really_write(fd, (uint8_t *)&command, sizeof(command)) == -1) { - syslog(LOG_CRIT, "Failed to write command to client"); - return -1; - } - return 0; -} - -int write_ethernet_args(int fd, struct ethernet_args *args) -{ - if (really_write(fd, (uint8_t *)&args->uuid_string[0], 36) == -1) { - syslog(LOG_CRIT, "Failed to write ethernet args to client"); - return -1; - } - return 0; -} diff --git a/alpine/packages/tap-vsockd/protocol.h b/alpine/packages/tap-vsockd/protocol.h deleted file mode 100644 index 05097b4e2..000000000 --- a/alpine/packages/tap-vsockd/protocol.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _VMNET_PROTOCOL_H_ -#define _VMNET_PROTOCOL_H_ - -#include -#include - -/* Client -> Server init_message */ -/* Server -> Client init_message */ -struct init_message { - char hello[5]; - uint8_t _padding[3]; - uint32_t version; - char commit[40]; /* git sha of the compiled commit */ -}; - -/* - * This should be bumped whenever we add something (like a feature or a - * bugfix) and we wish the UI to be able to detect when to trigger a - * reinstall. - */ -#define CURRENT_VERSION 13 - -extern struct init_message *create_init_message(void); -extern int read_init_message(int fd, struct init_message *ci); -extern int write_init_message(int fd, struct init_message *ci); -extern char *print_init_message(struct init_message *m); - -/* Client -> Server command */ -enum command { - ethernet = 1, -}; - -extern int write_command(int fd, enum command *c); - -/* Client -> Server command arguments */ -struct ethernet_args { - char uuid_string[36]; -}; - -extern int write_ethernet_args(int fd, struct ethernet_args *args); - -/* Server -> Client: details of a vif */ -struct vif_info { - uint8_t mac[6]; - short _padding; - size_t max_packet_size; - size_t mtu; -}; - -extern int read_vif_info(int fd, struct vif_info *vif); -extern int write_vif_info(int fd, struct vif_info *vif); - -extern char expected_hello[5]; -extern char expected_hello_old[5]; - -extern int really_read(int fd, uint8_t *buffer, size_t total); -extern int really_write(int fd, uint8_t *buffer, size_t total); - -#endif /* _VMNET_PROTOCOL_H_ */ diff --git a/alpine/packages/tap-vsockd/ring.c b/alpine/packages/tap-vsockd/ring.c deleted file mode 100644 index fe7791d58..000000000 --- a/alpine/packages/tap-vsockd/ring.c +++ /dev/null @@ -1,269 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "ring.h" - -extern void fatal(const char *msg); - - -/* A fixed-size circular buffer. - - The producer and consumer are positive integers from 0 to 2 * size-1. - Adds are modulo 2 * size. This effectively uses one bit to distinguish - the case where the buffer is empty (consumer == producer) from the case - where the buffer is full (consumer + size == producer). */ -struct ring { - int producer; /* Next sequence number to be written */ - int consumer; /* Next sequence number to be read */ - int last; /* Sequence number of end of stream or -1 */ - int size; /* Maximum number of buffered bytes */ - pthread_cond_t c; - pthread_mutex_t m; - char *data; -}; - -struct ring *ring_allocate(int size) -{ - struct ring *ring = (struct ring*)malloc(sizeof(struct ring)); - if (!ring) { - fatal("Failed to allocate ring buffer metadata"); - } - ring->data = (char*)malloc(size); - if (!ring->data) { - fatal("Failed to allocate ring buffer data"); - } - int err = 0; - if ((err = pthread_cond_init(&ring->c, NULL)) != 0) { - errno = err; - fatal("Failed to create condition variable"); - } - if ((err = pthread_mutex_init(&ring->m, NULL)) != 0) { - errno = err; - fatal("Failed to create mutex"); - } - ring->size = size; - ring->producer = ring->consumer = 0; - ring->last = -1; - return ring; -} - -#define RING_DATA_AVAILABLE(r) \ - ((r->producer >= r->consumer) ? \ - (r->producer - r->consumer) : \ - (2 * r->size + r->producer - r->consumer)) -#define RING_FREE_REQUESTS(r) (r->size - RING_DATA_AVAILABLE(r)) - -#define RING_GET(r, seq) (&(r->data[seq % r->size])) - -/* Signal that new data is been produced */ -void ring_producer_advance(struct ring *ring, int n) -{ - int err = 0; - assert(n >= 0); - if ((err = pthread_mutex_lock(&ring->m)) != 0) { - errno = err; - fatal("Failed to lock mutex"); - } - ring->producer = (ring->producer + n) % (2 * ring->size); - if ((err = pthread_cond_broadcast(&ring->c)) != 0) { - errno = err; - fatal("Failed to signal condition variable"); - } - if ((err = pthread_mutex_unlock(&ring->m)) != 0) { - errno = err; - fatal("Failed to unlock mutex"); - } - return; -} - -/* Signal that data has been consumed */ -void ring_consumer_advance(struct ring *ring, int n) -{ - int err = 0; - assert(n >= 0); - if ((err = pthread_mutex_lock(&ring->m)) != 0) { - errno = err; - fatal("Failed to lock mutex"); - } - ring->consumer = (ring->consumer + n) % (2 * ring->size); - - if ((err = pthread_cond_broadcast(&ring->c)) != 0) { - errno = err; - fatal("Failed to signal condition variable"); - } - if ((err = pthread_mutex_unlock(&ring->m)) != 0) { - errno = err; - fatal("Failed to unlock mutex"); - } - return; -} - -/* The producer sends Eof */ -void ring_producer_eof(struct ring *ring) -{ - int err = 0; - if ((err = pthread_mutex_lock(&ring->m)) != 0) { - errno = err; - fatal("Failed to lock mutex"); - } - ring->last = ring->producer - 1; - if ((err = pthread_cond_broadcast(&ring->c)) != 0) { - errno = err; - fatal("Failed to signal condition variable"); - } - if ((err = pthread_mutex_unlock(&ring->m)) != 0) { - errno = err; - fatal("Failed to unlock mutex"); - } - return; -} - -/* Wait for n bytes to become available. If the ring has shutdown, return - non-zero. If data is available then return zero and fill in the first - iovec_len entries of the iovec. */ -int ring_producer_wait_available( - struct ring *ring, size_t n, struct iovec *iovec, int *iovec_len -) { - int ret = 1; - int err = 0; - if ((err = pthread_mutex_lock(&ring->m)) != 0) { - errno = err; - fatal("Failed to lock mutex"); - } - while ((RING_FREE_REQUESTS(ring) < n) && (ring->last == -1)) { - if ((err = pthread_cond_wait(&ring->c, &ring->m)) != 0) { - errno = err; - fatal("Failed to wait on condition variable"); - } - } - if (ring->last != -1) { - goto out; - } - char *producer = RING_GET(ring, ring->producer); - char *consumer = RING_GET(ring, ring->consumer); - assert (producer >= RING_GET(ring, 0)); - assert (producer <= RING_GET(ring, ring->size-1)); - assert (consumer >= RING_GET(ring, 0)); - assert (consumer <= RING_GET(ring, ring->size-1)); - if (*iovec_len <= 0) { - ret = 0; - fprintf(stderr, "no iovecs\n"); - goto out; - } - if (consumer > producer) { - /* producer has not wrapped around the buffer yet */ - iovec[0].iov_base = producer; - iovec[0].iov_len = consumer - producer; - assert(iovec[0].iov_len > 0); - *iovec_len = 1; - ret = 0; - goto out; - } - /* consumer has wrapped around, so the first chunk is from the producer to - the end of the buffer */ - iovec[0].iov_base = producer; - iovec[0].iov_len = ring->size - (int) (producer - RING_GET(ring, 0)); - assert(iovec[0].iov_len > 0); - if (*iovec_len == 1) { - ret = 0; - goto out; - } - *iovec_len = 1; - /* also include the chunk from the beginning of the buffer to the consumer */ - iovec[1].iov_base = RING_GET(ring, 0); - iovec[1].iov_len = consumer - RING_GET(ring, 0); - if (iovec[1].iov_len > 0) { - /* ... but don't bother if it's zero */ - *iovec_len = 2; - } - ret = 0; -out: - if ((err = pthread_mutex_unlock(&ring->m)) != 0) { - errno = err; - fatal("Failed to unlock mutex"); - } - if (ret == 0) { - for (int i = 0; i < *iovec_len; i++) { - assert(iovec[i].iov_base >= (void*)RING_GET(ring, 0)); - assert(iovec[i].iov_base + iovec[i].iov_len - 1 <= (void*)RING_GET(ring, ring->size - 1)); - } - } - return ret; -} - -/* Wait for n bytes to become available. If the ring has shutdown, return - non-zero. If data is available then return zero and fill in the first - iovec_len entries of the iovec. */ -int ring_consumer_wait_available( - struct ring *ring, size_t n, struct iovec *iovec, int *iovec_len -) { - - int ret = 1; - int err = 0; - if ((err = pthread_mutex_lock(&ring->m)) != 0) { - errno = err; - fatal("Failed to lock mutex"); - } - while ((RING_DATA_AVAILABLE(ring) < n) && (ring->last == -1)) { - if ((err = pthread_cond_wait(&ring->c, &ring->m)) != 0) { - errno = err; - fatal("Failed to wait on condition variable"); - } - } - if (ring->last != -1) { - goto out; - } - char *producer = RING_GET(ring, ring->producer); - char *consumer = RING_GET(ring, ring->consumer); - assert (producer >= RING_GET(ring, 0)); - assert (producer <= RING_GET(ring, ring->size-1)); - assert (consumer >= RING_GET(ring, 0)); - assert (consumer <= RING_GET(ring, ring->size-1)); - if (*iovec_len <= 0) { - ret = 0; - goto out; - } - if (producer > consumer) { - /* producer has not wrapped around the buffer yet */ - iovec[0].iov_base = consumer; - iovec[0].iov_len = producer - consumer; - assert(iovec[0].iov_len > 0); - *iovec_len = 1; - ret = 0; - goto out; - } - /* producer has wrapped around, so the first chunk is from the consumer to - the end of the buffer */ - iovec[0].iov_base = consumer; - iovec[0].iov_len = ring->size - (int) (consumer - RING_GET(ring, 0)); - assert(iovec[0].iov_len > 0); - if (*iovec_len == 1) { - ret = 0; - goto out; - } - *iovec_len = 1; - /* also include the chunk from the beginning of the buffer to the producer */ - iovec[1].iov_base = RING_GET(ring, 0); - iovec[1].iov_len = producer - RING_GET(ring, 0); - if (iovec[1].iov_len > 0) { - /* ... but don't bother if its zero */ - *iovec_len = 2; - } - ret = 0; -out: - if ((err = pthread_mutex_unlock(&ring->m)) != 0) { - errno = err; - fatal("Failed to unlock mutex"); - } - if (ret == 0) { - for (int i = 0; i < *iovec_len; i++) { - assert(iovec[i].iov_base >= (void*)RING_GET(ring, 0)); - assert(iovec[i].iov_base + iovec[i].iov_len - 1 <= (void*)RING_GET(ring, ring->size - 1)); - } - } - return ret; -} diff --git a/alpine/packages/tap-vsockd/ring.h b/alpine/packages/tap-vsockd/ring.h deleted file mode 100644 index 9d126793b..000000000 --- a/alpine/packages/tap-vsockd/ring.h +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -/* A fixed-size circular buffer */ -struct ring; - -/* Allocate a circular buffer with the given payload size. - Size must be < INT_MAX / 2. */ -extern struct ring *ring_allocate(int size); - -/* Signal that new data is been produced */ -extern void ring_producer_advance(struct ring *ring, int n); - -/* Signal that data has been consumed */ -extern void ring_consumer_advance(struct ring *ring, int n); - -/* The producer sends Eof. This will cause ring_consumer_wait_available - and ring_producer_wait_available to return an error. */ -extern void ring_producer_eof(struct ring *ring); - -/* Wait for n bytes of space for new data to become available. If - ring_producer_eof has been called, return non-zero. If space is available - then fill the first *iovec_len entries of the iovec and set *iovec_len to - the number of iovecs used. */ -extern int ring_producer_wait_available( - struct ring *ring, size_t n, struct iovec *iovec, int *iovec_len -); - -/* Wait for n bytes to become available for reading. If ring_producer_eof has - been called, return non-zero. If data is available then fill the first - *iovec_len entries of the iovec and set *iovec_len to the number of iovecs - used. */ -extern int ring_consumer_wait_available( - struct ring *ring, size_t n, struct iovec *iovec, int *iovec_len -); diff --git a/alpine/packages/tap-vsockd/tap-vsockd.c b/alpine/packages/tap-vsockd/tap-vsockd.c deleted file mode 100644 index 7f566f642..000000000 --- a/alpine/packages/tap-vsockd/tap-vsockd.c +++ /dev/null @@ -1,727 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "hvsock.h" -#include "protocol.h" -#include "ring.h" - -int daemon_flag; -int nofork_flag; -int listen_flag; -int connect_flag; - -char *default_sid = "30D48B34-7D27-4B0B-AAAF-BBBED334DD59"; - -/* Support big frames if the server requests it */ -const int max_packet_size = 16384; - -static int verbose; -#define INFO(...) \ - do { \ - if (verbose) { \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } \ - } while (0) -#define DBG(...) \ - do { \ - if (verbose > 1) { \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } \ - } while (0) -#define TRC(...) \ - do { \ - if (verbose > 2) { \ - printf(__VA_ARGS__); \ - fflush(stdout); \ - } \ - } while (0) - -void fatal(const char *msg) -{ - syslog(LOG_CRIT, "%s Error: %d. %s", msg, errno, strerror(errno)); - exit(1); -} - -int alloc_tap(const char *dev) -{ - const char *clonedev = "/dev/net/tun"; - struct ifreq ifr; - int persist = 1; - int fd; - - fd = open(clonedev, O_RDWR); - if (fd == -1) - fatal("Failed to open /dev/net/tun"); - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) - fatal("TUNSETIFF failed"); - - if (ioctl(fd, TUNSETPERSIST, persist) < 0) - fatal("TUNSETPERSIST failed"); - - syslog(LOG_INFO, "successfully created TAP device %s", dev); - return fd; -} - -void set_macaddr(const char *dev, uint8_t *mac) -{ - struct ifreq ifq; - int fd; - - fd = socket(PF_INET, SOCK_DGRAM, 0); - if (fd == -1) - fatal("Could not get socket to set MAC address"); - strcpy(ifq.ifr_name, dev); - memcpy(&ifq.ifr_hwaddr.sa_data[0], mac, 6); - ifq.ifr_hwaddr.sa_family = ARPHRD_ETHER; - - if (ioctl(fd, SIOCSIFHWADDR, &ifq) == -1) - fatal("SIOCSIFHWADDR failed"); - - close(fd); -} - -void set_mtu(const char *dev, int mtu) -{ - struct ifreq ifq; - int fd; - - fd = socket(PF_INET, SOCK_DGRAM, 0); - if (fd == -1) - fatal("Could not get socket to set MTU"); - strcpy(ifq.ifr_name, dev); - ifq.ifr_mtu = mtu; - - if (ioctl(fd, SIOCSIFMTU, &ifq) == -1) - fatal("SIOCSIFMTU failed"); - - close(fd); -} - -/* Negotiate a vmnet connection, returns 0 on success and 1 on error. */ -int negotiate(int fd, struct vif_info *vif) -{ - enum command command = ethernet; - struct init_message *me; - struct ethernet_args args; - struct init_message you; - char *txt; - - me = create_init_message(); - if (!me) - goto err; - - if (write_init_message(fd, me) == -1) - goto err; - - if (read_init_message(fd, &you) == -1) - goto err; - - txt = print_init_message(&you); - if (!txt) - goto err; - - syslog(LOG_INFO, "Server reports %s", txt); - free(txt); - - if (write_command(fd, &command) == -1) - goto err; - - /* We don't need a uuid */ - memset(&args.uuid_string[0], 0, sizeof(args.uuid_string)); - if (write_ethernet_args(fd, &args) == -1) - goto err; - - if (read_vif_info(fd, vif) == -1) - goto err; - - return 0; -err: - syslog(LOG_CRIT, "Failed to negotiate vmnet connection"); - return 1; -} - -/* Argument passed to proxy threads */ -struct connection { - int fd; /* Hyper-V socket with vmnet protocol */ - int tapfd; /* TAP device with ethernet frames */ - struct vif_info vif; /* Contains MAC, MTU etc, received from server */ - struct ring* from_vmnet_ring; - struct ring* to_vmnet_ring; - int message_size; /* Maximum size of a Hyper-V read or write */ -}; - -/* Trim the iovec so that it contains at most len bytes. */ -void trim_iovec(struct iovec *iovec, int *iovec_len, size_t len) -{ - for (int i = 0; i < *iovec_len; i++) { - if (iovec[i].iov_len > len) { - iovec[i].iov_len = len; - *iovec_len = i + 1; - return; - } - len -= iovec[i].iov_len; - } -} - -size_t len_iovec(struct iovec *iovec, int iovec_len) -{ - size_t len = 0; - for (int i = 0; i < iovec_len; i++) { - len += iovec[i].iov_len; - } - return len; -} - -/* Read bytes from vmnet into the from_vmnet_ring */ -static void* vmnet_to_ring(void *arg) -{ - struct connection *c = (struct connection *)arg; - struct ring *ring = c->from_vmnet_ring; - struct iovec iovec[2]; /* We won't need more than 2 for the ring */ - int iovec_len; - while (1) { - iovec_len = sizeof(iovec) / sizeof(struct iovec); - TRC("vmnet_to_ring: ring_producer_wait_available n=%d iovec_len=%d\n", 1, iovec_len); - if (ring_producer_wait_available(ring, 1, &iovec[0], &iovec_len) != 0) { - fatal("Failed to read a data from vmnet"); - } - trim_iovec(iovec, &iovec_len, c->message_size); - { - int length = 0; - for (int i = 0; i < iovec_len; i ++) { - length += iovec[i].iov_len; - } - TRC("vmnet_to_ring readv len %d\n", length); - } - ssize_t n = readv(c->fd, &iovec[0], iovec_len); - TRC("vmnet_to_ring: read %zd\n", n); - if (n == 0) { - syslog(LOG_CRIT, "EOF reading from socket: closing\n"); - ring_producer_eof(ring); - goto err; - } - if (n < 0) { - syslog(LOG_CRIT, - "Failure reading from socket: closing: %s (%d)", - strerror(errno), errno); - ring_producer_eof(ring); - goto err; - } - TRC("vmnet_to_ring: advance producer %zd\n", n); - ring_producer_advance(ring, (size_t) n); - } -err: - /* - * On error: stop reading from the socket and trigger a clean - * shutdown - */ - TRC("vmnet_to_ring: shutdown\n"); - shutdown(c->fd, SHUT_RD); - return NULL; -} - -/* Decode packets on the from_vmnet_ring and write to the tap device */ -static void* ring_to_tap(void *arg) -{ - struct connection *c = (struct connection *)arg; - struct iovec iovec[2]; /* We won't need more than 2 for the ring */ - int iovec_len; - int length; - struct ring *ring = c->from_vmnet_ring; - while (1) { - /* Read the packet length: this requires 2 bytes */ - iovec_len = sizeof(iovec) / sizeof(struct iovec); - TRC("ring_to_tap: ring_consumer_wait_available n=%d iovec_len=%d\n", 2, iovec_len); - if (ring_consumer_wait_available(ring, 2, &iovec[0], &iovec_len) != 0) { - fatal("Failed to read a packet header from host"); - } - length = *((uint8_t*)iovec[0].iov_base) & 0xff; - /* The second byte might be in the second iovec array */ - if (iovec[0].iov_len >= 2) { - length |= (*((uint8_t*)iovec[0].iov_base + 1) & 0xff) << 8; - } else { - length |= (*((uint8_t*)iovec[1].iov_base) & 0xff) << 8; - } - assert(length > 0); - TRC("ring_to_tap: packet of length %d\n", length); - if (length > max_packet_size) { - syslog(LOG_CRIT, - "Received an over-large packet: %d > %ld", - length, max_packet_size); - exit(1); - } - ring_consumer_advance(ring, 2); - - /* Read the variable length packet */ - iovec_len = sizeof(iovec) / sizeof(struct iovec); - TRC("ring_to_tap: ring_consumer_wait_available n=%d iovec_len=%d\n", length, iovec_len); - if (ring_consumer_wait_available(ring, length, &iovec[0], &iovec_len) != 0) { - fatal("Failed to read a packet body from host"); - } - assert(len_iovec(&iovec[0], iovec_len) >= length); - trim_iovec(iovec, &iovec_len, length); - ssize_t n = writev(c->tapfd, &iovec[0], iovec_len); - if (n != length) { - syslog(LOG_CRIT, - "Failed to write %d bytes to tap device (wrote %d)", length, n); - //exit(1); - } - TRC("ring_to_tap: ring_consumer_advance n=%zd\n", n); - ring_consumer_advance(ring, (size_t) length); - } - return NULL; -} - -/* Write packets with header from the tap device onto the to_vmnet_ring */ -static void *tap_to_ring(void *arg) -{ - struct connection *connection = (struct connection *)arg; - struct ring *ring = connection->to_vmnet_ring; - struct iovec iovec[2]; /* We won't need more than 2 for the ring */ - int iovec_len; - struct iovec payload[2]; /* The packet body after the 2 byte header */ - int payload_len; - size_t length; - while (1) { - /* Wait for space for a 2 byte header + max_packet_size */ - length = 2 + connection->vif.max_packet_size; - iovec_len = sizeof(iovec) / sizeof(struct iovec); - TRC("tap_to_ring: ring_producer_wait_available n=%zd iovec_len=%d\n", length, iovec_len); - if (ring_producer_wait_available(ring, length, &iovec[0], &iovec_len) != 0) { - fatal("Failed to find enough free space for a packet"); - } - assert(iovec_len > 0); - assert(iovec[0].iov_len > 0); - memcpy(&payload[0], &iovec[0], sizeof(struct iovec) * iovec_len); - payload_len = iovec_len; - - /* take the first 2 bytes of the free space which will contain the header */ - char *header1 = payload[0].iov_base; - payload[0].iov_base++; - payload[0].iov_len--; - if (payload[0].iov_len == 0) { - assert(payload_len == 2); /* because `length` > 1 */ - payload[0].iov_base = payload[1].iov_base; - payload[0].iov_len = payload[1].iov_len; - payload_len --; - } - char *header2 = payload[0].iov_base; - payload[0].iov_base++; - payload[0].iov_len--; - /* payload is now where the packet should go */ - - /* limit the message size */ - trim_iovec(payload, &payload_len, connection->message_size); - - length = readv(connection->tapfd, payload, payload_len); - - if (length == -1) { - if (errno == ENXIO) - fatal("tap device has gone down"); - - syslog(LOG_WARNING, "ignoring error %d", errno); - /* - * This is what mirage-net-unix does. Is it a good - * idea really? - */ - exit(1); - } - *header1 = (length >> 0) & 0xff; - *header2 = (length >> 8) & 0xff; - TRC("tap_to_ring: ring_producer_advance n=%zd\n", length + 2); - - ring_producer_advance(ring, (size_t) (length + 2)); - } - return NULL; -} - -/* Write bytes from the to_vmnet_ring to the vmnet fd */ -static void *ring_to_vmnet(void *arg) -{ - struct connection *c = (struct connection *)arg; - struct iovec iovec[2]; /* We won't need more than 2 for the ring */ - int iovec_len; - int length; - struct ring *ring = c->to_vmnet_ring; - while (1) { - /* Read the packet length: this requires 2 bytes */ - iovec_len = sizeof(iovec) / sizeof(struct iovec); - TRC("ring_to_vmnet: ring_producer_wait_available n=%d iovec_len=%d\n", 1, iovec_len); - if (ring_consumer_wait_available(ring, 1, &iovec[0], &iovec_len) != 0) { - fatal("Failed to read data from ring"); - } - trim_iovec(iovec, &iovec_len, c->message_size); - length = 0; - for (int i = 0; i < iovec_len; i++ ) { - length += iovec[i].iov_len; - } - TRC("ring_to_vmnet: read %d bytes\n", length); - ssize_t n = writev(c->fd, &iovec[0], iovec_len); - - TRC("ring_to_vmnet: advance consumer %zd\n", n); - ring_consumer_advance(ring, (size_t) n); - } - return NULL; -} - -/* - * Handle a connection by exchanging ethernet frames forever. - */ -static void handle(struct connection *connection) -{ - pthread_t v2r, r2t, t2r, r2v; - - if (pthread_create(&t2r, NULL, tap_to_ring, connection) != 0) - fatal("Failed to create the tap_to_ring thread"); - - if (pthread_create(&v2r, NULL, vmnet_to_ring, connection) != 0) - fatal("Failed to create the vmnet_to_tap thread"); - - if (pthread_create(&r2t, NULL, ring_to_tap, connection) != 0) - fatal("Failed to create the ring_to_tap thread"); - - if (pthread_create(&r2v, NULL, ring_to_vmnet, connection) != 0) - fatal("Failed to create the ring_to_vmnet thread"); - - if (pthread_join(t2r, NULL) != 0) - fatal("Failed to join the tap_to_ring thread"); - - if (pthread_join(v2r, NULL) != 0) - fatal("Failed to join the vmnet_to_ring thread"); - - if (pthread_join(t2r, NULL) != 0) - fatal("Failed to join the tap_to_ring thread"); - - if (pthread_join(r2v, NULL) != 0) - fatal("Failed to join the ring_to_vmnet thread"); -} - -static int create_listening_socket(GUID serviceid) -{ - SOCKADDR_HV sa; - int lsock; - int res; - - lsock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW); - if (lsock == -1) - fatal("socket()"); - - sa.Family = AF_HYPERV; - sa.Reserved = 0; - sa.VmId = HV_GUID_WILDCARD; - sa.ServiceId = serviceid; - - res = bind(lsock, (const struct sockaddr *)&sa, sizeof(sa)); - if (res == -1) - fatal("bind()"); - - res = listen(lsock, SOMAXCONN); - if (res == -1) - fatal("listen()"); - - return lsock; -} - -static int connect_socket(GUID serviceid) -{ - SOCKADDR_HV sa; - int sock; - int res; - - sock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW); - if (sock == -1) - fatal("socket()"); - - sa.Family = AF_HYPERV; - sa.Reserved = 0; - sa.VmId = HV_GUID_PARENT; - sa.ServiceId = serviceid; - - res = connect(sock, (const struct sockaddr *)&sa, sizeof(sa)); - if (res == -1) - fatal("connect()"); - - return sock; -} - -static int accept_socket(int lsock) -{ - SOCKADDR_HV sac; - socklen_t socklen = sizeof(sac); - int csock; - - csock = accept(lsock, (struct sockaddr *)&sac, &socklen); - if (csock == -1) - fatal("accept()"); - - syslog(LOG_INFO, "Connect from: " GUID_FMT ":" GUID_FMT "\n", - GUID_ARGS(sac.VmId), GUID_ARGS(sac.ServiceId)); - - return csock; -} - -void write_pidfile(const char *pidfile) -{ - pid_t pid = getpid(); - char *pid_s; - FILE *file; - int len; - - if (asprintf(&pid_s, "%lld", (long long)pid) == -1) - fatal("Failed to allocate pidfile string"); - - len = strlen(pid_s); - file = fopen(pidfile, "w"); - if (file == NULL) { - syslog(LOG_CRIT, "Failed to open pidfile %s", pidfile); - exit(1); - } - - if (fwrite(pid_s, 1, len, file) != len) - fatal("Failed to write pid to pidfile"); - - fclose(file); - free(pid_s); -} - -void daemonize(const char *pidfile) -{ - pid_t pid; - int null; - - pid = fork(); - if (pid == -1) - fatal("Failed to fork()"); - else if (pid != 0) - exit(0); - - if (setsid() == -1) - fatal("Failed to setsid()"); - - if (chdir("/") == -1) - fatal("Failed to chdir()"); - - null = open("/dev/null", O_RDWR); - if (null == -1) - fatal("Failed to open /dev/null"); - dup2(null, STDIN_FILENO); - dup2(null, STDOUT_FILENO); - dup2(null, STDERR_FILENO); - close(null); - - if (pidfile) - write_pidfile(pidfile); -} - -void usage(char *name) -{ - printf("%s usage:\n", name); - printf("\t[--daemon] [--tap ] [--serviceid ] [--pid ]\n"); - printf("\t[--message-size ] [--buffer-size ]\n"); - printf("\t[--listen | --connect]\n\n"); - printf("where\n"); - printf("\t--daemonize: run as a background daemon\n"); - printf("\t--nofork: don't run handlers in subprocesses\n"); - printf("\t--tap : create a tap device with the given name\n"); - printf("\t (defaults to eth1)\n"); - printf("\t--serviceid : use as the well-known service GUID\n"); - printf("\t (defaults to %s)\n", default_sid); - printf("\t--pid : write a pid to the given file\n"); - printf("\t--message-size : dictates the maximum transfer size for AF_HVSOCK\n"); - printf("\t--buffer-size : dictates the buffer size for AF_HVSOCK\n"); - printf("\t--listen: listen forever for incoming AF_HVSOCK connections\n"); - printf("\t--connect: connect to the parent partition\n"); -} - -int main(int argc, char **argv) -{ - char *serviceid = default_sid; - struct connection connection; - char *tap = "eth1"; - char *pidfile = NULL; - int lsocket = -1; - int sock = -1; - int res = 0; - int status; - pid_t child; - int tapfd; - int ring_size = 1048576; - int message_size = 8192; /* Well known to work across Hyper-V versions */ - GUID sid; - int c; - - int option_index; - int log_flags = LOG_CONS | LOG_NDELAY; - static struct option long_options[] = { - /* These options set a flag. */ - {"daemon", no_argument, &daemon_flag, 1}, - {"nofork", no_argument, &nofork_flag, 1}, - {"serviceid", required_argument, NULL, 's'}, - {"tap", required_argument, NULL, 't'}, - {"pidfile", required_argument, NULL, 'p'}, - {"listen", no_argument, &listen_flag, 1}, - {"connect", no_argument, &connect_flag, 1}, - {"buffer-size", required_argument, NULL, 'b'}, - {"message-size", required_argument, NULL, 'm'}, - {0, 0, 0, 0} - }; - - opterr = 0; - while (1) { - option_index = 0; - - c = getopt_long(argc, argv, "ds:t:p:r:m:v", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'd': - daemon_flag = 1; - break; - case 'n': - nofork_flag = 1; - break; - case 's': - serviceid = optarg; - break; - case 't': - tap = optarg; - break; - case 'p': - pidfile = optarg; - break; - case 'b': - ring_size = atoi(optarg); - break; - case 'm': - message_size = atoi(optarg); - break; - case 'v': - verbose ++; - break; - case 0: - break; - default: - usage(argv[0]); - exit(1); - } - } - - if ((listen_flag && connect_flag) || !(listen_flag || connect_flag)) { - fprintf(stderr, "Please supply either the --listen or --connect flag, but not both.\n"); - exit(1); - } - - if (daemon_flag && !pidfile) { - fprintf(stderr, "For daemon mode, please supply a --pidfile argument.\n"); - exit(1); - } - - res = parseguid(serviceid, &sid); - if (res) { - fprintf(stderr, "Failed to parse serviceid as GUID: %s\n", serviceid); - usage(argv[0]); - exit(1); - } - - if (!daemon_flag) - log_flags |= LOG_PERROR; - - openlog(argv[0], log_flags, LOG_DAEMON); - - tapfd = alloc_tap(tap); - connection.tapfd = tapfd; - connection.to_vmnet_ring = ring_allocate(ring_size); - connection.from_vmnet_ring = ring_allocate(ring_size); - connection.message_size = message_size; - if (listen_flag) { - syslog(LOG_INFO, "starting in listening mode with serviceid=%s and tap=%s", serviceid, tap); - lsocket = create_listening_socket(sid); - } else { - syslog(LOG_INFO, "starting in connect mode with serviceid=%s and tap=%s", serviceid, tap); - } - - for (;;) { - if (sock != -1) { - close(sock); - sock = -1; - } - - if (listen_flag) - sock = accept_socket(lsocket); - else - sock = connect_socket(sid); - - connection.fd = sock; - if (negotiate(sock, &connection.vif) != 0) { - sleep(1); - continue; - } - - syslog(LOG_INFO, "VMNET VIF has MAC %02x:%02x:%02x:%02x:%02x:%02x", - connection.vif.mac[0], connection.vif.mac[1], connection.vif.mac[2], - connection.vif.mac[3], connection.vif.mac[4], connection.vif.mac[5] - ); - set_macaddr(tap, &connection.vif.mac[0]); - set_mtu(tap, connection.vif.mtu); - - /* Daemonize after we've made our first reliable connection */ - if (daemon_flag) { - daemon_flag = 0; - daemonize(pidfile); - } - if (nofork_flag) { - handle(&connection); - exit(1); - } - /* - * Run the multithreaded part in a subprocess. On error the - * process will exit() which tears down all the threads - */ - child = fork(); - if (child == 0) { - handle(&connection); - /* - * should never happen but just in case of a logic - * bug in handle - */ - exit(1); - } - - for (;;) { - if (waitpid(child, &status, 0) != -1) - break; - } - } -} diff --git a/alpine/packages/test/etc/init.d/test b/alpine/packages/test/etc/init.d/test deleted file mode 100755 index f0f5e4747..000000000 --- a/alpine/packages/test/etc/init.d/test +++ /dev/null @@ -1,25 +0,0 @@ -#!/sbin/openrc-run - -depend() -{ - need docker containerd -} - -start() -{ - [ -d /test ] || exit 0 - - ebegin "Running tests" - - if containerd-ctr containers start --no-pivot --attach test /test - then - printf "Moby test suite PASSED\n" - else - printf "Moby test suite FAILED\n" - fi - - eend "Tests completed" - - # now terminate with extreme prejudice - poweroff -f -} diff --git a/alpine/packages/transfused/.gitignore b/alpine/packages/transfused/.gitignore deleted file mode 100644 index e1ae85e07..000000000 --- a/alpine/packages/transfused/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sbin diff --git a/alpine/packages/transfused/Makefile b/alpine/packages/transfused/Makefile deleted file mode 100644 index ec87bea95..000000000 --- a/alpine/packages/transfused/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -C_COMPILE=mobylinux/c-compile:ac075fed7c87e4af30d8490ae0504166cceb0df3@sha256:0e82d441ce112d638f904a08199c76b022c065a2dbf8908bb366755267d4417f - -default: sbin/transfused - -DEPS=$(wildcard *.c *.h) - -sbin/transfused: $(DEPS) - mkdir -p $(dir $@) - tar cf - $(DEPS) | docker run --rm --net=none --log-driver=none -i $(C_COMPILE) -o $@ | tar xf - - -clean: - rm -rf sbin diff --git a/alpine/packages/transfused/etc/init.d/transfused b/alpine/packages/transfused/etc/init.d/transfused deleted file mode 100755 index accee759f..000000000 --- a/alpine/packages/transfused/etc/init.d/transfused +++ /dev/null @@ -1,40 +0,0 @@ -#!/sbin/openrc-run - -description="fuse proxy server" - -start() -{ - [ "$(mobyplatform)" != "mac" ] && exit 0 - ebegin "Starting FUSE socket passthrough" - - mkdir -p /host_docker_app - find /tmp -mindepth 1 -delete - - PIDFILE=/var/run/transfused.pid - STARTUP_LOGFILE=/var/transfused_start.log - - start-stop-daemon --start --quiet \ - --background \ - --exec /sbin/transfused \ - --pidfile ${PIDFILE} \ - -- \ - -p "${PIDFILE}" \ - -l "${STARTUP_LOGFILE}" - - ewaitfile 2 ${PIDFILE} - - eend $? "Failed to start transfused" -} - -stop() -{ - [ "$(mobyplatform)" != "mac" ] && exit 0 - ebegin "Stopping FUSE socket passthrough" - - PIDFILE=/var/run/transfused.pid - - start-stop-daemon --stop --quiet \ - --pidfile "${PIDFILE}" - - eend $? "Failed to stop transfused" -} diff --git a/alpine/packages/transfused/transfused.c b/alpine/packages/transfused/transfused.c deleted file mode 100644 index bf2e947ac..000000000 --- a/alpine/packages/transfused/transfused.c +++ /dev/null @@ -1,1246 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "transfused_log.h" -#include "transfused_vsock.h" -#include "transfused_perfstat.h" - -char *default_fusermount = DEFAULT_FUSERMOUNT; -char *default_socket = DEFAULT_SOCKET; -char *default_server = DEFAULT_SERVER; -char *usage = -"usage: transfused [-p pidfile] [-d server] [-s socket] [-f fusermount]\n" -" [-l logfile]\n" -" -p pidfile\tthe path at which to write the pid of the process\n" -" -d " DEFAULT_SERVER "\tthe server address to use ('v:addr:port')\n" -" -s " DEFAULT_SOCKET "\tthe socket address to use ('v:addr:port')\n" -" -f " DEFAULT_FUSERMOUNT "\tthe fusermount executable to use\n" -" -l logfile\tthe log file to use before uplink\n"; - -int debug; - -pthread_attr_t detached; - -typedef struct { - connection_t *connection; - int from; - int to; -} copy_thread_state; - -#include - -pid_t gettid(void) -{ - return syscall(SYS_gettid); -} - -void *must_malloc(char *const descr, size_t size) -{ - void *ptr; - - ptr = malloc(size); - if (size != 0 && ptr == NULL) - die(1, NULL, descr, ""); - - return ptr; -} - -void cond_init(char *const descr, pthread_cond_t *cond, - const pthread_condattr_t *restrict attr) -{ - errno = pthread_cond_init(cond, attr); - if (errno) - die(1, NULL, "", "cond init %s: ", descr); -} - -void lock_init(char *const descr, pthread_mutex_t *mutex, - const pthread_mutexattr_t *restrict attr) -{ - errno = pthread_mutex_init(mutex, attr); - if (errno) - die(1, NULL, "", "lock init %s: ", descr); -} - -void lock(char *const descr, pthread_mutex_t *mutex) -{ - errno = pthread_mutex_lock(mutex); - if (errno) - die(1, NULL, "", "lock %s: ", descr); -} - -void unlock(char *const descr, pthread_mutex_t *mutex) -{ - errno = pthread_mutex_unlock(mutex); - if (errno) - die(1, NULL, "", "unlock %s: ", descr); -} - -int bind_socket(const char *socket) -{ - int sock = -1; - - if (socket[0] == 0) - die(2, NULL, NULL, "Socket family required"); - - if (socket[1] != ':') - die(2, NULL, NULL, "Socket address required"); - - switch (socket[0]) { - case 'v': - sock = bind_vsock(socket + 2); - break; - default: - die(2, NULL, NULL, "Unknown socket family '%c'", socket[0]); - } - - return sock; -} - -int connect_socket(const char *socket) -{ - int sock = -1; - - if (socket[0] == 0) - die(2, NULL, NULL, "Socket family required"); - if (socket[1] != ':') - die(2, NULL, NULL, "Scoket address required"); - - switch (socket[0]) { - case 'v': - sock = connect_vsock(socket + 2); - break; - default: - die(2, NULL, NULL, "Unknown socket family '%c'", socket[0]); - } - - return sock; -} - -char **read_opts(connection_t *conn, char *buf) -{ - int read_count; - int optc = 1; - char **optv; - size_t mount_len; - int j; - - /* TODO: deal with socket read conditions e.g.EAGAIN */ - read_count = read(conn->sock, buf, EVENT_BUFSZ - 1); - if (read_count < 0) - die(1, conn->params, "read_opts error reading", ""); - - /* TODO: protocol should deal with short read */ - buf[read_count] = 0x0; - - for (int i = 0; i < read_count; i++) { - if (buf[i] == 0x0) - optc++; - } - - optv = (char **)must_malloc("read_opts optv", (optc + 1) * sizeof(void *)); - optv[0] = buf; - optv[optc] = 0x0; - - j = 1; - for (int i = 0; i < read_count && j < optc; i++) { - if (buf[i] == 0x0) { - optv[j] = buf + i + 1; - j++; - } - } - - mount_len = strnlen(optv[optc - 1], 4096) + 1; - conn->mount_point = must_malloc("mount point string", mount_len); - strncpy(conn->mount_point, optv[optc - 1], mount_len - 1); - conn->mount_point[mount_len - 1] = '\0'; - - return optv; -} - -uint64_t message_id(uint64_t *message) -{ - return message[1]; -} - -void read_exactly(char *descr, int fd, void *p, size_t nbyte) -{ - ssize_t read_count; - char *buf = p; - - while (nbyte > 0) { - read_count = read(fd, buf, nbyte); - if (read_count < 0) { - if (errno == EAGAIN || errno == EINTR) - continue; - die(1, NULL, "", "read %s: error reading: ", descr); - } - if (read_count == 0) - die(1, NULL, NULL, "read %s: EOF reading", descr); - nbyte -= read_count; - buf += read_count; - } -} - -int read_message(char *descr, parameters_t *params, int fd, - char *buf, size_t max_read) -{ - size_t nbyte = sizeof(uint32_t); - uint32_t len; - - read_exactly(descr, fd, buf, nbyte); - len = *((uint32_t *) buf); - if (len > max_read) - die(1, params, NULL, - "read %s: message size %d exceeds buffer capacity %d", - len, max_read); - if (len < nbyte) - die(1, params, NULL, - "read %s: message size is %d but must be at least %d", - len, nbyte); - - buf += nbyte; - nbyte = (size_t)(len - nbyte); - - read_exactly(descr, fd, buf, nbyte); - - return (int)len; -} - -void copy_into_fuse(copy_thread_state *copy_state) -{ - int from = copy_state->from; - int to = copy_state->to; - char *descr = copy_state->connection->mount_point; - int read_count, write_count; - void *buf; - connection_t *conn = copy_state->connection; - parameters_t *params = conn->params; - uint64_t unique; - - buf = must_malloc(descr, IN_BUFSZ); - - while (1) { - read_count = read_message(descr, params, - from, (char *)buf, IN_BUFSZ); - - write_count = write(to, buf, read_count); - if (write_count < 0) - die(1, params, "", "copy %s: error writing: ", descr); - - /* /dev/fuse accepts only complete writes */ - if (write_count != read_count) - die(1, params, NULL, - "copy %s: read %d but only wrote %d", - descr, read_count, write_count); - - unique = *((uint64_t *)buf + 1); - if (perfstat_close(unique, conn)) - log_time(params, - "dropping perfstat for edge message %lld", - unique); - } - - free(buf); -} - -void copy_notify_fuse(copy_thread_state *copy_state) -{ - int from = copy_state->from; - int to = copy_state->to; - char *descr = copy_state->connection->mount_point; - int read_count, write_count; - uint32_t zero = 0, err; - void *buf; - parameters_t *params = copy_state->connection->params; - - buf = must_malloc(descr, IN_BUFSZ); - - while (1) { - read_count = read_message(descr, params, - from, (char *)buf, IN_BUFSZ); - write_count = write(to, buf, read_count); - if (write_count < 0) { - err = errno; - write_count = write(from, &err, 4); - if (write_count < 0) { - log_time(params, - "copy notify %s write error: %s", strerror(err)); - die(1, params, "", - "copy notify %s reply write error: ", descr); - } - continue; - } else { - if (write(from, &zero, 4) < 0) - die(1, params, "", - "copy notify %s reply write error: ", descr); - } - - if (write_count != read_count) - die(1, params, NULL, - "copy notify %s: read %d but only wrote %d", - descr, read_count, write_count); - } - - free(buf); -} - -void write_exactly(char *descr, int fd, void *p, size_t nbyte) -{ - int write_count; - char *buf = p; - - while (nbyte > 0) { - write_count = write(fd, buf, nbyte); - if (write_count < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - die(1, NULL, "", "%s: error writing: ", descr); - } - if (write_count == 0) - die(1, NULL, "", "%s: 0 write: ", descr); - - nbyte -= write_count; - buf += write_count; - } -} - -void copy_outof_fuse(copy_thread_state *copy_state) -{ - int from = copy_state->from; - int to = copy_state->to; - char *descr = copy_state->connection->mount_point; - int read_count; - void *buf; - connection_t *conn = copy_state->connection; - parameters_t *params = conn->params; - uint64_t unique; - - buf = must_malloc(descr, OUT_BUFSZ); - - while (1) { - /* /dev/fuse only returns complete reads */ - read_count = read(from, buf, OUT_BUFSZ); - if (read_count < 0) - die(1, params, "", "copy %s: error reading: ", descr); - - write_exactly(descr, to, (char *)buf, read_count); - - unique = *((uint64_t *)buf + 1); - if (perfstat_open(unique, conn)) - die(1, params, NULL, - "copy %s: could not open perfstat for %d", - descr, unique); - } - - free(buf); -} - -void *copy_clean_into_fuse(copy_thread_state *copy_state) -{ - copy_into_fuse(copy_state); - - close(copy_state->from); - - free(copy_state); - - return NULL; -} - -void *copy_clean_into_fuse_thread(void *copy_state) -{ - return copy_clean_into_fuse((copy_thread_state *)copy_state); -} - -void *copy_clean_notify_fuse(copy_thread_state *copy_state) -{ - copy_notify_fuse(copy_state); - - close(copy_state->from); - - free(copy_state); - - return NULL; -} - -void *copy_clean_notify_fuse_thread(void *copy_state) -{ - return copy_clean_notify_fuse((copy_thread_state *) copy_state); -} - -void *copy_clean_outof_fuse(copy_thread_state *copy_state) -{ - copy_outof_fuse(copy_state); - - close(copy_state->to); - - free(copy_state); - - return NULL; -} - -void *copy_clean_outof_fuse_thread(void *copy_state) -{ - return copy_clean_outof_fuse((copy_thread_state *) copy_state); -} - -int recv_fd(parameters_t *params, int sock) -{ - int ret; - int fd = -1; - char iochar; - char buf[CMSG_SPACE(sizeof(fd))]; - - struct msghdr msg; - struct iovec vec; - struct cmsghdr *cmsg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - vec.iov_base = &iochar; - vec.iov_len = 1; - msg.msg_iov = &vec; - - msg.msg_iovlen = 1; - - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - - ret = recvmsg(sock, &msg, 0); - - if (ret == -1) - die(1, params, "recvmsg", ""); - - if (ret > 0 && msg.msg_controllen > 0) { - cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg->cmsg_level == SOL_SOCKET && (cmsg->cmsg_type == SCM_RIGHTS)) - fd = *(int *)CMSG_DATA(cmsg); - } - return fd; -} - -/* optv must be null-terminated */ -int get_fuse_sock(connection_t *conn, int optc, char *const optv[]) -{ - char **argv; - char *envp[2]; - char *mount_notice, *arg_acc; - pid_t fusermount_pid; - int fuse_socks[2]; - int status; - int fd; - - /* prepare argv from optv */ - argv = (char **)must_malloc("fusermount argv", - (optc + 2) * sizeof(char *)); - - argv[0] = conn->params->fusermount; - memcpy(&argv[1], optv, (optc + 1) * sizeof(char *)); - - /* report the mount command issued */ - if (asprintf(&arg_acc, "mount") == -1) - die(1, conn->params, - "Couldn't allocate mount notice base string", ""); - - for (int i = 0; argv[i]; i++) { - if (asprintf(&mount_notice, "%s %s", arg_acc, argv[i]) == -1) - die(1, conn->params, "", - "Couldn't allocate mount notice arg %d: ", i); - free(arg_acc); - arg_acc = mount_notice; - } - - if (asprintf(&mount_notice, "%s\n", arg_acc) == -1) - die(1, conn->params, "Couldn't allocate mount notice", ""); - - log_notice_time(conn->params, mount_notice); - - free(mount_notice); - free(arg_acc); - - /* make the socket over which we'll be sent the FUSE socket fd */ - if (socketpair(PF_UNIX, SOCK_STREAM, 0, fuse_socks)) - die(1, conn->params, "Couldn't create FUSE socketpair", ""); - - /* prepare to exec the suid binary fusermount */ - if (asprintf(&envp[0], "_FUSE_COMMFD=%d", fuse_socks[0]) == -1) - die(1, conn->params, "Couldn't allocate fusermount envp", ""); - - envp[1] = 0x0; - - /* fork and exec fusermount */ - fusermount_pid = fork(); - if (!fusermount_pid) - /* child */ - if (execve(argv[0], argv, envp)) - die(1, conn->params, - "Failed to execute fusermount", ""); - - /* parent */ - free(argv); - free(envp[0]); - - /* close the end of the socket that we gave away */ - close(fuse_socks[0]); - - /* wait for fusermount to return */ - waitpid(fusermount_pid, &status, 0); - if (!WIFEXITED(status)) - die(1, conn->params, NULL, "fusermount terminated abnormally"); - - if (WEXITSTATUS(status)) - die(1, conn->params, NULL, - "fusermount exited with code %d", WEXITSTATUS(status)); - - if (debug) - log_time(conn->params, "about to recv_fd from fusermount\n"); - - fd = recv_fd(conn->params, fuse_socks[1]); - if (fd == -1) - die(1, conn->params, NULL, "Couldn't receive fd over FUSE socket"); - - /* close the read end of the socket */ - close(fuse_socks[1]); - - return fd; -} - -void start_reader(connection_t *connection, int fuse) -{ - pthread_t child; - copy_thread_state *copy_state; - - copy_state = (copy_thread_state *) - must_malloc("start_reader copy_state", - sizeof(copy_thread_state)); - copy_state->connection = connection; - copy_state->from = connection->sock; - copy_state->to = fuse; - errno = pthread_create(&child, &detached, - copy_clean_into_fuse_thread, copy_state); - if (errno) - die(1, connection->params, "", - "Couldn't create read copy thread for mount %s: ", - connection->mount_point); -} - -void start_writer(connection_t *connection, int fuse) -{ - pthread_t child; - copy_thread_state *copy_state; - - copy_state = (copy_thread_state *) - must_malloc("start_writer copy_state", - sizeof(copy_thread_state)); - copy_state->connection = connection; - copy_state->from = fuse; - copy_state->to = connection->sock; - errno = pthread_create(&child, &detached, - copy_clean_outof_fuse_thread, copy_state); - if (errno) - die(1, connection->params, "", - "Couldn't create write copy thread for mount %s: ", - connection->mount_point); -} - -void negotiate_notify_channel(char *mount_point, int notify_sock) -{ - int len = strlen(mount_point); - struct { - uint32_t len; - uint16_t channel; - } __attribute__((packed)) hdr; - - hdr.len = 6 + len; - hdr.channel = TRANSFUSE_NOTIFY_CHANNEL; - - write_exactly("negotiate_notify_channel hdr", notify_sock, &hdr, 6); - write_exactly("negotiate_notify_channel mnt", - notify_sock, mount_point, len); -} - -void start_notify(connection_t *connection, int fuse) -{ - pthread_t child; - copy_thread_state *copy_state; - - copy_state = (copy_thread_state *) - must_malloc("start_notify copy_state", - sizeof(copy_thread_state)); - copy_state->connection = connection; - copy_state->from = connect_socket(connection->params->server); - copy_state->to = fuse; - - negotiate_notify_channel(connection->mount_point, copy_state->from); - - errno = pthread_create(&child, &detached, - copy_clean_notify_fuse_thread, copy_state); - if (errno) - die(1, connection->params, "", - "Couldn't create notify copy thread for mount %s: ", - connection->mount_point); -} - - -char *alloc_dirname(connection_t *conn, char *path) -{ - size_t len = strlen(path) + 1; - char *input = must_malloc("alloc_dirname input", len); - char *output = must_malloc("alloc_dirname output", len); - char *dir; - - strlcpy(input, path, len); - - dir = dirname(input); - if (dir == NULL) - die(1, conn->params, "", "Couldn't get dirname of %s: ", path); - strcpy(output, dir); - - free(input); - return output; -} - -void mkdir_p(connection_t *conn, char *path) -{ - char *parent; - - if (mkdir(path, 0700)) - switch (errno) { - case EEXIST: - return; - case ENOENT: - parent = alloc_dirname(conn, path); - mkdir_p(conn, parent); - free(parent); - if (mkdir(path, 0700)) - die(1, conn->params, "", - "Couldn't create directory %s: ", path); - break; - default: - die(1, conn->params, "", - "Couldn't create directory %s: ", path); - } -} - -int is_next_child_ok(parameters_t *params, char *path, DIR *dir) -{ - struct dirent *child; - - errno = 0; - child = readdir(dir); - if (child == NULL) { - if (errno != 0) - die(1, params, "", - "Couldn't read directory %s: ", path); - else - return 0; - } - return 1; -} - -int is_path_mountable(parameters_t *params, int allow_empty, char *path) -{ - DIR *dir; - - dir = opendir(path); - if (dir != NULL) { - /* allow for . and .. */ - if (is_next_child_ok(params, path, dir)) - if (is_next_child_ok(params, path, dir)) { - if (is_next_child_ok(params, path, dir)) - goto no; - else if (allow_empty) - goto yes; - else - goto no; - } - goto yes; - } else { - switch (errno) { - case ENOENT: - goto yes; - case ENOTDIR: - goto no; - default: - goto no; - } - } - goto no; - -no: - if (dir) - closedir(dir); - return 0; - -yes: - if (dir) - closedir(dir); - return 1; -} - -/* The leaf may exist but must be empty. Any proper path prefix may exist. */ -void prepare_mount_point(connection_t *conn) -{ - char *mount_point = conn->mount_point; - - if (is_path_mountable(conn->params, 1, mount_point)) - mkdir_p(conn, mount_point); - else - die(1, conn->params, NULL, - "Couldn't mount on %s: not missing or empty", mount_point); -} - -void *mount_connection(connection_t *conn) -{ - int optc; - char **optv; - int fuse; - char *buf; - pthread_mutex_t copy_lock; - pthread_cond_t copy_halt; - int should_halt = 0; - - buf = (char *)must_malloc("read_opts packet malloc", EVENT_BUFSZ); - - optv = read_opts(conn, buf); - - prepare_mount_point(conn); - - for (optc = 0; optv[optc] != NULL; optc++) { - } - - fuse = get_fuse_sock(conn, optc, optv); - free(buf); - free(optv); - - lock_init("copy_lock", ©_lock, NULL); - cond_init("copy_halt", ©_halt, NULL); - - start_reader(conn, fuse); - start_writer(conn, fuse); - start_notify(conn, fuse); - - lock("copy lock", ©_lock); - while (!should_halt) - errno = pthread_cond_wait(©_halt, ©_lock); - if (errno) - die(1, conn->params, "", - "Couldn't wait for copy halt for mount %s: ", - conn->mount_point); - unlock("copy lock", ©_lock); - - free(conn); - - return NULL; -} - -void *mount_thread(void *conn) -{ - return mount_connection((connection_t *) conn); -} - -void write_pid(connection_t *connection) -{ - pid_t pid = gettid(); - char *pid_s; - int pid_s_len; - - if (asprintf(&pid_s, "%lld", (long long)pid) == -1) - die(1, connection->params, "Couldn't allocate pid string", ""); - - pid_s_len = strlen(pid_s); - - write_exactly("pid", connection->sock, pid_s, pid_s_len); - - free(pid_s); -} - -void pong(parameters_t *params) -{ - char pong_msg[6] = {'\6', '\0', '\0', '\0', PONG_REPLY, '\0'}; - - write_exactly("pong reply", params->ctl_sock, pong_msg, 6); -} - -void perform_syscall(connection_t *conn, uint8_t syscall, char path[]) -{ - char *name; - int r = 0; - - switch (syscall) { - - case PING: - pong(conn->params); - r = 0; - break; - - case RMDIR_SYSCALL: - name = "rmdir"; - r = rmdir(path); - break; - - case UNLINK_SYSCALL: - name = "unlink"; - r = unlink(path); - break; - - case MKDIR_SYSCALL: - name = "mkdir"; - r = mkdir(path, 00000); - break; - - case SYMLINK_SYSCALL: - name = "symlink"; - r = symlink(".", path); - break; - - case MKNOD_REG_SYSCALL: - name = "mknod"; - r = mknod(path, 0600, 0); - break; - - case TRUNCATE_SYSCALL: - name = "truncate"; - r = truncate(path, 0); - break; - - case CHMOD_SYSCALL: - name = "chmod"; - r = chmod(path, 0700); - break; - - default: - die(1, conn->params, NULL, - "Unknown event syscall %" PRIu8, syscall); - } - - if (r != 0) - thread_log_time(conn, "Event %s %s error: %s\n", - name, path, strerror(errno)); -} - -void *event_thread(void *connection_ptr) -{ - int read_count, path_len; - void *buf; - connection_t *connection = connection_ptr; - - char *path; - uint8_t syscall; - - /* This thread registers with the file system server as being an - * fsnotify event actuator. Other mounted file system interactions - * (such as self-logging) SHOULD NOT occur on this thread. */ - write_pid(connection); - - buf = must_malloc("incoming event buffer", EVENT_BUFSZ); - - while (1) { - read_count = read_message("events", connection->params, - connection->sock, buf, EVENT_BUFSZ); - - if (debug) - thread_log_time(connection, - "read %d bytes from event connection\n", - read_count); - - path_len = (int)ntohs(*(((uint32_t *) buf) + 1)); - /* TODO: could check the path length isn't a lie here */ - path = (char *)(((uint8_t *)buf) + 6); - /* TODO: could check the path is NULL terminated here */ - syscall = *(((uint8_t *)buf) + 6 + path_len); - - /* TODO: should this be in another thread ? */ - perform_syscall(connection, syscall, path); - } - - free(buf); - /* TODO: close connection */ - return NULL; -} - -void write_pidfile(parameters_t *params) -{ - int fd; - pid_t pid = getpid(); - char *pid_s; - int pid_s_len, write_count; - - if (asprintf(&pid_s, "%lld", (long long)pid) == -1) - die(1, params, "Couldn't allocate pidfile string", ""); - - pid_s_len = strlen(pid_s); - - fd = open(params->pidfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd == -1) - die(1, params, "", - "Couldn't open pidfile path %s: ", params->pidfile); - - write_count = write(fd, pid_s, pid_s_len); - if (write_count == -1) - die(1, params, "", - "Error writing pidfile %s: ", params->pidfile); - - if (write_count != pid_s_len) - die(1, params, NULL, - "Error writing %s to pidfile %s: only wrote %d bytes", - pid_s, params->pidfile, write_count); - - close(fd); - free(pid_s); -} - -/* TODO: the message parsing here is rickety, do it properly */ -void *determine_mount_suitability(parameters_t *params, int allow_empty, - char *req, int len) -{ - void *buf = (void *)req; - uint16_t id = *((uint16_t *) buf); - uint16_t slen; - char *reply; - int roff; - - reply = (char *)must_malloc("determine_mount_suitability", len + 6); - *((uint16_t *) (reply + 4)) = MOUNT_SUITABILITY_REPLY; - *((uint16_t *) (reply + 6)) = id; - roff = 8; - - buf = (void *)((char *)buf + 2); - len -= 2; - while (len) { - slen = *((uint16_t *) buf) + 1; - if (is_path_mountable(params, allow_empty, ((char *)buf) + 2)) { - slen = strlcpy(reply + roff + 2, - ((char *)buf) + 2, slen) + 1; - *((uint16_t *)((void *)(reply + roff))) = slen - 1; - roff += 2 + slen; - } - buf = (void *)((char *)buf + 2 + slen); - len -= 2 + slen; - } - - *((uint32_t *) ((void *)reply)) = roff; - return (void *)reply; -} - -void *error_reply(uint16_t id, const char *fmt, ...) -{ - char *reply; - char *message; - size_t mlen; - va_list args; - - va_start(args, fmt); - vasprintf(&message, fmt, args); - va_end(args); - - mlen = strlen(message); - reply = (char *)must_malloc("error_reply", 8 + mlen); - *((uint32_t *)reply) = 8 + mlen; - *((uint16_t *) (reply + 4)) = ERROR_REPLY; - *((uint16_t *) (reply + 6)) = id; - memcpy(reply + 8, message, mlen); - free(message); - - return (void *)reply; -} - -connection_t *find_connection(connection_t *conn, char *name, size_t len) -{ - while (conn) { - if (strncmp(name, conn->mount_point, len) == 0) - return conn; - conn = conn->next; - } - return NULL; -} - -void *init_thread(void *params_ptr) -{ - parameters_t *params = params_ptr; - int read_count, len; - char init_msg[6] = {'\6', '\0', '\0', '\0', '\0', '\0'}; - void *buf, *response; - uint16_t msg_type; - - params->ctl_sock = connect_socket(params->server); - - write_exactly("init", params->ctl_sock, init_msg, sizeof(init_msg)); - - buf = must_malloc("incoming control message buffer", CTL_BUFSZ); - - /* TODO: handle other messages */ - read_exactly("init thread", params->ctl_sock, buf, sizeof(init_msg)); - if (memcmp(buf, init_msg, sizeof(init_msg))) - die(1, params, NULL, "init thread: unexpected message"); - - /* we've gotten Continue so write the pidfile */ - if (params->pidfile != NULL) - write_pidfile(params); - - while (1) { - read_count = read_message("control", params, params->ctl_sock, - buf, CTL_BUFSZ - 1); - msg_type = *((uint16_t *)buf + 2); - switch (msg_type) { - case MOUNT_SUITABILITY_REQUEST: - response = determine_mount_suitability(params, 0, - (char *)buf + 6, - read_count - 6); - len = *((size_t *) response); - write_exactly("init thread: mount suitability response", - params->ctl_sock, response, len); - free(response); - break; - - case EXPORT_SUITABILITY_REQUEST: - response = determine_mount_suitability(params, 1, - (char *)buf + 6, - read_count - 6); - len = *((size_t *) response); - write_exactly("init thread: export suitability response", - params->ctl_sock, response, len); - free(response); - break; - - case START_PERFSTAT_REQUEST: - ((char *)buf)[read_count] = '\0'; - response = start_perfstat(params, (char *)buf + 6, - read_count - 6); - len = *((size_t *) response); - write_exactly("init thread: start perfstat response", - params->ctl_sock, response, len); - free(response); - break; - - case STOP_PERFSTAT_REQUEST: - ((char *)buf)[read_count] = '\0'; - response = stop_perfstat(params, (char *)buf + 6, - read_count - 6); - len = *((size_t *) response); - write_exactly("init thread: stop perfstat response", - params->ctl_sock, response, len); - free(response); - break; - - default: - die(1, params, NULL, - "init thread: unknown message %d", msg_type); - } - } - - free(buf); - return NULL; -} - -void toggle_debug(int sig) -{ - debug = !debug; -} - -void setup_debug(void) -{ - if (signal(SIGHUP, toggle_debug) == SIG_ERR) - die(1, NULL, "Couldn't set SIGHUP behavior", ""); - - if (siginterrupt(SIGHUP, 1)) - die(1, NULL, "Couldn't set siginterrupt for SIGHUP", ""); -} - -void parse_parameters(int argc, char *argv[], parameters_t *params) -{ - int c; - int errflg = 0; - - params->pidfile = NULL; - params->socket = NULL; - params->fusermount = NULL; - params->logfile = NULL; - params->logfile_fd = 0; - params->data_sock = 0; - params->ctl_sock = 0; - lock_init("ctl_lock", ¶ms->ctl_lock, NULL); - params->connections = NULL; - - while ((c = getopt(argc, argv, ":p:d:s:f:l:")) != -1) { - switch (c) { - - case 'p': - params->pidfile = optarg; - break; - - case 'd': - params->server = optarg; - break; - - case 's': - params->socket = optarg; - break; - - case 'f': - params->fusermount = optarg; - break; - - case 'l': - params->logfile = optarg; - break; - - case ':': - fprintf(stderr, "Option -%c requires a path argument\n", optopt); - errflg++; - break; - - case '?': - fprintf(stderr, "Unrecognized option: '-%c'\n", optopt); - errflg++; - break; - - default: - fprintf(stderr, "Internal error parsing -%c\n", c); - errflg++; - } - } - - if (errflg) { - fprintf(stderr, "%s", usage); - exit(2); - } - if (params->pidfile != NULL && access(params->pidfile, W_OK)) - if (errno != ENOENT) { - fprintf(stderr, "-p %s path to pidfile must be writable: ", - params->pidfile); - perror(""); - exit(2); - } - if (params->fusermount == NULL) - params->fusermount = default_fusermount; - if (access(params->fusermount, X_OK)) { - fprintf(stderr, "-f %s path to fusermount must be executable: ", - params->fusermount); - perror(""); - exit(2); - } - if (params->socket == NULL) - params->socket = default_socket; - - if (params->server == NULL) - params->server = default_server; - - if (params->logfile != NULL && access(params->logfile, W_OK)) - if (errno != ENOENT) { - fprintf(stderr, "-l %s path to logfile must be writable: ", - params->logfile); - perror(""); - exit(2); - } -} - -void serve(parameters_t *params) -{ - char subproto_selector; - pthread_t child; - connection_t *conn; - void *(*connection_handler_thread)(void *) = NULL; - - if (listen(params->data_sock, 16)) - die(1, NULL, "listen", ""); - - errno = pthread_create(&child, &detached, init_thread, params); - if (errno) - die(1, NULL, "", "Couldn't create initialization thread: "); - - while (1) { - conn = (connection_t *)must_malloc("connection state", - sizeof(connection_t)); - conn->params = params; - conn->next = params->connections; - params->connections = conn; - conn->mount_point = ""; - conn->perfstat = 0; - conn->perfstats = NULL; - lock_init("perfstat lock",&conn->perfstat_lock,NULL); - - conn->sock = accept(params->data_sock, - &conn->sa_client, &conn->socklen_client); - if (conn->sock < 0) - die(1, params, "accept", ""); - - read_exactly("subproto", conn->sock, &subproto_selector, 1); - - switch (subproto_selector) { - case 'm': - conn->type_descr = "mount"; - connection_handler_thread = mount_thread; - break; - case 'e': - conn->type_descr = "event"; - connection_handler_thread = event_thread; - break; - default: - die(1, params, NULL, - "Unknown subprotocol type '%c'", subproto_selector); - } - - errno = pthread_create(&child, &detached, - connection_handler_thread, conn); - if (errno) - die(1, params, "", - "Couldn't create thread for %s connection: ", - conn->type_descr); - - if (debug) - log_time(conn->params, "thread spawned\n"); - } -} - -int main(int argc, char *argv[]) -{ - parameters_t params; - struct rlimit core_limit; - - core_limit.rlim_cur = RLIM_INFINITY; - core_limit.rlim_max = RLIM_INFINITY; - if (setrlimit(RLIMIT_CORE, &core_limit)) - die(1, NULL, "", "Couldn't set RLIMIT_CORE to RLIM_INFINITY"); - - openlog(argv[0], LOG_CONS | LOG_PERROR | LOG_NDELAY, LOG_DAEMON); - - parse_parameters(argc, argv, ¶ms); - setup_debug(); - - errno = pthread_attr_setdetachstate(&detached, PTHREAD_CREATE_DETACHED); - if (errno) - die(1, NULL, "Couldn't set pthread detach state", ""); - - if (params.logfile != NULL) { - params.logfile_fd = open(params.logfile, - O_WRONLY | O_APPEND | O_CREAT); - if (params.logfile_fd == -1) - die(1, NULL, "", - "Couldn't open log file %s: ", params.logfile); - } - params.data_sock = bind_socket(params.socket); - serve(¶ms); - - return 0; -} diff --git a/alpine/packages/transfused/transfused.h b/alpine/packages/transfused/transfused.h deleted file mode 100644 index b1e66f96e..000000000 --- a/alpine/packages/transfused/transfused.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef _TRANSFUSED_H_ -#define _TRANSFUSED_H_ - -#include -#include -#include "transfused_perfstat.h" - -#define IN_BUFSZ ((1 << 20) + 16) -#define OUT_BUFSZ ((1 << 20) + 64) -#define EVENT_BUFSZ 4096 -#define CTL_BUFSZ 65536 -#define PERFSTATS_PER_SEGMENT 2730 /* (64k - 16) / 24 */ -#define MAX_PERFSTAT_CHECK 64 - -#define DEFAULT_FUSERMOUNT "/bin/fusermount" -#define DEFAULT_SOCKET "v:_:1525" -#define DEFAULT_SERVER "v:2:1524" - -#define PING 128 -#define RMDIR_SYSCALL 0 -#define UNLINK_SYSCALL 1 -#define MKDIR_SYSCALL 2 -#define SYMLINK_SYSCALL 3 -#define TRUNCATE_SYSCALL 4 -#define CHMOD_SYSCALL 5 -#define MKNOD_REG_SYSCALL 6 -/* these could be turned into an enum probably but...C standard nausea */ - -#define MOUNT_SUITABILITY_REQUEST 1 -#define EXPORT_SUITABILITY_REQUEST 2 -#define START_PERFSTAT_REQUEST 3 -#define STOP_PERFSTAT_REQUEST 4 - -#define TRANSFUSE_LOG_ERROR 1 -#define TRANSFUSE_LOG_NOTICE 2 -#define PONG_REPLY 3 -#define MOUNT_SUITABILITY_REPLY 4 -#define TRANSFUSE_NOTIFY_CHANNEL 5 -#define PERFSTAT_REPLY 6 -#define ERROR_REPLY 7 - -struct parameters; -struct connection; - -struct parameters { - char *server; - char *socket; - char *fusermount; - char *pidfile; - char *logfile; - int logfile_fd; - int ctl_sock; - int data_sock; - pthread_mutex_t ctl_lock; - struct connection *connections; -}; - -typedef struct parameters parameters_t; - -struct connection { - struct connection *next; - parameters_t *params; - char *type_descr; - char *mount_point; - struct sockaddr sa_client; - socklen_t socklen_client; - int sock; - int perfstat; - perfstats_t *perfstats; - pthread_mutex_t perfstat_lock; -}; - -typedef struct connection connection_t; - -pthread_attr_t detached; - -void *must_malloc(char *const descr, size_t size); -void lock(char *const descr, pthread_mutex_t *mutex); -void unlock(char *const descr, pthread_mutex_t *mutex); -void write_exactly(char *descr, int fd, void *buf, size_t nbyte); - -void *error_reply(uint16_t id, const char *fmt, ...); - -connection_t *find_connection(connection_t *conn, char *name, size_t len); - -#endif /* _TRANSFUSED_H_ */ diff --git a/alpine/packages/transfused/transfused_log.c b/alpine/packages/transfused/transfused_log.c deleted file mode 100644 index 3c464ae06..000000000 --- a/alpine/packages/transfused/transfused_log.c +++ /dev/null @@ -1,257 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "transfused.h" -#include "transfused_log.h" - -void log_timestamp(int fd) -{ - char timestamp[26]; - int msec; - struct tm *tm_info; - struct timeval tv; - - gettimeofday(&tv, NULL); - - msec = lrint(tv.tv_usec / 1000.0); - if (msec >= 1000) { - msec -= 1000; - tv.tv_sec++; - } - tm_info = localtime(&tv.tv_sec); - - strftime(timestamp, 26, "%Y-%m-%d %H:%M:%S", tm_info); - dprintf(fd, "%s.%03d ", timestamp, msec); -} - -void vlog_sock_locked(int fd, uint16_t msg_type, const char *fmt, va_list args) -{ - int rc, len; - va_list targs; - char *fill; - - va_copy(targs, args); - len = vsnprintf(NULL, 0, fmt, targs); - if (len < 0) - die(1, NULL, NULL, "Couldn't log due to vsnprintf failure"); - va_end(targs); - - /* 4 for length itself and 2 for message type */ - rc = len + 4 + 2; - write_exactly("vlog_sock_locked", fd, - (uint32_t *)&rc, sizeof(uint32_t)); - write_exactly("vlog_sock_locked", fd, &msg_type, sizeof(uint16_t)); - - va_copy(targs, args); - rc = vdprintf(fd, fmt, targs); - if (rc < 0) - die(1, NULL, "Couldn't send log message with vdprintf", ""); - va_end(targs); - - if (rc < len) { - /* we didn't write the whole message :-( */ - rc = len - rc; - fill = (char *)calloc(rc, 1); - if (fill == NULL) - die(1, NULL, "vlog_sock_locked fill", ""); - write_exactly("vlog_sock_locked fill", fd, fill, rc); - } -} - -void log_sock_locked(int fd, uint16_t msg_type, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vlog_sock_locked(fd, msg_type, fmt, args); - va_end(args); -} - -void die(int exit_code, parameters_t *params, const char *parg, - const char *fmt, ...) -{ - va_list argp, targs; - int in_errno = errno; - int fd = 0; - - if (params != NULL) { - fd = params->ctl_sock; - lock("die ctl_lock", ¶ms->ctl_lock); - } - - va_start(argp, fmt); - va_copy(targs, argp); - vsyslog(LOG_CRIT, fmt, targs); - va_end(targs); - - if (fd != 0) - vlog_sock_locked(fd, TRANSFUSE_LOG_ERROR, fmt, argp); - va_end(argp); - - if (parg != NULL) { - if (*parg != 0) { - syslog(LOG_CRIT, "%s: %s", parg, strerror(in_errno)); - if (fd != 0) - log_sock_locked(fd, TRANSFUSE_LOG_ERROR, - "%s: %s", parg, strerror(in_errno)); - } else { - syslog(LOG_CRIT, "%s", strerror(in_errno)); - if (fd != 0) - log_sock_locked(fd, TRANSFUSE_LOG_ERROR, - "%s", strerror(in_errno)); - } - } - if (fd != 0) - close(fd); /* flush */ - exit(exit_code); - /* Nobody else should die before we terminate everything */ - unlock("die ctl_lock", ¶ms->ctl_lock); -} - -void vlog_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, va_list args) -{ - int rc; - int fd = params->ctl_sock; - va_list targs; - - if (fd != 0) { - vlog_sock_locked(fd, msg_type, fmt, args); - } else { - va_copy(targs, args); - /* TODO: translate msg_type to syslog message type */ - vsyslog(LOG_INFO, fmt, targs); - va_end(targs); - - fd = params->logfile_fd; - if (fd != 0) { - va_copy(targs, args); - /* TODO: include message type? */ - rc = vdprintf(fd, fmt, targs); - if (rc < 0) - die(1, NULL, - "Couldn't write log message with vdprintf", ""); - va_end(targs); - } - } -} - -void vlog_time_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, va_list args) -{ - int fd = params->logfile_fd; - - if (fd != 0 && params->ctl_sock == 0) - log_timestamp(fd); - vlog_locked(params, msg_type, fmt, args); -} - -void log_time_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vlog_time_locked(params, msg_type, fmt, args); - va_end(args); -} - -void log_time(parameters_t *params, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - lock("log_time ctl_lock", ¶ms->ctl_lock); - vlog_time_locked(params, TRANSFUSE_LOG_ERROR, fmt, args); - unlock("log_time ctl_lock", ¶ms->ctl_lock); - va_end(args); -} - -void log_notice_time(parameters_t *params, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - lock("log_time ctl_lock", ¶ms->ctl_lock); - vlog_time_locked(params, TRANSFUSE_LOG_NOTICE, fmt, args); - unlock("log_time ctl_lock", ¶ms->ctl_lock); - - va_end(args); -} - -typedef struct { - parameters_t *params; - char *msg; -} log_thread_state; - -void *log_time_thread(void *log_state_ptr) -{ - log_thread_state *log_state = log_state_ptr; - - log_time(log_state->params, log_state->msg); - - free(log_state->msg); - free(log_state); - return NULL; -} - -void thread_log_time(connection_t *conn, const char *fmt, ...) -{ - log_thread_state *log_state; - pthread_t logger; - va_list args; - - log_state = must_malloc("thread_log_time log_state", - sizeof(log_thread_state)); - log_state->params = conn->params; - - va_start(args, fmt); - if (vasprintf(&log_state->msg, fmt, args) == -1) - die(1, conn->params, - "Couldn't allocate thread_log_time message", ""); - va_end(args); - - /* TODO: We currently spawn a new thread for every - * message. This is far from ideal but fine for now as we - * anticipate thread-sensitive log demand to be low. */ - errno = pthread_create(&logger, &detached, log_time_thread, log_state); - if (errno) - die(1, conn->params, "", - "Couldn't create log thread for %s connection %s: ", - conn->type_descr, conn->mount_point); -} - -void log_continue_locked(parameters_t *params, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vlog_locked(params, TRANSFUSE_LOG_ERROR, fmt, args); - va_end(args); -} - -void log_continue(parameters_t *params, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - - lock("log_continue ctl_lock", ¶ms->ctl_lock); - vlog_locked(params, TRANSFUSE_LOG_ERROR, fmt, args); - unlock("log_continue ctl_lock", ¶ms->ctl_lock); - - va_end(args); -} diff --git a/alpine/packages/transfused/transfused_log.h b/alpine/packages/transfused/transfused_log.h deleted file mode 100644 index f500d2434..000000000 --- a/alpine/packages/transfused/transfused_log.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _TRANSFUSED_LOG_H_ -#define _TRANSFUSED_LOG_H_ - -#include -#include - -#include "transfused.h" - -void die(int exit_code, parameters_t *params, const char *perror_arg, - const char *fmt, ...); - -void vlog_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, va_list args); -void vlog_time_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, va_list args); - -void log_time_locked(parameters_t *params, uint16_t msg_type, - const char *fmt, ...); - -void log_time(parameters_t *params, const char *fmt, ...); -void log_notice_time(parameters_t *params, const char *fmt, ...); -void thread_log_time(connection_t *conn, const char *fmt, ...); -void log_continue_locked(parameters_t *params, const char *fmt, ...); -void log_continue(parameters_t *params, const char *fmt, ...); - -#endif /* _TRANSFUSED_LOG_H_ */ diff --git a/alpine/packages/transfused/transfused_perfstat.c b/alpine/packages/transfused/transfused_perfstat.c deleted file mode 100644 index ff505445e..000000000 --- a/alpine/packages/transfused/transfused_perfstat.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include "transfused.h" -#include "transfused_log.h" - -uint64_t now(parameters_t *params) -{ - uint64_t ns_in_s = 1000000000; - struct timespec now; - if (clock_gettime(CLOCK_MONOTONIC, &now)) - die(1, params, "now", ""); - return (uint64_t)now.tv_sec * ns_in_s + (uint64_t)now.tv_nsec; -} - -size_t size_of_perfstats(perfstats_t *p) -{ - size_t len = 0; - - while (p) { - len += sizeof(perfstat_t) * p->len + sizeof(perfstats_t); - p = p->next; - } - - return len; -} - -int perfstat_open(uint64_t unique, connection_t *conn) -{ - size_t sz; - perfstats_t *old_perfstats = conn->perfstats; - perfstats_t *stats = conn->perfstats; - perfstat_t stat; - - if (!conn->perfstat) - return 0; - - lock("perfstat lock: perfstat_open", &conn->perfstat_lock); - if (conn->perfstat) { - if (!stats || stats->len >= PERFSTATS_PER_SEGMENT) { - sz = sizeof(perfstats_t); - sz += PERFSTATS_PER_SEGMENT * sizeof(perfstat_t); - stats = must_malloc("perfstats",sz); - stats->next = old_perfstats; - stats->len = 0; - conn->perfstats = stats; - } - - stat = (perfstat_t) { - .id = unique, - .start = now(conn->params), - .stop = 0 - }; - stats->perfstat[stats->len] = stat; - stats->len++; - } - unlock("perfstat unlock: perfstat_close", &conn->perfstat_lock); - - return 0; -} - -int perfstat_close_locked(uint64_t unique, parameters_t *params, - perfstats_t *perfstats, int to_check) -{ - int i; - perfstat_t *stat; - - if (!perfstats) - return 1; - - i = perfstats->len - 1; - while (i >= 0 && to_check > 0) { - stat = &perfstats->perfstat[i]; - if (stat->id == unique) { - stat->stop = now(params); - return 0; - } else { - i--; - to_check--; - } - } - - if (to_check && !perfstat_close_locked(unique, params, perfstats->next, - to_check)) - return 0; - return 1; -} - -int perfstat_close(uint64_t unique, connection_t *conn) -{ - int rc = 0; - pthread_mutex_t *perfstat_lock = &conn->perfstat_lock; - - if (!conn->perfstat) - return 0; - - lock("perfstat lock: perfstat_close", perfstat_lock); - if (conn->perfstat) - rc = perfstat_close_locked(unique, conn->params, - conn->perfstats, - MAX_PERFSTAT_CHECK); - unlock("perfstat unlock: perfstat_close", perfstat_lock); - - return rc; -} - -void *start_perfstat(parameters_t *params, char *req, size_t len) -{ - char *reply; - uint16_t id = *((uint16_t *) req); - char *mount = (char *) req + 2; - connection_t *conn = find_connection(params->connections, mount, - len - 2); - if (conn == NULL) - return (void *)error_reply(id, "Mount %s unknown", mount); - - lock("perfstat lock: start_perfstat", &conn->perfstat_lock); - conn->perfstat = 1; - unlock("perfstat lock: start_perfstat", &conn->perfstat_lock); - - reply = (char *)must_malloc("start_perfstat", 8); - *((uint32_t *)reply) = 16; - *((uint16_t *) (reply + 4)) = PERFSTAT_REPLY; - *((uint16_t *) (reply + 6)) = id; - *((uint64_t *) (reply + 8)) = now(params); - - return (void *)reply; -} - -void copy_and_free_perfstats(perfstats_t *p, char *buf) -{ - size_t len; - perfstats_t *p_next; - - while (p) { - p_next = p->next; - len = p->len * sizeof(perfstat_t); - memcpy(buf, p->perfstat, len); - buf += len; - free(p); - p = p_next; - } -} - -void *stop_perfstat(parameters_t *params, char *req, size_t len) -{ - char *reply; - uint16_t id = *((uint16_t *) req); - char *mount = (char *) req + 2; - connection_t *conn = find_connection(params->connections, mount, - len - 2); - if (conn == NULL) - return (void *)error_reply(id, "Mount %s unknown", mount); - - size_t out_len = 16; - - lock("perfstat lock: stop_perfstat", &conn->perfstat_lock); - conn->perfstat = 0; - - out_len += size_of_perfstats(conn->perfstats); - - reply = (char *)must_malloc("stop_perfstat", out_len); - *((uint32_t *)reply) = out_len; - *((uint16_t *) (reply + 4)) = PERFSTAT_REPLY; - *((uint16_t *) (reply + 6)) = id; - *((uint64_t *) (reply + 8)) = now(params); - - copy_and_free_perfstats(conn->perfstats, reply + 16); - conn->perfstats = NULL; - - unlock("perfstat lock: stop_perfstat", &conn->perfstat_lock); - - return (void *)reply; -} diff --git a/alpine/packages/transfused/transfused_perfstat.h b/alpine/packages/transfused/transfused_perfstat.h deleted file mode 100644 index 33bb9047f..000000000 --- a/alpine/packages/transfused/transfused_perfstat.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _TRANSFUSED_PERFSTAT_H_ -#define _TRANSFUSED_PERFSTAT_H_ - -#include - -struct connection; -struct parameters; - -typedef struct { - uint64_t id; - uint64_t start; - uint64_t stop; -} perfstat_t; - -struct perfstats { - uint32_t len; - uint32_t nothing; - struct perfstats *next; - perfstat_t perfstat[0]; -}; - -typedef struct perfstats perfstats_t; - -int perfstat_open(uint64_t unique, struct connection *conn); -int perfstat_close(uint64_t unique, struct connection *conn); -void *start_perfstat(struct parameters *params, char *req, size_t len); -void *stop_perfstat(struct parameters *params, char *req, size_t len); - -#endif /* _TRANSFUSED_PERFSTAT_H_ */ diff --git a/alpine/packages/transfused/transfused_vsock.c b/alpine/packages/transfused/transfused_vsock.c deleted file mode 100644 index 04cdce6da..000000000 --- a/alpine/packages/transfused/transfused_vsock.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include - -#include "vm_sockets.h" - -#include "transfused_log.h" - -long parse_cid(const char *address) -{ - char *end = NULL; - long cid = strtol(address, &end, 10); - - if (address == end || *end != ':') { - *end = 0; - die(2, NULL, NULL, "Invalid vsock cid: %s", address); - } - return cid; -} - -long parse_port(const char *port_str) -{ - char *end = NULL; - long port = strtol(port_str, &end, 10); - - if (port_str == end || *end != '\0') { - *end = 0; - die(2, NULL, NULL, "Invalid vsock port: %s", port_str); - } - return port; -} - -int find_colon(const char *address) -{ - int colon = 0; - - while (address[colon] != '\0') - if (address[colon] == ':') - break; - else - colon++; - - if (address[colon] == '\0') - die(2, NULL, NULL, "Missing port in vsock address %s", address); - - return colon; -} - -int bind_vsock(const char *address) -{ - long cid, port; - int colon; - struct sockaddr_vm sa_listen = { - .svm_family = AF_VSOCK, - }; - int sock_fd; - - colon = find_colon(address); - - if (address[0] == '_' && colon == 1) - cid = VMADDR_CID_ANY; - else - cid = parse_cid(address); - - port = parse_port(address + colon + 1); - - sa_listen.svm_cid = cid; - sa_listen.svm_port = port; - - sock_fd = socket(AF_VSOCK, SOCK_STREAM, 0); - if (sock_fd < 0) - die(1, NULL, "socket(AF_VSOCK)", ""); - - if (bind(sock_fd, (struct sockaddr *)&sa_listen, sizeof(sa_listen))) - die(1, NULL, "bind(AF_VSOCK)", ""); - - return sock_fd; -} - -int connect_vsock(const char *address) -{ - long cid, port; - int colon; - struct sockaddr_vm sa_connect = { - .svm_family = AF_VSOCK, - }; - int sock_fd; - - colon = find_colon(address); - - cid = parse_cid(address); - port = parse_port(address + colon + 1); - - sa_connect.svm_cid = cid; - sa_connect.svm_port = port; - - sock_fd = socket(AF_VSOCK, SOCK_STREAM, 0); - if (sock_fd < 0) - die(1, NULL, "socket(AF_VSOCK)", ""); - - if (connect(sock_fd, (struct sockaddr *)&sa_connect, sizeof(sa_connect))) - die(1, NULL, "connect(AF_VSOCK)", ""); - - return sock_fd; -} diff --git a/alpine/packages/transfused/transfused_vsock.h b/alpine/packages/transfused/transfused_vsock.h deleted file mode 100644 index 6be8979e4..000000000 --- a/alpine/packages/transfused/transfused_vsock.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _TRANSFUSED_VSOCK_H_ -#define _TRANSFUSED_VSOCK_H_ - -int bind_vsock(const char *address); -int connect_vsock(const char *address); - -#endif /* _TRANSFUSED_VSOCK_H_ */ diff --git a/alpine/packages/transfused/vm_sockets.h b/alpine/packages/transfused/vm_sockets.h deleted file mode 100644 index 41934a185..000000000 --- a/alpine/packages/transfused/vm_sockets.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * VMware vSockets Driver - * - * Copyright (C) 2007-2013 VMware, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation version 2 and no later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#ifndef _UAPI_VM_SOCKETS_H -#define _UAPI_VM_SOCKETS_H - -#ifdef __KERNEL__ -#include -#else -#define __kernel_sa_family_t sa_family_t -#include -#endif - -/* Option name for STREAM socket buffer size. Use as the option name in - * setsockopt(3) or getsockopt(3) to set or get an unsigned long long that - * specifies the size of the buffer underlying a vSockets STREAM socket. - * Value is clamped to the MIN and MAX. - */ - -#define SO_VM_SOCKETS_BUFFER_SIZE 0 - -/* Option name for STREAM socket minimum buffer size. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get an unsigned long long that - * specifies the minimum size allowed for the buffer underlying a vSockets - * STREAM socket. - */ - -#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1 - -/* Option name for STREAM socket maximum buffer size. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get an unsigned long long - * that specifies the maximum size allowed for the buffer underlying a - * vSockets STREAM socket. - */ - -#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2 - -/* Option name for socket peer's host-specific VM ID. Use as the option name - * in getsockopt(3) to get a host-specific identifier for the peer endpoint's - * VM. The identifier is a signed integer. - * Only available for hypervisor endpoints. - */ - -#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3 - -/* Option name for determining if a socket is trusted. Use as the option name - * in getsockopt(3) to determine if a socket is trusted. The value is a - * signed integer. - */ - -#define SO_VM_SOCKETS_TRUSTED 5 - -/* Option name for STREAM socket connection timeout. Use as the option name - * in setsockopt(3) or getsockopt(3) to set or get the connection - * timeout for a STREAM socket. - */ - -#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6 - -/* Option name for using non-blocking send/receive. Use as the option name - * for setsockopt(3) or getsockopt(3) to set or get the non-blocking - * transmit/receive flag for a STREAM socket. This flag determines whether - * send() and recv() can be called in non-blocking contexts for the given - * socket. The value is a signed integer. - * - * This option is only relevant to kernel endpoints, where descheduling the - * thread of execution is not allowed, for example, while holding a spinlock. - * It is not to be confused with conventional non-blocking socket operations. - * - * Only available for hypervisor endpoints. - */ - -#define SO_VM_SOCKETS_NONBLOCK_TXRX 7 - -/* The vSocket equivalent of INADDR_ANY. This works for the svm_cid field of - * sockaddr_vm and indicates the context ID of the current endpoint. - */ - -#define VMADDR_CID_ANY -1U - -/* Bind to any available port. Works for the svm_port field of - * sockaddr_vm. - */ - -#define VMADDR_PORT_ANY -1U - -/* Use this as the destination CID in an address when referring to the - * hypervisor. VMCI relies on it being 0, but this would be useful for other - * transports too. - */ - -#define VMADDR_CID_HYPERVISOR 0 - -/* This CID is specific to VMCI and can be considered reserved (even VMCI - * doesn't use it anymore, it's a legacy value from an older release). - */ - -#define VMADDR_CID_RESERVED 1 - -/* Use this as the destination CID in an address when referring to the host - * (any process other than the hypervisor). VMCI relies on it being 2, but - * this would be useful for other transports too. - */ - -#define VMADDR_CID_HOST 2 - -/* Invalid vSockets version. */ - -#define VM_SOCKETS_INVALID_VERSION -1U - -/* The epoch (first) component of the vSockets version. A single byte - * representing the epoch component of the vSockets version. - */ - -#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v) & 0xFF000000) >> 24) - -/* The major (second) component of the vSockets version. A single byte - * representing the major component of the vSockets version. Typically - * changes for every major release of a product. - */ - -#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v) & 0x00FF0000) >> 16) - -/* The minor (third) component of the vSockets version. Two bytes representing - * the minor component of the vSockets version. - */ - -#define VM_SOCKETS_VERSION_MINOR(_v) (((_v) & 0x0000FFFF)) - -/* Address structure for vSockets. The address family should be set to - * AF_VSOCK. The structure members should all align on their natural - * boundaries without resorting to compiler packing directives. The total size - * of this structure should be exactly the same as that of struct sockaddr. - */ - -struct sockaddr_vm { - __kernel_sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(sa_family_t) - - sizeof(unsigned short) - - sizeof(unsigned int) - sizeof(unsigned int)]; -}; - -#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) - -#endif /* _UAPI_VM_SOCKETS_H */ diff --git a/alpine/packages/userns/etc/subgid b/alpine/packages/userns/etc/subgid deleted file mode 100644 index b8b245e67..000000000 --- a/alpine/packages/userns/etc/subgid +++ /dev/null @@ -1 +0,0 @@ -dockremap:100000:65536 diff --git a/alpine/packages/userns/etc/subuid b/alpine/packages/userns/etc/subuid deleted file mode 100644 index b8b245e67..000000000 --- a/alpine/packages/userns/etc/subuid +++ /dev/null @@ -1 +0,0 @@ -dockremap:100000:65536 diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/LICENSE b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/LICENSE deleted file mode 100644 index a85d08915..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/LICENSE +++ /dev/null @@ -1,71 +0,0 @@ -Copyright 2016 Rolf Neugebauer - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - -Some of the code in ./go/hvsock.go, ./go/hvsock_windows.go, and -zsyscall_windows.go is covered by the following licenses: -============================================================================== - -The MIT License (MIT) - -Copyright (c) 2015 Microsoft - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -and -=== - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/client.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/client.go deleted file mode 100644 index dd93b3439..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/client.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "bufio" - "flag" - "fmt" - "log" - - "../" -) - -var ( - vmstr string - portstr string -) - -func init() { - flag.StringVar(&vmstr, "vm", "", "Hyper-V VM to connect to") - flag.StringVar(&portstr, "port", "23a432c2-537a-4291-bcb5-d62504644739", "Hyper-V sockets service/port") -} - -func main() { - log.SetFlags(log.LstdFlags) - flag.Parse() - - vmid, err := hvsock.GuidFromString(vmstr) - if err != nil { - log.Fatalln("Failed to parse GUID", vmstr, err) - } - svcid, err := hvsock.GuidFromString(portstr) - if err != nil { - log.Fatalln("Failed to parse GUID", portstr, err) - } - - c, err := hvsock.Dial(hvsock.HypervAddr{VmId: vmid, ServiceId: svcid}) - if err != nil { - log.Fatalln("Failed to Dial:\n", vmstr, portstr, err) - } - - fmt.Println("Send: hello") - l, err := fmt.Fprintf(c, "hello\n") - if err != nil { - log.Fatalln("Failed to send: ", err) - } - fmt.Println("Sent: %s bytes", l) - - message, _ := bufio.NewReader(c).ReadString('\n') - fmt.Println("From SVR: " + message) -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go deleted file mode 100644 index f0ab0f4c0..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go +++ /dev/null @@ -1,131 +0,0 @@ -package main - -import ( - "bufio" - "flag" - "fmt" - "io" - "log" - "net" - "strings" - - "../hvsock" -) - -var ( - clientStr string - serverMode bool - - svcid, _ = hvsock.GuidFromString("3049197C-9A4E-4FBF-9367-97F792F16994") -) - -func init() { - flag.StringVar(&clientStr, "c", "", "Client") - flag.BoolVar(&serverMode, "s", false, "Start as a Server") -} - -func server() { - l, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - log.Fatalln("Listen():", err) - } - defer func() { - l.Close() - }() - - for { - conn, err := l.Accept() - if err != nil { - log.Fatalln("Accept(): ", err) - } - fmt.Printf("Received message %s -> %s \n", conn.RemoteAddr(), conn.LocalAddr()) - - go handleRequest(conn) - } -} - -func handleRequest(c net.Conn) { - defer func() { - fmt.Printf("Closing\n") - err := c.Close() - if err != nil { - log.Fatalln("Close():", err) - } - }() - - n, err := io.Copy(c, c) - if err != nil { - log.Fatalln("Copy():", err) - } - fmt.Printf("Copied Bytes: %d\n", n) - - fmt.Printf("Sending BYE message\n") - // The '\n' is important as the client use ReadString() - _, err = fmt.Fprintf(c, "Got %d bytes. Bye\n", n) - if err != nil { - log.Fatalln("Failed to send: ", err) - } - fmt.Printf("Sent bye\n") -} - -func client(vmid hvsock.GUID) { - sa := hvsock.HypervAddr{VmId: vmid, ServiceId: svcid} - c, err := hvsock.Dial(sa) - if err != nil { - log.Fatalln("Failed to Dial:\n", sa.VmId.String(), sa.ServiceId.String(), err) - } - - defer func() { - fmt.Printf("Closing\n") - c.Close() - }() - - fmt.Printf("Send: hello\n") - // Note the '\n' is significant as we use ReadString below - l, err := fmt.Fprintf(c, "hello\n") - if err != nil { - log.Fatalln("Failed to send: ", err) - } - fmt.Printf("Sent: %d bytes\n", l) - - message, err := bufio.NewReader(c).ReadString('\n') - if err != nil { - log.Fatalln("Failed to receive: ", err) - } - fmt.Printf("From SVR: %s", message) - - fmt.Printf("CloseWrite()\n") - c.CloseWrite() - - fmt.Printf("Waiting for Bye message\n") - message, err = bufio.NewReader(c).ReadString('\n') - if err != nil { - log.Fatalln("Failed to receive: ", err) - } - fmt.Printf("From SVR: %s", message) -} - -func main() { - log.SetFlags(log.LstdFlags) - flag.Parse() - - if serverMode { - fmt.Printf("Starting server\n") - server() - } - - vmid := hvsock.GUID_ZERO - var err error - if strings.Contains(clientStr, "-") { - vmid, err = hvsock.GuidFromString(clientStr) - if err != nil { - log.Fatalln("Can't parse GUID: ", clientStr) - } - } else if clientStr == "parent" { - vmid = hvsock.GUID_PARENT - } else { - vmid = hvsock.GUID_LOOPBACK - } - fmt.Printf("Client connecting to %s", vmid.String()) - client(vmid) -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go deleted file mode 100644 index ddb66dc71..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go +++ /dev/null @@ -1,243 +0,0 @@ -package main - -import ( - "bufio" - "flag" - "fmt" - "io" - "log" - "net" - "strings" - "sync" - "time" - - "crypto/md5" - "math/rand" - "sync/atomic" - - "../hvsock" -) - -var ( - clientStr string - serverMode bool - maxDataLen int - connections int - sleepTime int - verbose int - exitOnError bool - parallel int - svcid, _ = hvsock.GuidFromString("3049197C-9A4E-4FBF-9367-97F792F16994") - - connCounter int32 -) - -func init() { - flag.StringVar(&clientStr, "c", "", "Client") - flag.BoolVar(&serverMode, "s", false, "Start as a Server") - flag.IntVar(&maxDataLen, "l", 64*1024, "Maximum Length of data") - flag.IntVar(&connections, "i", 100, "Total number of connections") - flag.IntVar(&sleepTime, "w", 0, "Sleep time in seconds between new connections") - flag.IntVar(¶llel, "p", 1, "Run n connections in parallel") - flag.BoolVar(&exitOnError, "e", false, "Exit when an error occurs") - flag.IntVar(&verbose, "v", 0, "Set the verbosity level") - - rand.Seed(time.Now().UnixNano()) -} - -func main() { - log.SetFlags(log.LstdFlags) - flag.Parse() - - if verbose > 2 { - hvsock.Debug = true - } - - if serverMode { - fmt.Printf("Starting server\n") - server() - return - } - - // Client mode - vmid := hvsock.GUID_ZERO - var err error - if strings.Contains(clientStr, "-") { - vmid, err = hvsock.GuidFromString(clientStr) - if err != nil { - log.Fatalln("Can't parse GUID: ", clientStr) - } - } else if clientStr == "parent" { - vmid = hvsock.GUID_PARENT - } else { - vmid = hvsock.GUID_LOOPBACK - } - - if parallel <= 1 { - // No parallelism, run in the main thread. - fmt.Printf("Client connecting to %s\n", vmid.String()) - for i := 0; i < connections; i++ { - client(vmid, i) - time.Sleep(time.Duration(sleepTime) * time.Second) - } - return - } - - // Parallel clients - var wg sync.WaitGroup - for i := 0; i < parallel; i++ { - wg.Add(1) - go parClient(&wg, vmid) - } - wg.Wait() -} - -func server() { - l, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - log.Fatalln("Listen():", err) - } - defer func() { - l.Close() - }() - - connid := 0 - - for { - conn, err := l.Accept() - if err != nil { - log.Fatalf("Accept(): %s\n", err) - } - - prDebug("[%05d] accept(): %s -> %s \n", connid, conn.RemoteAddr(), conn.LocalAddr()) - go handleRequest(conn, connid) - connid++ - } -} - -func handleRequest(c net.Conn, connid int) { - defer func() { - prDebug("[%05d] Closing\n", connid) - err := c.Close() - if err != nil { - prError("[%05d] Close(): %s\n", connid, err) - } - }() - - n, err := io.Copy(c, c) - if err != nil { - prError("[%05d] Copy(): %s", connid, err) - return - } - prInfo("[%05d] Copied Bytes: %d\n", connid, n) - - if n == 0 { - return - } - - prDebug("[%05d] Sending BYE message\n", connid) - - // The '\n' is important as the client use ReadString() - _, err = fmt.Fprintf(c, "Got %d bytes. Bye\n", n) - if err != nil { - prError("[%05d] Failed to send: %s", connid, err) - return - } - prDebug("[%05d] Sent bye\n", connid) -} - -func parClient(wg *sync.WaitGroup, vmid hvsock.GUID) { - connid := int(atomic.AddInt32(&connCounter, 1)) - for connid < connections { - client(vmid, connid) - connid = int(atomic.AddInt32(&connCounter, 1)) - time.Sleep(time.Duration(sleepTime) * time.Second) - } - - wg.Done() -} - -func client(vmid hvsock.GUID, conid int) { - sa := hvsock.HypervAddr{VmId: vmid, ServiceId: svcid} - c, err := hvsock.Dial(sa) - if err != nil { - prError("[%05d] Failed to Dial: %s:%s %s\n", conid, sa.VmId.String(), sa.ServiceId.String(), err) - } - - defer c.Close() - - // Create buffer with random data and random length. - // Make sure the buffer is not zero-length - buflen := rand.Intn(maxDataLen-1) + 1 - txbuf := randBuf(buflen) - csum0 := md5.Sum(txbuf) - - prDebug("[%05d] TX: %d bytes, md5=%02x\n", conid, buflen, csum0) - - w := make(chan int) - go func() { - l, err := c.Write(txbuf) - if err != nil { - prError("[%05d] Failed to send: %s\n", conid, err) - } - if l != buflen { - prError("[%05d] Failed to send enough data: %d\n", conid, l) - } - - // Tell the other end that we are done - c.CloseWrite() - - w <- l - }() - - rxbuf := make([]byte, buflen) - - n, err := io.ReadFull(bufio.NewReader(c), rxbuf) - if err != nil { - prError("[%05d] Failed to receive: %s\n", conid, err) - return - } - csum1 := md5.Sum(rxbuf) - - totalSent := <-w - - prInfo("[%05d] RX: %d bytes, md5=%02x (sent=%d)\n", conid, n, csum1, totalSent) - if csum0 != csum1 { - prError("[%05d] Checksums don't match", conid) - } - - // Wait for Bye message - message, err := bufio.NewReader(c).ReadString('\n') - if err != nil { - prError("[%05d] Failed to receive bye: %s\n", conid, err) - } - prDebug("[%05d] From SVR: %s", conid, message) -} - -func randBuf(n int) []byte { - b := make([]byte, n) - for i := range b { - b[i] = byte(rand.Intn(255)) - } - return b -} - -func prError(format string, args ...interface{}) { - if exitOnError { - log.Fatalf(format, args...) - } else { - log.Printf(format, args...) - } -} - -func prInfo(format string, args ...interface{}) { - if verbose > 0 { - log.Printf(format, args...) - } -} - -func prDebug(format string, args ...interface{}) { - if verbose > 1 { - log.Printf(format, args...) - } -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go deleted file mode 100644 index 2e4f19ebd..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go +++ /dev/null @@ -1,414 +0,0 @@ -package hvsock - -import ( - "errors" - "fmt" - "io" - "log" - "net" - "sync" - "syscall" - - "encoding/binary" -) - -// This package provides a Go interface to Hyper-V sockets both on -// Windows and on Linux (assuming the appropriate Linux kernel patches -// have been applied). -// -// Unfortunately, it is not easy/possible to extend the existing Go -// socket implementations with new Address Families, so this module -// wraps directly around system calls (and handles Windows' -// asynchronous system calls). -// -// There is an additional wrinkle. Hyper-V sockets in currently -// shipping versions of Windows don't support graceful and/or -// unidirectional shutdown(). So we turn a stream based protocol into -// message based protocol which allows to send in-line "messages" to -// the other end. We then provide a stream based interface on top of -// that. Yuk. -// -// The message interface is pretty simple. We first send a 32bit -// message containing the size of the data in the following -// message. Messages are limited to 'maxmsgsize'. Special message -// (without data), `shutdownrd` and 'shutdownwr' are used to used to -// signal a shutdown to the other end. - -// On Windows 10 build 10586 larger maxMsgSize values work, but on -// newer builds it fails. It is unclear what the cause is... -const ( - maxMsgSize = 4 * 1024 // Maximum message size -) - -// Hypper-V sockets use GUIDs for addresses and "ports" -type GUID [16]byte - -// Convert a GUID into a string -func (g *GUID) String() string { - /* XXX This assume little endian */ - return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - g[3], g[2], g[1], g[0], - g[5], g[4], - g[7], g[6], - g[8], g[9], - g[10], g[11], g[12], g[13], g[14], g[15]) -} - -// Parse a GUID string -func GuidFromString(s string) (GUID, error) { - var g GUID - var err error - _, err = fmt.Sscanf(s, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - &g[3], &g[2], &g[1], &g[0], - &g[5], &g[4], - &g[7], &g[6], - &g[8], &g[9], - &g[10], &g[11], &g[12], &g[13], &g[14], &g[15]) - return g, err -} - -type HypervAddr struct { - VmId GUID - ServiceId GUID -} - -func (a HypervAddr) Network() string { return "hvsock" } - -func (a HypervAddr) String() string { - vmid := a.VmId.String() - svc := a.ServiceId.String() - - return vmid + ":" + svc -} - -var ( - Debug = false // Set to True to enable additional debug output - - GUID_ZERO, _ = GuidFromString("00000000-0000-0000-0000-000000000000") - GUID_WILDCARD, _ = GuidFromString("00000000-0000-0000-0000-000000000000") - GUID_BROADCAST, _ = GuidFromString("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") - GUID_CHILDREN, _ = GuidFromString("90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd") - GUID_LOOPBACK, _ = GuidFromString("e0e16197-dd56-4a10-9195-5ee7a155a838") - GUID_PARENT, _ = GuidFromString("a42e7cda-d03f-480c-9cc2-a4de20abb878") -) - -func Dial(raddr HypervAddr) (Conn, error) { - fd, err := syscall.Socket(AF_HYPERV, syscall.SOCK_STREAM, SHV_PROTO_RAW) - if err != nil { - return nil, err - } - - err = connect(fd, &raddr) - if err != nil { - return nil, err - } - - v, err := newHVsockConn(fd, HypervAddr{VmId: GUID_ZERO, ServiceId: GUID_ZERO}, raddr) - if err != nil { - return nil, err - } - v.wrlock = &sync.Mutex{} - return v, nil -} - -func Listen(addr HypervAddr) (net.Listener, error) { - - accept_fd, err := syscall.Socket(AF_HYPERV, syscall.SOCK_STREAM, SHV_PROTO_RAW) - if err != nil { - return nil, err - } - - err = bind(accept_fd, addr) - if err != nil { - return nil, err - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - return nil, err - } - - return &hvsockListener{accept_fd, addr}, nil -} - -const ( - shutdownrd = 0xdeadbeef // Message for CloseRead() - shutdownwr = 0xbeefdead // Message for CloseWrite() - closemsg = 0xdeaddead // Message for Close() -) - -// Conn is a hvsock connection which support half-close. -type Conn interface { - net.Conn - CloseRead() error - CloseWrite() error -} - -func (v *hvsockListener) Accept() (net.Conn, error) { - var raddr HypervAddr - fd, err := accept(v.accept_fd, &raddr) - if err != nil { - return nil, err - } - - a, err := newHVsockConn(fd, v.laddr, raddr) - if err != nil { - return nil, err - } - a.wrlock = &sync.Mutex{} - return a, nil -} - -func (v *hvsockListener) Close() error { - // Note this won't cause the Accept to unblock. - return syscall.Close(v.accept_fd) -} - -func (v *hvsockListener) Addr() net.Addr { - return HypervAddr{VmId: v.laddr.VmId, ServiceId: v.laddr.ServiceId} -} - -/* - * A wrapper around FileConn which supports CloseRead and CloseWrite - */ - -var ( - ErrSocketClosed = errors.New("HvSocket has already been closed") - ErrSocketWriteClosed = errors.New("HvSocket has been closed for write") - ErrSocketReadClosed = errors.New("HvSocket has been closed for read") - ErrSocketMsgSize = errors.New("HvSocket message was of wrong size") - ErrSocketMsgWrite = errors.New("HvSocket writing message") - ErrSocketNotEnoughData = errors.New("HvSocket not enough data written") - ErrSocketUnImplemented = errors.New("Function not implemented") -) - -type HVsockConn struct { - hvsockConn - - wrlock *sync.Mutex - - writeClosed bool - readClosed bool - - bytesToRead int -} - -func (v *HVsockConn) LocalAddr() net.Addr { - return v.local -} - -func (v *HVsockConn) RemoteAddr() net.Addr { - return v.remote -} - -func (v *HVsockConn) Close() error { - prDebug("Close\n") - - v.readClosed = true - v.writeClosed = true - - prDebug("TX: Close\n") - v.wrlock.Lock() - err := v.sendMsg(closemsg) - v.wrlock.Unlock() - if err != nil { - // chances are that the other end beat us to the close - prDebug("Mmmm. %s\n", err) - return v.close() - } - - // wait for reply/ignore errors - // we may get a EOF because the other end closed, - b := make([]byte, 4) - _, _ = v.read(b) - prDebug("close\n") - return v.close() -} - -func (v *HVsockConn) CloseRead() error { - if v.readClosed { - return ErrSocketReadClosed - } - - prDebug("TX: Shutdown Read\n") - v.wrlock.Lock() - err := v.sendMsg(shutdownrd) - v.wrlock.Unlock() - if err != nil { - return err - } - - v.readClosed = true - return nil -} - -func (v *HVsockConn) CloseWrite() error { - if v.writeClosed { - return ErrSocketWriteClosed - } - - prDebug("TX: Shutdown Write\n") - v.wrlock.Lock() - err := v.sendMsg(shutdownwr) - v.wrlock.Unlock() - if err != nil { - return err - } - - v.writeClosed = true - return nil -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} - -// Read into buffer. This function turns a stream interface into -// messages and also handles the inband control messages. -func (v *HVsockConn) Read(buf []byte) (int, error) { - if v.readClosed { - return 0, io.EOF - } - - if v.bytesToRead == 0 { - for { - // wait for next message - b := make([]byte, 4) - - n, err := v.read(b) - if err != nil { - return 0, err - } - - if n != 4 { - return n, ErrSocketMsgSize - } - - msg := int(binary.LittleEndian.Uint32(b)) - if msg == shutdownwr { - // The other end shutdown write. No point reading more - v.readClosed = true - prDebug("RX: ShutdownWrite\n") - return 0, io.EOF - } else if msg == shutdownrd { - // The other end shutdown read. No point writing more - v.writeClosed = true - prDebug("RX: ShutdownRead\n") - } else if msg == closemsg { - // Setting write close here forces a proper close - v.writeClosed = true - prDebug("RX: Close\n") - v.Close() - } else { - v.bytesToRead = msg - if v.bytesToRead == 0 { - // XXX Something is odd. If I don't have this here, this - // case is hit. However, with this code in place this - // case never get's hit. Suspect overly eager GC... - log.Printf("RX: Zero length %02x", b) - continue - } - break - } - } - } - - // If we get here, we know there is v.bytesToRead worth of - // data coming our way. Read it directly into to buffer passed - // in by the caller making sure we do not read mode than we - // should read by splicing the buffer. - toRead := min(len(buf), v.bytesToRead) - prDebug("READ: %d len=0x%x\n", int(v.fd), toRead) - n, err := v.read(buf[:toRead]) - if err != nil || n == 0 { - v.readClosed = true - return n, err - } - v.bytesToRead -= n - return n, nil -} - -func (v *HVsockConn) Write(buf []byte) (int, error) { - if v.writeClosed { - return 0, ErrSocketWriteClosed - } - - var err error - toWrite := len(buf) - written := 0 - - prDebug("WRITE: %d Total len=%x\n", int(v.fd), len(buf)) - - for toWrite > 0 { - if v.writeClosed { - return 0, ErrSocketWriteClosed - } - - // We write batches of MSG + data which need to be - // "atomic". We don't want to hold the lock for the - // entire Write() in case some other threads wants to - // send OOB data, e.g. for closing. - - v.wrlock.Lock() - - thisBatch := min(toWrite, maxMsgSize) - prDebug("WRITE: %d len=%x\n", int(v.fd), thisBatch) - // Write message header - err = v.sendMsg(uint32(thisBatch)) - if err != nil { - prDebug("Write MSG Error: %s\n", err) - goto ErrOut - } - - // Write data - n, err := v.write(buf[written : written+thisBatch]) - if err != nil { - prDebug("Write Error 3\n") - goto ErrOut - } - if n != thisBatch { - prDebug("Write Error 4\n") - err = ErrSocketNotEnoughData - goto ErrOut - } - toWrite -= n - written += n - v.wrlock.Unlock() - } - - return written, nil - -ErrOut: - v.wrlock.Unlock() - v.writeClosed = true - return 0, err -} - -// hvsockConn, SetDeadline(), SetReadDeadline(), and -// SetWriteDeadline() are OS specific. - -// Send a message to the other end -// The Lock must be held to call this functions -func (v *HVsockConn) sendMsg(msg uint32) error { - b := make([]byte, 4) - - binary.LittleEndian.PutUint32(b, msg) - n, err := v.write(b) - if err != nil { - prDebug("Write Error 1\n") - return err - } - if n != len(b) { - return ErrSocketMsgWrite - } - return nil -} - -func prDebug(format string, args ...interface{}) { - if Debug { - log.Printf(format, args...) - } -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go deleted file mode 100644 index 99f8ea1d0..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go +++ /dev/null @@ -1,70 +0,0 @@ -// Dummy implementation to compile on Mac OSX - -package hvsock - -import ( - "errors" - "time" -) - -const ( - AF_HYPERV = 42 - SHV_PROTO_RAW = 1 -) - -type hvsockListener struct { - accept_fd int - laddr HypervAddr -} - -// -// System call wrapper -// -func connect(s int, a *HypervAddr) (err error) { - return errors.New("connect() not implemented") -} - -func bind(s int, a HypervAddr) error { - return errors.New("bind() not implemented") -} - -func accept(s int, a *HypervAddr) (int, error) { - return 0, errors.New("accept() not implemented") -} - -// Internal representation. Complex mostly due to asynch send()/recv() syscalls. -type hvsockConn struct { - fd int - local HypervAddr - remote HypervAddr -} - -// Main constructor -func newHVsockConn(fd int, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { - v := &hvsockConn{local: local, remote: remote} - return &HVsockConn{hvsockConn: *v}, errors.New("newHVsockConn() not implemented") -} - -func (v *HVsockConn) close() error { - return errors.New("close() not implemented") -} - -func (v *HVsockConn) read(buf []byte) (int, error) { - return 0, errors.New("read() not implemented") -} - -func (v *HVsockConn) write(buf []byte) (int, error) { - return 0, errors.New("write() not implemented") -} - -func (v *HVsockConn) SetReadDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *HVsockConn) SetWriteDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *HVsockConn) SetDeadline(t time.Time) error { - return nil // FIXME -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go deleted file mode 100644 index 53d287c6f..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go +++ /dev/null @@ -1,147 +0,0 @@ -package hvsock - -/* -#include - -struct sockaddr_hv { - unsigned short shv_family; - unsigned short reserved; - unsigned char shv_vm_id[16]; - unsigned char shv_service_id[16]; -}; -int bind_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { - return bind(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); -} -int connect_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { - return connect(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); -} -int accept_hv(int fd, struct sockaddr_hv *sa_hv, socklen_t *sa_hv_len) { - return accept4(fd, (struct sockaddr *)sa_hv, sa_hv_len, 0); -} -*/ -import "C" - -import ( - "errors" - "fmt" - "os" - "strconv" - "time" -) - -const ( - AF_HYPERV = 43 - SHV_PROTO_RAW = 1 -) - -type hvsockListener struct { - accept_fd int - laddr HypervAddr -} - -// -// System call wrapper -// -func connect(s int, a *HypervAddr) (err error) { - sa := C.struct_sockaddr_hv{} - sa.shv_family = AF_HYPERV - sa.reserved = 0 - - for i := 0; i < 16; i++ { - sa.shv_vm_id[i] = C.uchar(a.VmId[i]) - } - for i := 0; i < 16; i++ { - sa.shv_service_id[i] = C.uchar(a.ServiceId[i]) - } - - if ret := C.connect_sockaddr_hv(C.int(s), &sa); ret != 0 { - return errors.New("connect() returned " + strconv.Itoa(int(ret))) - } - - return nil -} - -func bind(s int, a HypervAddr) error { - sa := C.struct_sockaddr_hv{} - sa.shv_family = AF_HYPERV - sa.reserved = 0 - - for i := 0; i < 16; i++ { - // XXX this should take the address from `a` but Linux - // currently only support 0s - sa.shv_vm_id[i] = C.uchar(GUID_ZERO[i]) - } - for i := 0; i < 16; i++ { - sa.shv_service_id[i] = C.uchar(a.ServiceId[i]) - } - - if ret := C.bind_sockaddr_hv(C.int(s), &sa); ret != 0 { - return errors.New("bind() returned " + strconv.Itoa(int(ret))) - } - - return nil -} - -func accept(s int, a *HypervAddr) (int, error) { - var accept_sa C.struct_sockaddr_hv - var accept_sa_len C.socklen_t - - accept_sa_len = C.sizeof_struct_sockaddr_hv - fd, err := C.accept_hv(C.int(s), &accept_sa, &accept_sa_len) - if err != nil { - return -1, err - } - - a.VmId = guidFromC(accept_sa.shv_vm_id) - a.ServiceId = guidFromC(accept_sa.shv_service_id) - - return int(fd), nil -} - -// Internal representation. Complex mostly due to asynch send()/recv() syscalls. -type hvsockConn struct { - fd int - hvsock *os.File - local HypervAddr - remote HypervAddr -} - -// Main constructor -func newHVsockConn(fd int, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { - hvsock := os.NewFile(uintptr(fd), fmt.Sprintf("hvsock:%d", fd)) - v := &hvsockConn{fd: fd, hvsock: hvsock, local: local, remote: remote} - - return &HVsockConn{hvsockConn: *v}, nil -} - -func (v *HVsockConn) close() error { - return v.hvsock.Close() -} - -func (v *HVsockConn) read(buf []byte) (int, error) { - return v.hvsock.Read(buf) -} - -func (v *HVsockConn) write(buf []byte) (int, error) { - return v.hvsock.Write(buf) -} - -func (v *HVsockConn) SetReadDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *HVsockConn) SetWriteDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *HVsockConn) SetDeadline(t time.Time) error { - return nil // FIXME -} - -func guidFromC(cg [16]C.uchar) GUID { - var g GUID - for i := 0; i < 16; i++ { - g[i] = byte(cg[i]) - } - return g -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go deleted file mode 100644 index 3008f9c95..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go +++ /dev/null @@ -1,309 +0,0 @@ -package hvsock - -import ( - "errors" - "io" - "log" - "sync" - "syscall" - "time" - "unsafe" -) - -// Make sure Winsock2 is initialised -func init() { - e := syscall.WSAStartup(uint32(0x202), &wsaData) - if e != nil { - log.Fatal("WSAStartup", e) - } -} - -const ( - AF_HYPERV = 34 - SHV_PROTO_RAW = 1 - socket_error = uintptr(^uint32(0)) -) - -// struck sockaddr equivalent -type rawSockaddrHyperv struct { - Family uint16 - Reserved uint16 - VmId GUID - ServiceId GUID -} - -type hvsockListener struct { - accept_fd syscall.Handle - laddr HypervAddr -} - -// Internal representation. Complex mostly due to asynch send()/recv() syscalls. -type hvsockConn struct { - fd syscall.Handle - local HypervAddr - remote HypervAddr - - wg sync.WaitGroup - closing bool - readDeadline time.Time - writeDeadline time.Time -} - -// Used for async system calls -const ( - cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 - cFILE_SKIP_SET_EVENT_ON_HANDLE = 2 -) - -var ( - errTimeout = &timeoutError{} - - wsaData syscall.WSAData -) - -type timeoutError struct{} - -func (e *timeoutError) Error() string { return "i/o timeout" } -func (e *timeoutError) Timeout() bool { return true } -func (e *timeoutError) Temporary() bool { return true } - -// Main constructor -func newHVsockConn(h syscall.Handle, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { - ioInitOnce.Do(initIo) - v := &hvsockConn{fd: h, local: local, remote: remote} - - _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) - if err != nil { - return nil, err - } - err = setFileCompletionNotificationModes(h, - cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE) - if err != nil { - return nil, err - } - - return &HVsockConn{hvsockConn: *v}, nil -} - -// Utility function to build a struct sockaddr for syscalls. -func (a HypervAddr) sockaddr(sa *rawSockaddrHyperv) (unsafe.Pointer, int32, error) { - sa.Family = AF_HYPERV - sa.Reserved = 0 - for i := 0; i < len(sa.VmId); i++ { - sa.VmId[i] = a.VmId[i] - } - for i := 0; i < len(sa.ServiceId); i++ { - sa.ServiceId[i] = a.ServiceId[i] - } - - return unsafe.Pointer(sa), int32(unsafe.Sizeof(*sa)), nil -} - -func connect(s syscall.Handle, a *HypervAddr) (err error) { - var sa rawSockaddrHyperv - ptr, n, err := a.sockaddr(&sa) - if err != nil { - return err - } - - return sys_connect(s, ptr, n) -} - -func bind(s syscall.Handle, a HypervAddr) error { - var sa rawSockaddrHyperv - ptr, n, err := a.sockaddr(&sa) - if err != nil { - return err - } - - return sys_bind(s, ptr, n) -} - -func accept(s syscall.Handle, a *HypervAddr) (syscall.Handle, error) { - return 0, errors.New("accept(): Unimplemented") -} - -// -// File IO/Socket interface -// -func (s *HVsockConn) close() error { - s.closeHandle() - - return nil -} - -// Underlying raw read() function. -func (v *HVsockConn) read(buf []byte) (int, error) { - var b syscall.WSABuf - var bytes uint32 - var f uint32 - - b.Len = uint32(len(buf)) - b.Buf = &buf[0] - - c, err := v.prepareIo() - if err != nil { - return 0, err - } - - err = syscall.WSARecv(v.fd, &b, 1, &bytes, &f, &c.o, nil) - n, err := v.asyncIo(c, v.readDeadline, bytes, err) - - // Handle EOF conditions. - if err == nil && n == 0 && len(buf) != 0 { - return 0, io.EOF - } - if err == syscall.ERROR_BROKEN_PIPE { - return 0, io.EOF - } - - return n, err -} - -// Underlying raw write() function. -func (v *HVsockConn) write(buf []byte) (int, error) { - var b syscall.WSABuf - var f uint32 - var bytes uint32 - - if len(buf) == 0 { - return 0, nil - } - - f = 0 - b.Len = uint32(len(buf)) - b.Buf = &buf[0] - - c, err := v.prepareIo() - if err != nil { - return 0, err - } - err = syscall.WSASend(v.fd, &b, 1, &bytes, f, &c.o, nil) - return v.asyncIo(c, v.writeDeadline, bytes, err) -} - -func (v *HVsockConn) SetReadDeadline(t time.Time) error { - v.readDeadline = t - return nil -} - -func (v *HVsockConn) SetWriteDeadline(t time.Time) error { - v.writeDeadline = t - return nil -} - -func (v *HVsockConn) SetDeadline(t time.Time) error { - v.SetReadDeadline(t) - v.SetWriteDeadline(t) - return nil -} - -// The code below here is adjusted from: -// https://github.com/Microsoft/go-winio/blob/master/file.go - -var ioInitOnce sync.Once -var ioCompletionPort syscall.Handle - -// ioResult contains the result of an asynchronous IO operation -type ioResult struct { - bytes uint32 - err error -} - -type ioOperation struct { - o syscall.Overlapped - ch chan ioResult -} - -func initIo() { - h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff) - if err != nil { - panic(err) - } - ioCompletionPort = h - go ioCompletionProcessor(h) -} - -func (v *hvsockConn) closeHandle() { - if !v.closing { - // cancel all IO and wait for it to complete - v.closing = true - cancelIoEx(v.fd, nil) - v.wg.Wait() - // at this point, no new IO can start - syscall.Close(v.fd) - v.fd = 0 - } -} - -// prepareIo prepares for a new IO operation -func (s *hvsockConn) prepareIo() (*ioOperation, error) { - s.wg.Add(1) - if s.closing { - return nil, ErrSocketClosed - } - c := &ioOperation{} - c.ch = make(chan ioResult) - return c, nil -} - -// ioCompletionProcessor processes completed async IOs forever -func ioCompletionProcessor(h syscall.Handle) { - // Set the timer resolution to 1. This fixes a performance regression in golang 1.6. - timeBeginPeriod(1) - for { - var bytes uint32 - var key uintptr - var op *ioOperation - err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE) - if op == nil { - panic(err) - } - op.ch <- ioResult{bytes, err} - } -} - -// asyncIo processes the return value from ReadFile or WriteFile, blocking until -// the operation has actually completed. -func (v *hvsockConn) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) { - if err != syscall.ERROR_IO_PENDING { - v.wg.Done() - return int(bytes), err - } - - var r ioResult - wait := true - timedout := false - if v.closing { - cancelIoEx(v.fd, &c.o) - } else if !deadline.IsZero() { - now := time.Now() - if !deadline.After(now) { - timedout = true - } else { - timeout := time.After(deadline.Sub(now)) - select { - case r = <-c.ch: - wait = false - case <-timeout: - timedout = true - } - } - } - if timedout { - cancelIoEx(v.fd, &c.o) - } - if wait { - r = <-c.ch - } - err = r.err - if err == syscall.ERROR_OPERATION_ABORTED { - if v.closing { - err = ErrSocketClosed - } else if timedout { - err = errTimeout - } - } - v.wg.Done() - return int(r.bytes), err -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go deleted file mode 100644 index 32fb2f253..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go +++ /dev/null @@ -1,100 +0,0 @@ -package hvsock - -import ( - "syscall" - "unsafe" -) - -var ( - modws2_32 = syscall.NewLazyDLL("ws2_32.dll") - modwinmm = syscall.NewLazyDLL("winmm.dll") - modkernel32 = syscall.NewLazyDLL("kernel32.dll") - - procConnect = modws2_32.NewProc("connect") - procbind = modws2_32.NewProc("bind") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod") -) - -func sys_connect(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procConnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - - return -} - -func sys_bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socket_error { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) - newport = syscall.Handle(r0) - if newport == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func timeBeginPeriod(period uint32) (n int32) { - r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) - n = int32(r0) - return -} diff --git a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go b/alpine/packages/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go deleted file mode 100644 index 21da5cd69..000000000 --- a/alpine/packages/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go +++ /dev/null @@ -1,195 +0,0 @@ -package vsock - -import ( - "errors" - "fmt" - "net" - "os" - "syscall" - "time" -) - -/* No way to teach net or syscall about vsock sockaddr, so go right to C */ - -/* -#include - -struct sockaddr_vm { - sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(sa_family_t) - sizeof(unsigned short) - - sizeof(unsigned int) - sizeof(unsigned int)]; -}; - -int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return bind(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { - return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); -} -*/ -import "C" - -const ( - AF_VSOCK = 40 - VSOCK_CID_ANY = 4294967295 /* 2^32-1 */ - VSOCK_CID_HYPERVISOR = 0 - VSOCK_CID_HOST = 2 - VSOCK_CID_SELF = 3 -) - -func Dial(cid, port uint) (Conn, error) { - fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) - if err != nil { - return nil, err - } - - sa := C.struct_sockaddr_vm{} - sa.svm_family = AF_VSOCK - sa.svm_port = C.uint(port) - sa.svm_cid = C.uint(cid) - - if ret, errno := C.connect_sockaddr_vm(C.int(fd), &sa); ret != 0 { - return nil, errors.New(fmt.Sprintf( - "failed bind connect to %08x.%08x, returned %d, errno %d: %s", - sa.svm_cid, sa.svm_port, ret, errno, errno)) - } - - return newVsockConn(uintptr(fd), port) -} - -// Listen returns a net.Listener which can accept connections on the given -// vhan port. -func Listen(port uint) (net.Listener, error) { - accept_fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) - if err != nil { - return nil, err - } - - sa := C.struct_sockaddr_vm{} - sa.svm_family = AF_VSOCK - sa.svm_port = C.uint(port) - sa.svm_cid = VSOCK_CID_ANY - - if ret, errno := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { - return nil, errors.New(fmt.Sprintf( - "failed bind vsock connection to %08x.%08x, returned %d, errno %d: %s", - sa.svm_cid, sa.svm_port, ret, errno, errno)) - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - return nil, err - } - return &vsockListener{accept_fd, port}, nil -} - -// Conn is a vsock connection which support half-close. -type Conn interface { - net.Conn - CloseRead() error - CloseWrite() error -} - -type vsockListener struct { - accept_fd int - port uint -} - -func (v *vsockListener) Accept() (net.Conn, error) { - var accept_sa C.struct_sockaddr_vm - var accept_sa_len C.socklen_t - - accept_sa_len = C.sizeof_struct_sockaddr_vm - fd, err := C.accept_vm(C.int(v.accept_fd), &accept_sa, &accept_sa_len) - if err != nil { - return nil, err - } - return newVsockConn(uintptr(fd), v.port) -} - -func (v *vsockListener) Close() error { - // Note this won't cause the Accept to unblock. - return syscall.Close(v.accept_fd) -} - -type VsockAddr struct { - Port uint -} - -func (a VsockAddr) Network() string { - return "vsock" -} - -func (a VsockAddr) String() string { - return fmt.Sprintf("%08x", a.Port) -} - -func (v *vsockListener) Addr() net.Addr { - return VsockAddr{Port: v.port} -} - -// a wrapper around FileConn which supports CloseRead and CloseWrite -type vsockConn struct { - vsock *os.File - fd uintptr - local VsockAddr - remote VsockAddr -} - -type VsockConn struct { - vsockConn -} - -func newVsockConn(fd uintptr, localPort uint) (*VsockConn, error) { - vsock := os.NewFile(fd, fmt.Sprintf("vsock:%d", fd)) - local := VsockAddr{Port: localPort} - remote := VsockAddr{Port: uint(0)} // FIXME - return &VsockConn{vsockConn{vsock: vsock, fd: fd, local: local, remote: remote}}, nil -} - -func (v *VsockConn) LocalAddr() net.Addr { - return v.local -} - -func (v *VsockConn) RemoteAddr() net.Addr { - return v.remote -} - -func (v *VsockConn) CloseRead() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_RD) -} - -func (v *VsockConn) CloseWrite() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_WR) -} - -func (v *VsockConn) Close() error { - return v.vsock.Close() -} - -func (v *VsockConn) Read(buf []byte) (int, error) { - return v.vsock.Read(buf) -} - -func (v *VsockConn) Write(buf []byte) (int, error) { - return v.vsock.Write(buf) -} - -func (v *VsockConn) SetDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetReadDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetWriteDeadline(t time.Time) error { - return nil // FIXME -} diff --git a/alpine/packages/vendor/manifest b/alpine/packages/vendor/manifest deleted file mode 100644 index 19690cf88..000000000 --- a/alpine/packages/vendor/manifest +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": 0, - "dependencies": [ - { - "importpath": "github.com/rneugeba/virtsock/go", - "repository": "https://github.com/rneugeba/virtsock", - "vcs": "git", - "revision": "650ef8224a0c06b4b20e9bee1600dbf677c8176d", - "branch": "master", - "path": "/go", - "notests": true - } - ] -} diff --git a/alpine/packages/vsudd/.gitignore b/alpine/packages/vsudd/.gitignore deleted file mode 100644 index 5b42612bc..000000000 --- a/alpine/packages/vsudd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sbin/ diff --git a/alpine/packages/vsudd/Makefile b/alpine/packages/vsudd/Makefile deleted file mode 100644 index 6516d27a9..000000000 --- a/alpine/packages/vsudd/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -GO_COMPILE=mobylinux/go-compile:d2d25ac665b5148ad356d0eab3ff3762a68c633d@sha256:aab55d0c317460850e66a07dd94139cc11ea9e1c0bee88716a6a8c768740885f - -default: sbin/vsudd - -DEPS=$(wildcard *.go) - -sbin/vsudd: $(DEPS) ../vendor/manifest - mkdir -p $(dir $@) - tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - - -clean: - rm -rf sbin - -.DELETE_ON_ERROR: diff --git a/alpine/packages/vsudd/etc/init.d/vsudd b/alpine/packages/vsudd/etc/init.d/vsudd deleted file mode 100755 index 7a0c05982..000000000 --- a/alpine/packages/vsudd/etc/init.d/vsudd +++ /dev/null @@ -1,55 +0,0 @@ -#!/sbin/openrc-run - -description="vsock socket proxy client" - -depend() -{ - need bootmisc -} - -start() -{ - [ "$(mobyplatform)" != "mac" ] && [ "$(mobyplatform)" != "windows" ] && exit 0 - - ebegin "Starting vsock proxy" - - if [ "$(mobyplatform)" = "windows" ]; then - DOCKER_PORT=23a432c2-537a-4291-bcb5-d62504644739 - SYSLOG_PORT="" #TBD - else - DOCKER_PORT=2376 - SYSLOG_PORT=514 - fi - - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/vsudd.pid - - if [ -n "$SYSLOG_PORT" ] ; then - # Can be inlined below once Windows defines syslog port - SYSLOG_SOCK=/var/run/syslog.vsock - SYSLOG_OPT="-syslog ${SYSLOG_PORT}:${SYSLOG_SOCK}" - fi - - start-stop-daemon --start --quiet \ - --background \ - --exec /sbin/vsudd \ - -- -inport "${DOCKER_PORT}:unix:/var/run/docker.sock" \ - ${SYSLOG_OPT} \ - -pidfile ${PIDFILE} - - ewaitfile 10 ${SYSLOG_SOCK} ${PIDFILE} - - eend $? "Failed to start vsudd" -} - -stop() -{ - [ "$(mobyplatform)" != "mac" ] && [ "$(mobyplatform)" != "windows" ] && exit 0 - - ebegin "Stopping docker socket passthrough" - - [ -n "${PIDFILE}" ] || PIDFILE=/var/run/vsudd.pid - - start-stop-daemon --stop --quiet --pidfile ${PIDFILE} - - eend $? "Failed to stop vsudd" -} diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go deleted file mode 100644 index d1461e94e..000000000 --- a/alpine/packages/vsudd/main.go +++ /dev/null @@ -1,239 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io" - "log" - "log/syslog" - "net" - "os" - "strconv" - "strings" - "sync" - "syscall" - - "github.com/rneugeba/virtsock/go/hvsock" - "github.com/rneugeba/virtsock/go/vsock" -) - -type forward struct { - vsock string - net string // "unix" or "unixgram" - usock string -} - -type forwards []forward - -var ( - inForwards forwards - detach bool - useHVsock bool - syslogFwd string - pidfile string -) - -type vConn interface { - net.Conn - CloseRead() error - CloseWrite() error -} - -func (f *forwards) String() string { - return "Forwards" -} - -func (f *forwards) Set(value string) error { - s := strings.SplitN(value, ":", 3) - if len(s) != 3 { - return fmt.Errorf("Failed to parse: %s", value) - } - var newF forward - newF.vsock = s[0] - newF.net = s[1] - newF.usock = s[2] - *f = append(*f, newF) - return nil -} - -func init() { - flag.Var(&inForwards, "inport", "incoming port to forward") - flag.StringVar(&syslogFwd, "syslog", "", "enable syslog forwarding") - flag.BoolVar(&detach, "detach", false, "detach from terminal") - flag.StringVar(&pidfile, "pidfile", "", "pid file") -} - -func main() { - log.SetFlags(log.LstdFlags) - flag.Parse() - - if pidfile != "" { - file, err := os.OpenFile(pidfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - log.Fatalln("Failed to open pidfile", err) - } - _, err = fmt.Fprintf(file, "%d", os.Getpid()) - file.Close() - if err != nil { - log.Fatalln("Failed to write pid", err) - } - } - - if detach { - syslog, err := syslog.New(syslog.LOG_INFO|syslog.LOG_DAEMON, "vsudd") - if err != nil { - log.Fatalln("Failed to open syslog", err) - } - - null, err := os.OpenFile("/dev/null", os.O_RDWR, 0) - if err != nil { - log.Fatalln("Failed to open /dev/null", err) - } - - /* Don't do this above since we aren't yet forwarding - /* syslog (if we've been asked to) so the above error - /* reporting wants to go via the default path - /* (stdio). */ - - log.SetOutput(syslog) - log.SetFlags(0) - - fd := null.Fd() - syscall.Dup2(int(fd), int(os.Stdin.Fd())) - syscall.Dup2(int(fd), int(os.Stdout.Fd())) - syscall.Dup2(int(fd), int(os.Stderr.Fd())) - } - - var wg sync.WaitGroup - - if syslogFwd != "" { - wg.Add(1) - go func() { - defer wg.Done() - handleSyslogForward(syslogFwd) - }() - } - - connid := 0 - - for _, inF := range inForwards { - var portstr = inF.vsock - var network = inF.net - var usock = inF.usock - - var l net.Listener - - if network != "unix" { - log.Fatalf("cannot forward incoming port to %s:%s", network, usock) - } - - log.Printf("incoming port forward from %s to %s", portstr, usock) - - if strings.Contains(portstr, "-") { - svcid, err := hvsock.GuidFromString(portstr) - if err != nil { - log.Fatalln("Failed to parse GUID", portstr, err) - } - l, err = hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - log.Fatalf("Failed to bind to hvsock port: %s", err) - } - log.Printf("Listening on ServiceId %s", svcid) - useHVsock = true - } else { - port, err := strconv.ParseUint(portstr, 10, 32) - if err != nil { - log.Fatalln("Can't convert %s to a uint.", portstr, err) - } - l, err = vsock.Listen(uint(port)) - if err != nil { - log.Fatalf("Failed to bind to vsock port %d: %s", port, err) - } - log.Printf("Listening on port %s", portstr) - useHVsock = false - } - - wg.Add(1) - - go func() { - defer wg.Done() - for { - connid++ - conn, err := l.Accept() - if err != nil { - log.Printf("Error accepting connection: %s", err) - return // no more listening - } - log.Printf("Connection %d to: %s from: %s\n", connid, portstr, conn.RemoteAddr()) - - go handleOneIn(connid, conn.(vConn), usock) - } - }() - } - - wg.Wait() -} - -func handleOneIn(connid int, conn vConn, sock string) { - defer func() { - if err := conn.Close(); err != nil { - // On windows we get an EINVAL when the other end already closed - // Don't bother spilling this into the logs - if !(useHVsock && err == syscall.EINVAL) { - log.Println(connid, "Error closing", conn, ":", err) - } - } - }() - - var docker *net.UnixConn - var err error - - docker, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: sock, Net: "unix"}) - - if err != nil { - // If the forwarding program has broken then close and continue - log.Println(connid, "Failed to connect to Unix domain socket", sock, err) - return - } - defer func() { - if err := docker.Close(); err != nil { - log.Println(connid, "Error closing", docker, ":", err) - } - }() - - w := make(chan int64) - go func() { - n, err := io.Copy(conn, docker) - if err != nil { - log.Println(connid, "error copying from docker to vsock:", err) - } - - err = docker.CloseRead() - if err != nil { - log.Println(connid, "error CloseRead on docker socket:", err) - } - err = conn.CloseWrite() - if err != nil { - log.Println(connid, "error CloseWrite on vsock:", err) - } - w <- n - }() - - n, err := io.Copy(docker, conn) - if err != nil { - log.Println(connid, "error copying from vsock to docker:", err) - } - totalRead := n - - err = docker.CloseWrite() - if err != nil { - log.Println(connid, "error CloseWrite on docker socket:", err) - } - err = conn.CloseRead() - if err != nil { - log.Println(connid, "error CloseRead on vsock:", err) - } - - totalWritten := <-w - log.Println(connid, "Done. read:", totalRead, "written:", totalWritten) -} diff --git a/alpine/packages/vsudd/vsyslog.go b/alpine/packages/vsudd/vsyslog.go deleted file mode 100644 index 6bc738357..000000000 --- a/alpine/packages/vsudd/vsyslog.go +++ /dev/null @@ -1,179 +0,0 @@ -/* -* Functions in this file are used to forward syslog messages to the -* host and must be quite careful about their own logging. In general -* error messages should go via the console log.Logger defined in this -* file. - */ -package main - -import ( - "errors" - "fmt" - "log" - "net" - "os" - "strconv" - "strings" - - "github.com/rneugeba/virtsock/go/hvsock" - "github.com/rneugeba/virtsock/go/vsock" -) - -var ( - console *log.Logger - currentConn vConn - - alreadyConnectedOnce bool - - /* When writing we don't discover e.g. EPIPE until the _next_ - * attempt to write. Therefore we keep a copy of the last - * message sent such that we can repeat it after an error. - * - * Note that this is imperfect since their can be multiple - * messages in flight at the point a connection collapses - * which will then be lost. This only handles the delayed - * notification of such an error to this code. - */ - lastMessage []byte -) - -/* rfc5425 like scheme, see section 4.3 */ -func rfc5425Write(conn vConn, buf []byte) error { - - msglen := fmt.Sprintf("%d ", len(buf)) - - _, err := conn.Write([]byte(msglen)) - /* XXX todo, check for serious vs retriable errors */ - if err != nil { - console.Printf("Error in length write: %s", err) - return err - } - - _, err = conn.Write(buf) - /* XXX todo, check for serious vs retriable errors */ - if err != nil { - console.Printf("Error in buf write: %s", err) - } - - return err -} - -func forwardSyslogDatagram(buf []byte, portstr string) error { - for try := 0; try < 2; try++ { - conn := currentConn - if conn == nil { - if strings.Contains(portstr, "-") { - svcid, err := hvsock.GuidFromString(portstr) - if err != nil { - console.Fatalln("Failed to parse GUID", portstr, err) - } - - conn, err = hvsock.Dial(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) - if err != nil { - console.Printf("Failed to dial hvsock port: %s", err) - continue - } - } else { - port, err := strconv.ParseUint(portstr, 10, 32) - if err != nil { - console.Fatalln("Can't convert %s to a uint.", portstr, err) - } - - conn, err = vsock.Dial(vsock.VSOCK_CID_HOST, uint(port)) - if err != nil { - console.Printf("Failed to dial vsock port %d: %s", port, err) - continue - } - } - - conn.CloseRead() - - /* - * Only log on reconnection, not the initial connection since - * that is mostly uninteresting - */ - if alreadyConnectedOnce { - console.Printf("Opened new conn to %s: %#v", portstr, conn) - } - alreadyConnectedOnce = true - - if lastMessage != nil { - console.Printf("Replaying last message: %s", lastMessage) - err := rfc5425Write(conn, lastMessage) - if err != nil { - conn.Close() - continue - } - lastMessage = nil - } - - currentConn = conn - } - - err := rfc5425Write(conn, buf) - if err != nil { - currentConn.Close() - currentConn = nil - console.Printf("Failed to write: %s", string(buf)) - continue - } - - if try > 0 { - console.Printf("Forwarded on attempt %d: %s", try+1, string(buf)) - } - - // Keep a copy in case we get an EPIPE from the next write - lastMessage = make([]byte, len(buf)) - copy(lastMessage, buf) - - return nil - } - - lastMessage = nil // No point repeating this now - return errors.New("Failed to send datagram, too many retries") -} - -func handleSyslogForward(cfg string) { - // logging to the default syslog while trying to do syslog - // forwarding would result in infinite loops, so log all - // messages in this callchain to the console instead. - logFile, err := os.OpenFile("/dev/console", os.O_WRONLY, 0) - if err != nil { - /* What are the chances of this going anywhere useful... */ - log.Fatalln("Failed to open /dev/console for syslog forward logging", err) - } - - console = log.New(logFile, "vsyslog: ", log.LstdFlags) - - s := strings.SplitN(cfg, ":", 2) - if len(s) != 2 { - console.Fatalf("Failed to parse: %s", cfg) - } - vsock := s[0] - usock := s[1] - - err = os.Remove(usock) - if err != nil && !os.IsNotExist(err) { - console.Printf("Failed to remove %s: %s", usock, err) - /* Try and carry on... */ - } - - l, err := net.ListenUnixgram("unixgram", &net.UnixAddr{Name: usock, Net: "unixgram"}) - if err != nil { - console.Fatalf("Failed to listen to unixgram:%s: %s", usock, err) - } - - var buf [4096]byte // Ugh, no way to peek at the next message's size in Go - for { - r, err := l.Read(buf[:]) - if err != nil { - console.Fatalf("Failed to read: %s", err) - } - - err = forwardSyslogDatagram(buf[:r], vsock) - if err != nil { - console.Printf("Failed to send log: %s: %s", - err, string(buf[:r])) - } - } -} diff --git a/alpine/packages/windowsnet/etc/init.d/windowsnet b/alpine/packages/windowsnet/etc/init.d/windowsnet deleted file mode 100755 index bd0890c53..000000000 --- a/alpine/packages/windowsnet/etc/init.d/windowsnet +++ /dev/null @@ -1,30 +0,0 @@ -#!/sbin/openrc-run - -description="Configuring Windows network settings from database." - -depend() { - need database-windows - before sysctl net -} - -start() { - [ "$(mobyplatform)" = "windows" ] || exit 0 - - ebegin "Configuring Windows network settings from database" - - # We have two network interfaces. The Hyper-V interface - # comes up as eth0. Rename and configure it. - ip link set eth0 down - ip link set eth0 name hvint0 - - mobyconfig exists net/config && NETCONFIG=`mobyconfig get net/config` - if [ "${NETCONFIG}" = "static" ]; then - # assume that the other configsDB entries exist - IP=`mobyconfig get net/address` - MASK=`mobyconfig get net/netmask` - ip addr add ${IP}/${MASK} dev hvint0 - ip link set hvint0 up - fi - - eend 0 -} diff --git a/alpine/test/Makefile b/alpine/test/Makefile deleted file mode 100644 index 05550f6e3..000000000 --- a/alpine/test/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -default: test.img - -RIDDLER=mobylinux/riddler:7d4545d8b8ac2700971a83f12a3446a76db28c14@sha256:11b7310df6482fc38aa52b419c2ef1065d7b9207c633d47554e13aa99f6c0b72 - -TEST_IMAGE=mobylinux/test:725422886c3ea8fca2e0f4a8df5c6442cb1e937b@sha256:a077b8f84a51a4f4271b62adaa44985a4feff3d0a82b0d5fa8a46b45378428bc - -container.tar: - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock $(RIDDLER) \ - $(TEST_IMAGE) /test --cap-drop all --cap-add SYS_ADMIN -e HOME=/tmp \ - -v /tmp:/tmp -v /var/run/docker.sock:/var/run/docker.sock:ro \ - -v /usr/bin/docker:/usr/bin/docker:ro \ - -v /etc/resolv.conf:/etc/resolv.conf:ro \ - --net host --read-only $(TEST_IMAGE) /bin/sh /bin/test.sh >$@ - -TAR2INITRD_IMAGE=mobylinux/tar2initrd:d5711601eb5b89de0f052d87365e18388ff3f1b5@sha256:58d377e65845f91400e173ce9fca93462f2f237947eef2b0d2c17bb4f2da5ee8 - -test.img: container.tar - cat $^ | docker run --rm --read-only --net=none --log-driver=none --tmpfs /tmp -i $(TAR2INITRD_IMAGE) > $@ - -clean: - rm -f container.tar test.img - -.DELETE_ON_ERROR: diff --git a/alpine/usr/lib/dhcpcd/dhcpcd-hooks/10-mtu b/alpine/usr/lib/dhcpcd/dhcpcd-hooks/10-mtu deleted file mode 100644 index f04274e70..000000000 --- a/alpine/usr/lib/dhcpcd/dhcpcd-hooks/10-mtu +++ /dev/null @@ -1,38 +0,0 @@ -# Configure the MTU for the interface - -mtu_dir="$state_dir/mtu" - -set_mtu() -{ - local mtu=$1 - - if [ -w /sys/class/net/$interface/mtu ]; then - echo "$mtu" >/sys/class/net/$interface/mtu - else - ifconfig "$interface" mtu "$mtu" - fi -} - -if [ "$reason" = PREINIT -a -e "$mtu_dir/$interface" ]; then - rm "$mtu_dir/$interface" -elif [ -n "$new_interface_mtu" ] && $if_up; then - # The smalled MTU dhcpcd can work with is 576 - if [ "$new_interface_mtu" -ge 576 ]; then - if set_mtu "$new_interface_mtu"; then - syslog info "$interface: MTU set to $new_interface_mtu" - # Save the MTU so we can restore it later - if [ ! -e "$mtu_dir/$interface" ]; then - mkdir -p "$mtu_dir" - echo "$ifmtu" > "$mtu_dir/$interface" - fi - fi - fi -elif [ -e "$mtu_dir/$interface" ]; then - if $if_up || $if_down; then - # No MTU in this state, so restore the prior MTU - mtu=$(cat "$mtu_dir/$interface") - syslog info "$interface: MTU restored to $mtu" - set_mtu "$mtu" - rm "$mtu_dir/$interface" - fi -fi diff --git a/base/init/etc/init.d/containers b/base/init/etc/init.d/containers index fdb76b32a..65c827020 100755 --- a/base/init/etc/init.d/containers +++ b/base/init/etc/init.d/containers @@ -8,11 +8,25 @@ while ! ctr list 2> /dev/null; do sleep 1; done # temporarily using runc not containerd LOG=/var/log/system-containers.log touch $LOG -for f in /containers/* -do - base="$(basename $f)" - /sbin/start-stop-daemon --start --pidfile /run/$base.pid --exec /usr/bin/runc -- run --bundle "$f" --pid-file /run/$base.pid "$(basename $f)" $LOG >$LOG & - printf " - $(basename $f)\n" -done + +if [ -d /containers/system ] +then + for f in $(find /containers/system -mindepth 1 -maxdepth 1 | sort) + do + base="$(basename $f)" + /usr/bin/runc -- run --bundle "$f" "$(basename $f)" + printf " - $base\n" + done +fi + +if [ -d /containers/daemon ] +then + for f in $(find /containers/daemon -mindepth 1 -maxdepth 1 | sort) + do + base="$(basename $f)" + /sbin/start-stop-daemon --start --pidfile /run/$base.pid --exec /usr/bin/runc -- run --bundle "$f" --pid-file /run/$base.pid "$(basename $f)" $LOG >$LOG & + printf " - $base\n" + done +fi wait diff --git a/moby/config.go b/config.go similarity index 78% rename from moby/config.go rename to config.go index 78383e393..b4d2096fa 100644 --- a/moby/config.go +++ b/config.go @@ -4,6 +4,7 @@ import ( "archive/tar" "bytes" "errors" + "fmt" "path" "strconv" "strings" @@ -11,10 +12,12 @@ import ( "gopkg.in/yaml.v2" ) +// Moby is the type of a Moby config file type Moby struct { Kernel string Init string System []MobyImage + Daemon []MobyImage Files []struct { Path string Contents string @@ -24,6 +27,7 @@ type Moby struct { } } +// MobyImage is the type of an image config, based on Compose type MobyImage struct { Name string Image string @@ -32,10 +36,12 @@ type MobyImage struct { OomScoreAdj int64 `yaml:"oom_score_adj"` Command []string NetworkMode string `yaml:"network_mode"` + Pid string } const riddler = "mobylinux/riddler:7d4545d8b8ac2700971a83f12a3446a76db28c14@sha256:11b7310df6482fc38aa52b419c2ef1065d7b9207c633d47554e13aa99f6c0b72" +// NewConfig parses a config file func NewConfig(config []byte) (*Moby, error) { m := Moby{} @@ -47,9 +53,11 @@ func NewConfig(config []byte) (*Moby, error) { return &m, nil } -func ConfigToRun(image *MobyImage) []string { +// ConfigToRun converts a config to a series of arguments for docker run +func ConfigToRun(order int, path string, image *MobyImage) []string { // riddler arguments - args := []string{"-v", "/var/run/docker.sock:/var/run/docker.sock", riddler, image.Image, "/containers/" + image.Name} + so := fmt.Sprintf("%03d", order) + args := []string{"-v", "/var/run/docker.sock:/var/run/docker.sock", riddler, image.Image, "/containers/" + path + "/" + so + "-" + image.Name} // docker arguments args = append(args, "--cap-drop", "all") for _, cap := range image.Capabilities { @@ -62,7 +70,12 @@ func ConfigToRun(image *MobyImage) []string { args = append(args, "--oom-score-adj", strconv.FormatInt(image.OomScoreAdj, 10)) } if image.NetworkMode != "" { - args = append(args, "--net", image.NetworkMode) + // TODO only "host" supported + args = append(args, "--net="+image.NetworkMode) + } + if image.Pid != "" { + // TODO only "host" supported + args = append(args, "--pid="+image.Pid) } for _, bind := range image.Binds { args = append(args, "-v", bind) @@ -75,7 +88,7 @@ func ConfigToRun(image *MobyImage) []string { return args } -func Filesystem(m *Moby) (*bytes.Buffer, error) { +func filesystem(m *Moby) (*bytes.Buffer, error) { buf := new(bytes.Buffer) tw := tar.NewWriter(buf) defer tw.Close() diff --git a/moby/main.go b/main.go similarity index 85% rename from moby/main.go rename to main.go index ec46cccc6..44b1075f3 100644 --- a/moby/main.go +++ b/main.go @@ -7,7 +7,9 @@ import ( "io" "io/ioutil" "log" + "os" "os/exec" + "path/filepath" "github.com/docker/moby/pkg/initrd" ) @@ -137,9 +139,18 @@ func build(configfile string) { buffer := bytes.NewBuffer(init) containers = append(containers, buffer) - for _, image := range m.System { - args := ConfigToRun(&image) - // get output tarball + for i, image := range m.System { + args := ConfigToRun(i, "system", &image) + out, err := dockerRun(args...) + if err != nil { + log.Fatalf("Failed to build container tarball: %v", err) + } + buffer := bytes.NewBuffer(out) + containers = append(containers, buffer) + } + + for i, image := range m.Daemon { + args := ConfigToRun(i, "daemon", &image) out, err := dockerRun(args...) if err != nil { log.Fatalf("Failed to build container tarball: %v", err) @@ -149,7 +160,7 @@ func build(configfile string) { } // add files - buffer, err = Filesystem(m) + buffer, err = filesystem(m) if err != nil { log.Fatalf("failed to add filesystem parts: %v", err) } @@ -160,12 +171,23 @@ func build(configfile string) { log.Fatalf("Failed to make initrd %v", err) } - err = outputs(m, bzimage.Bytes(), initrd.Bytes()) + base := filepath.Base(conf) + ext := filepath.Ext(conf) + if ext != "" { + base = base[:len(base)-len(ext)] + } + + err = outputs(m, base, bzimage.Bytes(), initrd.Bytes()) if err != nil { log.Fatalf("Error writing outputs: %v", err) } } +var conf = "moby.yaml" + func main() { - build("moby.yaml") + if len(os.Args) >= 2 { + conf = os.Args[1] + } + build(conf) } diff --git a/moby/moby.yaml b/moby.yaml similarity index 90% rename from moby/moby.yaml rename to moby.yaml index 3b8924fae..455026514 100644 --- a/moby/moby.yaml +++ b/moby.yaml @@ -1,11 +1,12 @@ kernel: "mobylinux/kernel:7fa748810d7866797fd807a5682d5cb3c9c98111" -init: "mobylinux/init:1d498af0fe0909b95eefc53ef6d4b43be82d77ae" +init: "mobylinux/init:99cd639fa724a706e2d85575cabc4b645b71a727" system: - name: binfmt image: "mobylinux/binfmt:a94e0587b702edaa95cc6f303464959d0eb2311c@sha256:432732b90cbe0498f5ca148d75b90bb1eabd8fbfe8c872df8b23906c225091b1" binds: - /proc/sys/fs/binfmt_misc:/binfmt_misc command: [/usr/bin/binfmt, -dir, /etc/binfmt.d/, -mount, /binfmt_misc] +daemon: - name: rngd image: "mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9@sha256:1c93c1db7196f6f71f8e300bc1d15f0376dd18e8891c8789d77c8ff19f3a9a92" capabilities: @@ -19,6 +20,7 @@ system: - CAP_CHOWN - CAP_SETUID - CAP_SETGID + - CAP_DAC_OVERRIDE network_mode: host files: - path: etc/docker/daemon.json diff --git a/moby/output.go b/output.go similarity index 78% rename from moby/output.go rename to output.go index dcd5fd2ec..34f8e92c5 100644 --- a/moby/output.go +++ b/output.go @@ -13,21 +13,21 @@ const ( efi = "mobylinux/mkimage-iso-efi:40f35270037dae95584324427e56f829756ff145@sha256:ae5b37ae560a5e030342f3d493d4ad611f2694bcd54eba86bf42ca069da986a7" ) -func outputs(m *Moby, bzimage []byte, initrd []byte) error { +func outputs(m *Moby, base string, bzimage []byte, initrd []byte) error { for _, o := range m.Outputs { switch o.Format { case "kernel+initrd": - err := outputKernelInitrd(bzimage, initrd) + err := outputKernelInitrd(base, bzimage, initrd) if err != nil { return fmt.Errorf("Error writing %s output: %v", o.Format, err) } case "iso-bios": - err := outputISO(bios, "mobylinux.iso", bzimage, initrd) + err := outputISO(bios, base+".iso", bzimage, initrd) if err != nil { return fmt.Errorf("Error writing %s output: %v", o.Format, err) } case "iso-efi": - err := outputISO(efi, "mobylinux-efi.iso", bzimage, initrd) + err := outputISO(efi, base+"-efi.iso", bzimage, initrd) if err != nil { return fmt.Errorf("Error writing %s output: %v", o.Format, err) } @@ -87,15 +87,15 @@ func outputISO(image, filename string, bzimage []byte, initrd []byte) error { return nil } -func outputKernelInitrd(bzimage []byte, initrd []byte) error { - err := ioutil.WriteFile("initrd.img", initrd, os.FileMode(0644)) +func outputKernelInitrd(base string, bzimage []byte, initrd []byte) error { + err := ioutil.WriteFile(base+"-initrd.img", initrd, os.FileMode(0644)) if err != nil { return err } - err = ioutil.WriteFile("bzImage", bzimage, os.FileMode(0644)) + err = ioutil.WriteFile(base+"-bzImage", bzimage, os.FileMode(0644)) if err != nil { return err } - fmt.Println("bzImage initrd.img") + fmt.Println(base + "-bzImage " + base + "-initrd.img") return nil } diff --git a/pkg/initrd/initrd.go b/pkg/initrd/initrd.go index 51495b2aa..ef470e9ed 100644 --- a/pkg/initrd/initrd.go +++ b/pkg/initrd/initrd.go @@ -112,10 +112,10 @@ func (w *Writer) Write(b []byte) (n int, e error) { } // Close closes the writer -func (initrd *Writer) Close() error { - err1 := initrd.cw.Close() - err2 := initrd.gw.Close() - err3 := initrd.pw.Close() +func (w *Writer) Close() error { + err1 := w.cw.Close() + err2 := w.gw.Close() + err3 := w.pw.Close() if err1 != nil { return err1 } diff --git a/scripts/hyperkit.sh b/scripts/hyperkit.sh index deb233086..4a6bc9c13 100755 --- a/scripts/hyperkit.sh +++ b/scripts/hyperkit.sh @@ -2,22 +2,27 @@ set -e -KERNEL="kernel/x86_64/vmlinuz64" -: ${INITRD:="alpine/initrd.img"} +PREFIX="moby" +[ $# -ge 1 ] && PREFIX="$1" + +KERNEL="$PREFIX-bzImage" +INITRD="$PREFIX-initrd.img" + CMDLINE="earlyprintk=serial console=ttyS0" +SLIRP_SOCK="$HOME/Library/Containers/com.docker.docker/Data/s50" + [ -f disk.img ] || dd if=/dev/zero of=disk.img bs=1048576 count=256 MEM="-m 1G" SMP="-c 1" -SLIRP_SOCK=$(mktemp) NET="-s 2:0,virtio-vpnkit,path=$SLIRP_SOCK" IMG_HDD="-s 4,virtio-blk,disk.img" PCI_DEV="-s 0:0,hostbridge -s 31,lpc" RND="-s 5,virtio-rnd" LPC_DEV="-l com1,stdio" -bin/vpnkit --ethernet $SLIRP_SOCK &>/dev/null & -trap "kill $!; rm $SLIRP_SOCK" EXIT +#bin/vpnkit --ethernet $SLIRP_SOCK &>/dev/null & +#trap "kill $!; rm $SLIRP_SOCK" EXIT bin/com.docker.hyperkit -A $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_HDD $RND -u -f kexec,$KERNEL,$INITRD,"$CMDLINE" diff --git a/test.yaml b/test.yaml new file mode 100644 index 000000000..bcd64adbf --- /dev/null +++ b/test.yaml @@ -0,0 +1,20 @@ +kernel: "mobylinux/kernel:7fa748810d7866797fd807a5682d5cb3c9c98111" +init: "mobylinux/init:99cd639fa724a706e2d85575cabc4b645b71a727" +system: + - name: binfmt + image: "mobylinux/binfmt:a94e0587b702edaa95cc6f303464959d0eb2311c@sha256:432732b90cbe0498f5ca148d75b90bb1eabd8fbfe8c872df8b23906c225091b1" + binds: + - /proc/sys/fs/binfmt_misc:/binfmt_misc + command: [/usr/bin/binfmt, -dir, /etc/binfmt.d/, -mount, /binfmt_misc] + - name: check + image: "mobylinux/check:6dd4f08c02c1f80cf38f63b30046e48b88d72743" + pid: host + capabilities: + - CAP_SYS_BOOT +files: + - path: etc/docker/daemon.json + contents: '{"debug": true}' +outputs: + - format: kernel+initrd + - format: iso-bios + - format: iso-efi diff --git a/tools/check/Dockerfile b/tools/check/Dockerfile new file mode 100644 index 000000000..8c6f44395 --- /dev/null +++ b/tools/check/Dockerfile @@ -0,0 +1,5 @@ +FROM alpine:3.5 +RUN apk update && apk upgrade && apk add --no-cache bash +ADD https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh /check-config.sh +ADD . ./ +ENTRYPOINT ["/bin/sh", "/check.sh"] diff --git a/tools/check/Makefile b/tools/check/Makefile new file mode 100644 index 000000000..960295fe5 --- /dev/null +++ b/tools/check/Makefile @@ -0,0 +1,29 @@ +.PHONY: tag push + +BASE=alpine:3.5 +IMAGE=check + +default: push + +hash: Dockerfile check.sh check-kernel-config.sh + DOCKER_CONTENT_TRUST=1 docker pull $(BASE) + tar cf - $^ | docker build --no-cache -t $(IMAGE):build - + docker run --rm --entrypoint=/bin/sh $(IMAGE):build -c "cat $^ /lib/apk/db/installed | sha1sum" | sed 's/ .*//' > hash + +push: hash + docker pull mobylinux/$(IMAGE):$(shell cat hash) || \ + (docker tag $(IMAGE):build mobylinux/$(IMAGE):$(shell cat hash) && \ + docker push mobylinux/$(IMAGE):$(shell cat hash)) + docker rmi $(IMAGE):build + rm -f hash + +tag: hash + docker pull mobylinux/$(IMAGE):$(shell cat hash) || \ + docker tag $(IMAGE):build mobylinux/$(IMAGE):$(shell cat hash) + docker rmi $(IMAGE):build + rm -f hash + +clean: + rm -f hash + +.DELETE_ON_ERROR: diff --git a/tools/check/check-kernel-config.sh b/tools/check/check-kernel-config.sh new file mode 100755 index 000000000..64bc89e45 --- /dev/null +++ b/tools/check/check-kernel-config.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +set -e + +echo "starting kernel config sanity test with /proc/config.gz" + +# decompress /proc/config.gz from the Moby host +zcat /proc/config.gz > unzipped_config + +kernelVersion="$(uname -r)" +kernelMajor="${kernelVersion%%.*}" +kernelMinor="${kernelVersion#$kernelMajor.}" +kernelMinor="${kernelMinor%%.*}" + +# Most tests against https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project +# Positive cases +cat unzipped_config | grep CONFIG_BUG=y +cat unzipped_config | grep CONFIG_DEBUG_KERNEL=y +cat unzipped_config | grep CONFIG_DEBUG_RODATA=y +cat unzipped_config | grep CONFIG_CC_STACKPROTECTOR=y +cat unzipped_config | grep CONFIG_CC_STACKPROTECTOR_STRONG=y +cat unzipped_config | grep CONFIG_STRICT_DEVMEM=y +cat unzipped_config | grep CONFIG_SYN_COOKIES=y +cat unzipped_config | grep CONFIG_DEBUG_CREDENTIALS=y +cat unzipped_config | grep CONFIG_DEBUG_NOTIFIERS=y +cat unzipped_config | grep CONFIG_DEBUG_LIST=y +cat unzipped_config | grep CONFIG_SECCOMP=y +cat unzipped_config | grep CONFIG_SECCOMP_FILTER=y +cat unzipped_config | grep CONFIG_SECURITY=y +cat unzipped_config | grep CONFIG_SECURITY_YAMA=y +cat unzipped_config | grep CONFIG_PANIC_ON_OOPS=y +cat unzipped_config | grep CONFIG_DEBUG_SET_MODULE_RONX=y +cat unzipped_config | grep CONFIG_SYN_COOKIES=y +cat unzipped_config | grep CONFIG_LEGACY_VSYSCALL_NONE=y +cat unzipped_config | grep CONFIG_RANDOMIZE_BASE=y + +# Conditional on kernel version +if [ "$kernelMajor" -ge 4 -a "$kernelMinor" -ge 5 ]; then + cat unzipped_config | grep CONFIG_IO_STRICT_DEVMEM=y + cat unzipped_config | grep CONFIG_UBSAN=y +fi +if [ "$kernelMajor" -ge 4 -a "$kernelMinor" -ge 7 ]; then + cat unzipped_config | grep CONFIG_SLAB_FREELIST_RANDOM=y +fi +if [ "$kernelMajor" -ge 4 -a "$kernelMinor" -ge 8 ]; then + cat unzipped_config | grep CONFIG_HARDENED_USERCOPY=y + cat unzipped_config | grep CONFIG_RANDOMIZE_MEMORY=y +fi + +# poisoning cannot be enabled in 4.4 +if [ "$kernelMajor" -ge 4 -a "$kernelMinor" -ge 9 ]; then + cat unzipped_config | grep CONFIG_PAGE_POISONING=y + cat unzipped_config | grep CONFIG_PAGE_POISONING_NO_SANITY=y + cat unzipped_config | grep CONFIG_PAGE_POISONING_ZERO=y +fi + +if [ "$kernelMajor" -ge 4 -a "$kernelMinor" -ge 10 ]; then + cat unzipped_config | grep CONFIG_BUG_ON_DATA_CORRUPTION=y +fi + +# Negative cases +cat unzipped_config | grep 'CONFIG_ACPI_CUSTOM_METHOD is not set' +cat unzipped_config | grep 'CONFIG_COMPAT_BRK is not set' +cat unzipped_config | grep 'CONFIG_DEVKMEM is not set' +cat unzipped_config | grep 'CONFIG_COMPAT_VDSO is not set' +cat unzipped_config | grep 'CONFIG_KEXEC is not set' +cat unzipped_config | grep 'CONFIG_HIBERNATION is not set' +cat unzipped_config | grep 'CONFIG_LEGACY_PTYS is not set' +cat unzipped_config | grep 'CONFIG_X86_X32 is not set' +cat unzipped_config | grep 'CONFIG_MODIFY_LDT_SYSCALL is not set' diff --git a/tools/check/check.sh b/tools/check/check.sh new file mode 100755 index 000000000..b33211fac --- /dev/null +++ b/tools/check/check.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +function failed { + printf "Moby test suite FAILED\n" + /sbin/poweroff -f +} + +/check-kernel-config.sh || failed +bash /check-config.sh || failed + +printf "Moby test suite PASSED\n" +/sbin/poweroff -f diff --git a/tools/go-compile/Dockerfile b/tools/go-compile/Dockerfile index d29708348..e4e6c1e30 100644 --- a/tools/go-compile/Dockerfile +++ b/tools/go-compile/Dockerfile @@ -1,8 +1,8 @@ -FROM golang:1.8-alpine -RUN apk update && apk add --no-cache build-base git - +FROM alpine:3.5 +RUN apk update && apk add --no-cache build-base git go +ENV GOPATH=/go PATH=$PATH:/go/bin RUN go get -u github.com/golang/lint/golint -COPY compile.sh /usr/bin/ +COPY . ./ -ENTRYPOINT ["/usr/bin/compile.sh"] +ENTRYPOINT ["/compile.sh"] diff --git a/tools/go-compile/Makefile b/tools/go-compile/Makefile index 7e3528196..fa9f40f1b 100644 --- a/tools/go-compile/Makefile +++ b/tools/go-compile/Makefile @@ -1,6 +1,6 @@ .PHONY: tag push -BASE=golang:1.8-alpine +BASE=alpine:3.5 IMAGE=go-compile default: push @@ -8,7 +8,7 @@ default: push hash: Dockerfile compile.sh DOCKER_CONTENT_TRUST=1 docker pull $(BASE) tar cf - $^ | docker build --no-cache -t $(IMAGE):build - - docker run --rm --entrypoint=/bin/sh $(IMAGE):build -c 'cat /usr/local/go/bin/go /lib/apk/db/installed /go/bin/golint /usr/bin/compile.sh | sha1sum' | sed 's/ .*//' > hash + docker run --rm --entrypoint=/bin/sh $(IMAGE):build -c "cat $^ /lib/apk/db/installed /go/bin/golint | sha1sum" | sed 's/ .*//' > hash push: hash docker pull mobylinux/$(IMAGE):$(shell cat hash) || \ diff --git a/tools/go-compile/compile.sh b/tools/go-compile/compile.sh index ab2f288bf..ab86c88d8 100755 --- a/tools/go-compile/compile.sh +++ b/tools/go-compile/compile.sh @@ -3,7 +3,6 @@ # This is designed to compile a single package to a single binary # so it makes some assumptions about things to simplify config # to output a single binary (in a tarball) just use -o file -# use --docker to output a tarball for input to docker build - set -e @@ -23,6 +22,10 @@ do mkdir -p "$(dirname $2)" shift ;; + --package) + package="$2" + shift + ;; *) echo "Unknown option $1" exit 1 @@ -33,7 +36,7 @@ done [ $# -gt 0 ] && usage [ -z "$out" ] && usage -package=$(basename "$out") +[ -z "$package" ] && package=$(basename "$out") dir="$GOPATH/src/$package" @@ -46,16 +49,21 @@ cd $dir # lint before building >&2 echo "gofmt..." -test -z $(gofmt -s -l .| grep -v .pb. | grep -v */vendor/ | tee /dev/stderr) +test -z $(gofmt -s -l .| grep -v .pb. | grep -v vendor/ | tee /dev/stderr) >&2 echo "govet..." -test -z $(go tool vet -printf=false . 2>&1 | grep -v */vendor/ | tee /dev/stderr) +test -z $(GOOS=linux go tool vet -printf=false . 2>&1 | grep -v vendor/ | tee /dev/stderr) >&2 echo "golint..." test -z $(find . -type f -name "*.go" -not -path "*/vendor/*" -not -name "*.pb.*" -exec golint {} \; | tee /dev/stderr) >&2 echo "go build..." -go build -o $out -buildmode pie --ldflags '-extldflags "-static"' "$package" +if [ "$GOOS" = "darwin" ] +then + go build -o $out "$package" +else + go build -o $out -buildmode pie --ldflags '-extldflags "-static"' "$package" +fi tar cf - $out diff --git a/base/qemu/Dockerfile b/tools/qemu/Dockerfile similarity index 100% rename from base/qemu/Dockerfile rename to tools/qemu/Dockerfile diff --git a/base/qemu/Makefile b/tools/qemu/Makefile similarity index 100% rename from base/qemu/Makefile rename to tools/qemu/Makefile diff --git a/base/qemu/qemu.sh b/tools/qemu/qemu.sh similarity index 94% rename from base/qemu/qemu.sh rename to tools/qemu/qemu.sh index 615d2f8fd..a1353771d 100755 --- a/base/qemu/qemu.sh +++ b/tools/qemu/qemu.sh @@ -14,7 +14,7 @@ TGZ="$(find . -name '*.tgz' -or -name '*.tar.gz')" ISO="$(find . -name '*.iso')" RAW="$(find . -name '*.raw')" INITRD="$(find . -name '*.img')" -KERNEL="$(find . -name vmlinuz64 -or -name bzImage)" +KERNEL="$(find . -name vmlinuz64 -or -name '*bzImage')" if [ -n "$ISO" ] then