зеркало из https://github.com/microsoft/docker.git
Merge pull request #27519 from justincormack/proxy-build
Build docker-proxy from git checkout like other external binaries
This commit is contained in:
Коммит
36f47aa252
|
@ -222,10 +222,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
|
||||||
hello-world:latest@sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7
|
hello-world:latest@sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7
|
||||||
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
||||||
|
|
||||||
# Install tomlv, runc, containerd and grimes
|
# Install tomlv, runc, containerd, grimes, docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh tomlv runc containerd grimes
|
RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy
|
||||||
|
|
||||||
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
||||||
ENTRYPOINT ["hack/dind"]
|
ENTRYPOINT ["hack/dind"]
|
||||||
|
|
|
@ -165,10 +165,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
|
||||||
aarch64/hello-world:latest@sha256:65a4a158587b307bb02db4de41b836addb0c35175bdc801367b1ac1ddeb9afda
|
aarch64/hello-world:latest@sha256:65a4a158587b307bb02db4de41b836addb0c35175bdc801367b1ac1ddeb9afda
|
||||||
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
||||||
|
|
||||||
# Install tomlv, runc, containerd and grimes
|
# Install tomlv, runc, containerd, grimes, docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh tomlv runc containerd grimes
|
RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy
|
||||||
|
|
||||||
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
||||||
ENTRYPOINT ["hack/dind"]
|
ENTRYPOINT ["hack/dind"]
|
||||||
|
|
|
@ -164,10 +164,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
|
||||||
armhf/hello-world:latest@sha256:161dcecea0225975b2ad5f768058212c1e0d39e8211098666ffa1ac74cfb7791
|
armhf/hello-world:latest@sha256:161dcecea0225975b2ad5f768058212c1e0d39e8211098666ffa1ac74cfb7791
|
||||||
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
||||||
|
|
||||||
# Install tomlv, runc, containerd and grimes
|
# Install tomlv, runc, containerd, grimes, docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh tomlv runc containerd grimes
|
RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy
|
||||||
|
|
||||||
ENTRYPOINT ["hack/dind"]
|
ENTRYPOINT ["hack/dind"]
|
||||||
|
|
||||||
|
|
|
@ -183,10 +183,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
|
||||||
ppc64le/hello-world:latest@sha256:186a40a9a02ca26df0b6c8acdfb8ac2f3ae6678996a838f977e57fac9d963974
|
ppc64le/hello-world:latest@sha256:186a40a9a02ca26df0b6c8acdfb8ac2f3ae6678996a838f977e57fac9d963974
|
||||||
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
||||||
|
|
||||||
# Install tomlv, runc, containerd and grimes
|
# Install tomlv, runc, containerd, grimes, docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh tomlv runc containerd grimes
|
RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy
|
||||||
|
|
||||||
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
||||||
ENTRYPOINT ["hack/dind"]
|
ENTRYPOINT ["hack/dind"]
|
||||||
|
|
|
@ -175,10 +175,10 @@ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \
|
||||||
s390x/hello-world:latest@sha256:780d80b3a7677c3788c0d5cd9168281320c8d4a6d9183892d8ee5cdd610f5699
|
s390x/hello-world:latest@sha256:780d80b3a7677c3788c0d5cd9168281320c8d4a6d9183892d8ee5cdd610f5699
|
||||||
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
# See also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
|
||||||
|
|
||||||
# Install tomlv, runc, containerd and grimes
|
# Install tomlv, runc, containerd, grimes, docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh tomlv runc containerd grimes
|
RUN /tmp/install-binaries.sh tomlv runc containerd grimes proxy
|
||||||
|
|
||||||
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
# Wrap all commands in the "docker-in-docker" script to allow nested containers
|
||||||
ENTRYPOINT ["hack/dind"]
|
ENTRYPOINT ["hack/dind"]
|
||||||
|
|
|
@ -56,10 +56,10 @@ ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||||
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
|
||||||
ENV CGO_LDFLAGS -L/lib
|
ENV CGO_LDFLAGS -L/lib
|
||||||
|
|
||||||
# Install runc, containerd and grimes
|
# Install runc, containerd, grimes and docker-proxy
|
||||||
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
# Please edit hack/dockerfile/install-binaries.sh to update them.
|
||||||
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
|
||||||
RUN /tmp/install-binaries.sh runc containerd grimes
|
RUN /tmp/install-binaries.sh runc containerd grimes proxy
|
||||||
|
|
||||||
ENV AUTO_GOPATH 1
|
ENV AUTO_GOPATH 1
|
||||||
WORKDIR /usr/src/docker
|
WORKDIR /usr/src/docker
|
||||||
|
|
|
@ -124,9 +124,6 @@ clean() {
|
||||||
findArgs+=( -path "vendor/src/$import" )
|
findArgs+=( -path "vendor/src/$import" )
|
||||||
done
|
done
|
||||||
|
|
||||||
# The docker proxy command is built from libnetwork
|
|
||||||
findArgs+=( -or -path vendor/src/github.com/docker/libnetwork/cmd/proxy )
|
|
||||||
|
|
||||||
local IFS=$'\n'
|
local IFS=$'\n'
|
||||||
local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
|
local prune=( $($find vendor -depth -type d -not '(' "${findArgs[@]}" ')') )
|
||||||
unset IFS
|
unset IFS
|
||||||
|
|
|
@ -6,6 +6,7 @@ TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
|
||||||
RUNC_COMMIT=02f8fa7863dd3f82909a73e2061897828460d52f
|
RUNC_COMMIT=02f8fa7863dd3f82909a73e2061897828460d52f
|
||||||
CONTAINERD_COMMIT=52ef1ceb4b660c42cf4ea9013180a5663968d4c7
|
CONTAINERD_COMMIT=52ef1ceb4b660c42cf4ea9013180a5663968d4c7
|
||||||
GRIMES_COMMIT=74341e923bdf06cfb6b70cf54089c4d3ac87ec2d
|
GRIMES_COMMIT=74341e923bdf06cfb6b70cf54089c4d3ac87ec2d
|
||||||
|
LIBNETWORK_COMMIT=0f534354b813003a754606689722fe253101bc4e
|
||||||
|
|
||||||
export GOPATH="$(mktemp -d)"
|
export GOPATH="$(mktemp -d)"
|
||||||
|
|
||||||
|
@ -66,8 +67,16 @@ do
|
||||||
cp init /usr/local/bin/docker-init
|
cp init /usr/local/bin/docker-init
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
proxy)
|
||||||
|
echo "Install docker-proxy version $LIBNETWORK_COMMIT"
|
||||||
|
git clone https://github.com/docker/libnetwork.git "$GOPATH/src/github.com/docker/libnetwork"
|
||||||
|
cd "$GOPATH/src/github.com/docker/libnetwork"
|
||||||
|
git checkout -q "$LIBNETWORK_COMMIT"
|
||||||
|
CGO_ENABLED=0 go build -v -o /usr/local/bin/docker-proxy github.com/docker/libnetwork/cmd/proxy
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo echo "Usage: $0 [tomlv|runc|containerd|grimes]"
|
echo echo "Usage: $0 [tomlv|runc|containerd|grimes|proxy]"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -257,7 +257,7 @@ copy_binaries() {
|
||||||
if [ "$(go env GOOS)/$(go env GOARCH)" == "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" ]; then
|
if [ "$(go env GOOS)/$(go env GOARCH)" == "$(go env GOHOSTOS)/$(go env GOHOSTARCH)" ]; then
|
||||||
if [ -x /usr/local/bin/docker-runc ]; then
|
if [ -x /usr/local/bin/docker-runc ]; then
|
||||||
echo "Copying nested executables into $dir"
|
echo "Copying nested executables into $dir"
|
||||||
for file in containerd containerd-shim containerd-ctr runc init; do
|
for file in containerd containerd-shim containerd-ctr runc init proxy; do
|
||||||
cp `which "docker-$file"` "$dir/"
|
cp `which "docker-$file"` "$dir/"
|
||||||
if [ "$2" == "hash" ]; then
|
if [ "$2" == "hash" ]; then
|
||||||
hash_files "$dir/docker-$file"
|
hash_files "$dir/docker-$file"
|
||||||
|
|
|
@ -24,11 +24,12 @@ override_dh_auto_install:
|
||||||
mkdir -p debian/docker-engine/usr/bin
|
mkdir -p debian/docker-engine/usr/bin
|
||||||
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-client/docker)" debian/docker-engine/usr/bin/docker
|
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-client/docker)" debian/docker-engine/usr/bin/docker
|
||||||
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/dockerd)" debian/docker-engine/usr/bin/dockerd
|
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/dockerd)" debian/docker-engine/usr/bin/dockerd
|
||||||
cp -aT "$$(readlink -f bundles/$(VERSION)/dynbinary-daemon/docker-proxy)" debian/docker-engine/usr/bin/docker-proxy
|
cp -aT /usr/local/bin/docker-proxy debian/docker-engine/usr/bin/docker-proxy
|
||||||
cp -aT /usr/local/bin/docker-containerd debian/docker-engine/usr/bin/docker-containerd
|
cp -aT /usr/local/bin/docker-containerd debian/docker-engine/usr/bin/docker-containerd
|
||||||
cp -aT /usr/local/bin/docker-containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim
|
cp -aT /usr/local/bin/docker-containerd-shim debian/docker-engine/usr/bin/docker-containerd-shim
|
||||||
cp -aT /usr/local/bin/docker-containerd-ctr debian/docker-engine/usr/bin/docker-containerd-ctr
|
cp -aT /usr/local/bin/docker-containerd-ctr debian/docker-engine/usr/bin/docker-containerd-ctr
|
||||||
cp -aT /usr/local/bin/docker-runc debian/docker-engine/usr/bin/docker-runc
|
cp -aT /usr/local/bin/docker-runc debian/docker-engine/usr/bin/docker-runc
|
||||||
|
cp -aT /usr/local/bin/docker-init debian/docker-engine/usr/bin/docker-init
|
||||||
mkdir -p debian/docker-engine/usr/lib/docker
|
mkdir -p debian/docker-engine/usr/lib/docker
|
||||||
|
|
||||||
override_dh_installinit:
|
override_dh_installinit:
|
||||||
|
|
|
@ -126,7 +126,9 @@ export DOCKER_GITCOMMIT=%{_gitcommit}
|
||||||
install -d $RPM_BUILD_ROOT/%{_bindir}
|
install -d $RPM_BUILD_ROOT/%{_bindir}
|
||||||
install -p -m 755 bundles/%{_origversion}/dynbinary-client/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
|
install -p -m 755 bundles/%{_origversion}/dynbinary-client/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker
|
||||||
install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/dockerd-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/dockerd
|
install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/dockerd-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/dockerd
|
||||||
install -p -m 755 bundles/%{_origversion}/dynbinary-daemon/docker-proxy-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker-proxy
|
|
||||||
|
# install proxy
|
||||||
|
install -p -m 755 /usr/local/bin/docker-proxy $RPM_BUILD_ROOT/%{_bindir}/docker-proxy
|
||||||
|
|
||||||
# install containerd
|
# install containerd
|
||||||
install -p -m 755 /usr/local/bin/docker-containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd
|
install -p -m 755 /usr/local/bin/docker-containerd $RPM_BUILD_ROOT/%{_bindir}/docker-containerd
|
||||||
|
@ -136,6 +138,9 @@ install -p -m 755 /usr/local/bin/docker-containerd-ctr $RPM_BUILD_ROOT/%{_bindir
|
||||||
# install runc
|
# install runc
|
||||||
install -p -m 755 /usr/local/bin/docker-runc $RPM_BUILD_ROOT/%{_bindir}/docker-runc
|
install -p -m 755 /usr/local/bin/docker-runc $RPM_BUILD_ROOT/%{_bindir}/docker-runc
|
||||||
|
|
||||||
|
# install grimes
|
||||||
|
install -p -m 755 /usr/local/bin/docker-init $RPM_BUILD_ROOT/%{_bindir}/docker-init
|
||||||
|
|
||||||
# install udev rules
|
# install udev rules
|
||||||
install -d $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d
|
install -d $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d
|
||||||
install -p -m 644 contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d/80-docker.rules
|
install -p -m 644 contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d/80-docker.rules
|
||||||
|
|
|
@ -9,8 +9,5 @@ set -e
|
||||||
export BINARY_SHORT_NAME="$DOCKER_DAEMON_BINARY_NAME"
|
export BINARY_SHORT_NAME="$DOCKER_DAEMON_BINARY_NAME"
|
||||||
export SOURCE_PATH='./cmd/dockerd'
|
export SOURCE_PATH='./cmd/dockerd'
|
||||||
source "${MAKEDIR}/.binary"
|
source "${MAKEDIR}/.binary"
|
||||||
export BINARY_SHORT_NAME="$DOCKER_PROXY_BINARY_NAME"
|
|
||||||
export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy'
|
|
||||||
source "${MAKEDIR}/.binary"
|
|
||||||
copy_binaries "$DEST" 'hash'
|
copy_binaries "$DEST" 'hash'
|
||||||
)
|
)
|
||||||
|
|
|
@ -73,8 +73,8 @@ set -e
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||||
# Install runc and containerd
|
# Install runc, containerd, proxy and grimes
|
||||||
RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic
|
RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic proxy grimes
|
||||||
EOF
|
EOF
|
||||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||||
RUN cp -aL hack/make/.build-deb debian
|
RUN cp -aL hack/make/.build-deb debian
|
||||||
|
|
|
@ -93,8 +93,8 @@ set -e
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
cat >> "$DEST/$version/Dockerfile.build" <<-EOF
|
||||||
# Install runc and containerd
|
# Install runc, containerd, proxy and grimes
|
||||||
RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic
|
RUN ./hack/dockerfile/install-binaries.sh runc-dynamic containerd-dynamic proxy grimes
|
||||||
EOF
|
EOF
|
||||||
if [[ "$VERSION" == *-dev ]] || [ -n "$(git status --porcelain)" ]; then
|
if [[ "$VERSION" == *-dev ]] || [ -n "$(git status --porcelain)" ]; then
|
||||||
echo 'ENV DOCKER_EXPERIMENTAL 1' >> "$DEST/$version/Dockerfile.build"
|
echo 'ENV DOCKER_EXPERIMENTAL 1' >> "$DEST/$version/Dockerfile.build"
|
||||||
|
|
|
@ -9,8 +9,4 @@ set -e
|
||||||
export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
|
export BUILDFLAGS=( "${BUILDFLAGS[@]/netgo /}" ) # disable netgo, since we don't need it for a dynamic binary
|
||||||
export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
|
export BUILDFLAGS=( "${BUILDFLAGS[@]/static_build /}" ) # we're not building a "static" binary here
|
||||||
source "${MAKEDIR}/.binary"
|
source "${MAKEDIR}/.binary"
|
||||||
export BINARY_SHORT_NAME='docker-proxy'
|
|
||||||
export SOURCE_PATH='./vendor/src/github.com/docker/libnetwork/cmd/proxy'
|
|
||||||
export LDFLAGS_STATIC_DOCKER='-linkmode=external'
|
|
||||||
source "${MAKEDIR}/.binary"
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
f := os.NewFile(3, "signal-parent")
|
|
||||||
host, container := parseHostContainerAddrs()
|
|
||||||
|
|
||||||
p, err := NewProxy(host, container)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(f, "1\n%s", err)
|
|
||||||
f.Close()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
go handleStopSignals(p)
|
|
||||||
fmt.Fprint(f, "0\n")
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
// Run will block until the proxy stops
|
|
||||||
p.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, container net.Addr) {
|
|
||||||
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")
|
|
||||||
)
|
|
||||||
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
switch *proto {
|
|
||||||
case "tcp":
|
|
||||||
host = &net.TCPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
|
|
||||||
container = &net.TCPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
|
|
||||||
case "udp":
|
|
||||||
host = &net.UDPAddr{IP: net.ParseIP(*hostIP), Port: *hostPort}
|
|
||||||
container = &net.UDPAddr{IP: net.ParseIP(*containerIP), Port: *containerPort}
|
|
||||||
default:
|
|
||||||
log.Fatalf("unsupported protocol %s", *proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
return host, container
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleStopSignals(p Proxy) {
|
|
||||||
s := make(chan os.Signal, 10)
|
|
||||||
signal.Notify(s, os.Interrupt, syscall.SIGTERM)
|
|
||||||
|
|
||||||
for range s {
|
|
||||||
p.Close()
|
|
||||||
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
// docker-proxy provides a network Proxy interface and implementations for TCP
|
|
||||||
// and UDP.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProxy creates a Proxy according to the specified frontendAddr and backendAddr.
|
|
||||||
func NewProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
|
|
||||||
switch frontendAddr.(type) {
|
|
||||||
case *net.UDPAddr:
|
|
||||||
return NewUDPProxy(frontendAddr.(*net.UDPAddr), backendAddr.(*net.UDPAddr))
|
|
||||||
case *net.TCPAddr:
|
|
||||||
return NewTCPProxy(frontendAddr.(*net.TCPAddr), backendAddr.(*net.TCPAddr))
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("Unsupported protocol"))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.TCPListener
|
|
||||||
frontendAddr *net.TCPAddr
|
|
||||||
backendAddr *net.TCPAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTCPProxy creates a new TCPProxy.
|
|
||||||
func NewTCPProxy(frontendAddr, backendAddr *net.TCPAddr) (*TCPProxy, error) {
|
|
||||||
listener, err := net.ListenTCP("tcp", frontendAddr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// 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().(*net.TCPAddr),
|
|
||||||
backendAddr: backendAddr,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (proxy *TCPProxy) clientLoop(client *net.TCPConn, quit chan bool) {
|
|
||||||
backend, err := net.DialTCP("tcp", nil, proxy.backendAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Can't forward traffic to backend tcp/%v: %s\n", proxy.backendAddr, err)
|
|
||||||
client.Close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
var broker = func(to, from *net.TCPConn) {
|
|
||||||
if _, err := io.Copy(to, from); err != nil {
|
|
||||||
// If the socket we are writing to is shutdown with
|
|
||||||
// SHUT_WR, forward it to the other end of the pipe:
|
|
||||||
if err, ok := err.(*net.OpError); ok && err.Err == syscall.EPIPE {
|
|
||||||
from.CloseWrite()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
to.CloseRead()
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Add(2)
|
|
||||||
go broker(client, backend)
|
|
||||||
go broker(backend, client)
|
|
||||||
|
|
||||||
finish := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
wg.Wait()
|
|
||||||
close(finish)
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-quit:
|
|
||||||
case <-finish:
|
|
||||||
}
|
|
||||||
client.Close()
|
|
||||||
backend.Close()
|
|
||||||
<-finish
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 proxy.clientLoop(client.(*net.TCPConn), 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 }
|
|
|
@ -1,168 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
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 *net.UDPConn
|
|
||||||
frontendAddr *net.UDPAddr
|
|
||||||
backendAddr *net.UDPAddr
|
|
||||||
connTrackTable connTrackMap
|
|
||||||
connTrackLock sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUDPProxy creates a new UDPProxy.
|
|
||||||
func NewUDPProxy(frontendAddr, backendAddr *net.UDPAddr) (*UDPProxy, error) {
|
|
||||||
listener, err := net.ListenUDP("udp", frontendAddr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &UDPProxy{
|
|
||||||
listener: listener,
|
|
||||||
frontendAddr: listener.LocalAddr().(*net.UDPAddr),
|
|
||||||
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 udp/%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")
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче