mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
* Improved Makefile * Multiarch Docker build (amd64, arm64 and armv7) * closes #104
This commit is contained in:
parent
e97fb38bd5
commit
54716f7f53
@ -10,7 +10,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install Dependencies
|
name: Install Dependencies
|
||||||
command: |
|
command: |
|
||||||
make dep
|
make build-dependencies
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: go-mod-latest-v4-{{ checksum "go.sum" }}
|
key: go-mod-latest-v4-{{ checksum "go.sum" }}
|
||||||
paths:
|
paths:
|
||||||
@ -20,19 +20,26 @@ jobs:
|
|||||||
command: |
|
command: |
|
||||||
VERSION=$CIRCLE_BRANCH
|
VERSION=$CIRCLE_BRANCH
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
||||||
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build
|
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build-amd64
|
||||||
- run:
|
- run:
|
||||||
name: Install Cross-Platform Dependencies
|
name: Install Cross-Platform Dependencies
|
||||||
command: |
|
command: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
||||||
|
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
|
||||||
sudo ln -s /usr/include/asm-generic /usr/include/asm
|
sudo ln -s /usr/include/asm-generic /usr/include/asm
|
||||||
|
- run:
|
||||||
|
name: Build ARM64
|
||||||
|
command: |
|
||||||
|
VERSION=$CIRCLE_BRANCH
|
||||||
|
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
||||||
|
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build-arm64
|
||||||
- run:
|
- run:
|
||||||
name: Build ARM
|
name: Build ARM
|
||||||
command: |
|
command: |
|
||||||
VERSION=$CIRCLE_BRANCH
|
VERSION=$CIRCLE_BRANCH
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
||||||
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build-cross-plat
|
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build-arm
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ~/repo/dist
|
path: ~/repo/dist
|
||||||
- run:
|
- run:
|
||||||
@ -44,7 +51,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.17
|
- image: cimg/go:1.19
|
||||||
build-116: # just to validate compatibility with minimum go version
|
build-116: # just to validate compatibility with minimum go version
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
@ -54,13 +61,13 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Install Dependencies
|
name: Install Dependencies
|
||||||
command: |
|
command: |
|
||||||
make dep
|
make build-dependencies
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: go-mod-116-v4-{{ checksum "go.sum" }}
|
key: go-mod-116-v4-{{ checksum "go.sum" }}
|
||||||
paths:
|
paths:
|
||||||
- "~/go/pkg/mod"
|
- "~/go/pkg/mod"
|
||||||
- run:
|
- run:
|
||||||
name: Build AMD64
|
name: Build
|
||||||
command: |
|
command: |
|
||||||
VERSION=$CIRCLE_BRANCH
|
VERSION=$CIRCLE_BRANCH
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
||||||
@ -68,54 +75,6 @@ jobs:
|
|||||||
working_directory: ~/repo116
|
working_directory: ~/repo116
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/go:1.16
|
- image: cimg/go:1.16
|
||||||
build-legacy:
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- go-mod-legacy-v4-{{ checksum "go.sum" }}
|
|
||||||
- run:
|
|
||||||
name: Install Dependencies
|
|
||||||
command: |
|
|
||||||
make dep
|
|
||||||
- save_cache:
|
|
||||||
key: go-mod-legacy-v4-{{ checksum "go.sum" }}
|
|
||||||
paths:
|
|
||||||
- "/go/pkg/mod"
|
|
||||||
- run:
|
|
||||||
name: Build AMD64
|
|
||||||
command: |
|
|
||||||
VERSION=$CIRCLE_BRANCH
|
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
|
||||||
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build
|
|
||||||
- run:
|
|
||||||
name: Install Cross-Platform Dependencies
|
|
||||||
command: |
|
|
||||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
|
|
||||||
sudo ln -s /usr/include/asm-generic /usr/include/asm
|
|
||||||
- run:
|
|
||||||
name: Build ARM
|
|
||||||
command: |
|
|
||||||
VERSION=$CIRCLE_BRANCH
|
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then VERSION=$CIRCLE_TAG; fi
|
|
||||||
make ENV_BUILD_IDENTIFIER=$VERSION ENV_BUILD_VERSION=$(echo $CIRCLE_SHA1 | cut -c1-7) build-cross-plat
|
|
||||||
- store_artifacts:
|
|
||||||
path: ~/repolegacy/dist
|
|
||||||
- run:
|
|
||||||
name: "Publish Legacy Release on GitHub"
|
|
||||||
command: |
|
|
||||||
rm ~/repolegacy/dist/wg-portal.service ~/repolegacy/dist/wg-portal.env
|
|
||||||
mv ~/repolegacy/dist/wg-portal-amd64 ~/repolegacy/dist/wg-portal-amd64-legacy
|
|
||||||
mv ~/repolegacy/dist/wg-portal-arm ~/repolegacy/dist/wg-portal-arm-legacy
|
|
||||||
mv ~/repolegacy/dist/wg-portal-arm64 ~/repolegacy/dist/wg-portal-arm64-legacy
|
|
||||||
if [ ! -z "${CIRCLE_TAG}" ]; then
|
|
||||||
go get github.com/tcnksm/ghr
|
|
||||||
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} $CIRCLE_TAG ~/repolegacy/dist
|
|
||||||
fi
|
|
||||||
working_directory: ~/repolegacy
|
|
||||||
docker:
|
|
||||||
- image: circleci/golang:1.16-stretch
|
|
||||||
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
build-and-release:
|
build-and-release:
|
||||||
@ -126,12 +85,6 @@ workflows:
|
|||||||
tags:
|
tags:
|
||||||
only: /^v.*/
|
only: /^v.*/
|
||||||
- build-116:
|
- build-116:
|
||||||
requires:
|
|
||||||
- build-latest
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: /^v.*/
|
|
||||||
- build-legacy:
|
|
||||||
requires:
|
requires:
|
||||||
- build-latest
|
- build-latest
|
||||||
filters:
|
filters:
|
||||||
|
30
.github/workflows/docker-publish.yml
vendored
30
.github/workflows/docker-publish.yml
vendored
@ -24,7 +24,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Get Version
|
- name: Get Version
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -35,14 +41,14 @@ jobs:
|
|||||||
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Extract metadata (tags, labels) for Docker
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v3
|
uses: docker/metadata-action@v4
|
||||||
with:
|
with:
|
||||||
images: h44z/wg-portal
|
images: h44z/wg-portal
|
||||||
flavor: |
|
flavor: |
|
||||||
@ -55,12 +61,13 @@ jobs:
|
|||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
build-args: |
|
build-args: |
|
||||||
BUILD_IDENTIFIER=${{ steps.get_version.outputs.identifier }}
|
BUILD_IDENTIFIER=${{ steps.get_version.outputs.identifier }}
|
||||||
BUILD_VERSION=${{ steps.get_version.outputs.hash }}
|
BUILD_VERSION=${{ steps.get_version.outputs.hash }}
|
||||||
@ -74,7 +81,13 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Get Version
|
- name: Get Version
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -87,7 +100,7 @@ jobs:
|
|||||||
# https://github.com/docker/login-action
|
# https://github.com/docker/login-action
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@ -97,7 +110,7 @@ jobs:
|
|||||||
# https://github.com/docker/metadata-action
|
# https://github.com/docker/metadata-action
|
||||||
- name: Extract Docker metadata
|
- name: Extract Docker metadata
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@v3
|
uses: docker/metadata-action@v4
|
||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
flavor: |
|
flavor: |
|
||||||
@ -112,12 +125,13 @@ jobs:
|
|||||||
# Build and push Docker image with Buildx (don't push on PR)
|
# Build and push Docker image with Buildx (don't push on PR)
|
||||||
# https://github.com/docker/build-push-action
|
# https://github.com/docker/build-push-action
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
build-args: |
|
build-args: |
|
||||||
BUILD_IDENTIFIER=${{ steps.get_version.outputs.identifier }}
|
BUILD_IDENTIFIER=${{ steps.get_version.outputs.identifier }}
|
||||||
BUILD_VERSION=${{ steps.get_version.outputs.hash }}
|
BUILD_VERSION=${{ steps.get_version.outputs.hash }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,6 +28,7 @@
|
|||||||
out/
|
out/
|
||||||
dist/
|
dist/
|
||||||
data/
|
data/
|
||||||
|
docker_images/
|
||||||
ssh.key
|
ssh.key
|
||||||
.testCoverage.txt
|
.testCoverage.txt
|
||||||
wg_portal.db
|
wg_portal.db
|
||||||
|
22
Dockerfile
22
Dockerfile
@ -12,6 +12,10 @@ ENV ENV_BUILD_IDENTIFIER=$BUILD_IDENTIFIER
|
|||||||
ARG BUILD_VERSION
|
ARG BUILD_VERSION
|
||||||
ENV ENV_BUILD_VERSION=$BUILD_VERSION
|
ENV ENV_BUILD_VERSION=$BUILD_VERSION
|
||||||
|
|
||||||
|
# populated by BuildKit
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
ENV ENV_TARGETPLATFORM=$TARGETPLATFORM
|
||||||
|
|
||||||
RUN mkdir /build
|
RUN mkdir /build
|
||||||
|
|
||||||
# Copy the source from the current directory to the Working Directory inside the container
|
# Copy the source from the current directory to the Working Directory inside the container
|
||||||
@ -20,16 +24,8 @@ ADD . /build/
|
|||||||
# Set the Current Working Directory inside the container
|
# Set the Current Working Directory inside the container
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
# Workaround for failing travis-ci builds
|
|
||||||
RUN rm -rf ~/go; rm -rf go.sum
|
|
||||||
|
|
||||||
# Download dependencies
|
|
||||||
RUN curl -L https://git.prolicht.digital/pub/healthcheck/-/releases/v1.0.1/downloads/binaries/hc -o /build/hc; \
|
|
||||||
chmod +rx /build/hc; \
|
|
||||||
echo "Building version: $ENV_BUILD_IDENTIFIER-$ENV_BUILD_VERSION"
|
|
||||||
|
|
||||||
# Build the Go app
|
# Build the Go app
|
||||||
RUN go clean -modcache; go mod tidy; make build-docker
|
RUN echo "Building version '$ENV_BUILD_IDENTIFIER-$ENV_BUILD_VERSION' for platform $ENV_TARGETPLATFORM"; make build
|
||||||
|
|
||||||
######-
|
######-
|
||||||
# Here starts the main image
|
# Here starts the main image
|
||||||
@ -44,16 +40,14 @@ COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|||||||
COPY --from=builder /etc/passwd /etc/passwd
|
COPY --from=builder /etc/passwd /etc/passwd
|
||||||
COPY --from=builder /etc/group /etc/group
|
COPY --from=builder /etc/group /etc/group
|
||||||
|
|
||||||
# Import healthcheck binary
|
|
||||||
COPY --from=builder /build/hc /app/hc
|
|
||||||
|
|
||||||
# Copy binaries
|
# Copy binaries
|
||||||
COPY --from=builder /build/dist/wgportal /app/wgportal
|
COPY --from=builder /build/dist/wg-portal /app/wg-portal
|
||||||
|
COPY --from=builder /build/dist/hc /app/hc
|
||||||
|
|
||||||
# Set the Current Working Directory inside the container
|
# Set the Current Working Directory inside the container
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Command to run the executable
|
# Command to run the executable
|
||||||
CMD [ "/app/wgportal" ]
|
CMD [ "/app/wg-portal" ]
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 CMD [ "/app/hc", "http://localhost:11223/health" ]
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 CMD [ "/app/hc", "http://localhost:11223/health" ]
|
||||||
|
159
Makefile
159
Makefile
@ -6,62 +6,119 @@ BUILDDIR=dist
|
|||||||
BINARIES=$(subst cmd/,,$(wildcard cmd/*))
|
BINARIES=$(subst cmd/,,$(wildcard cmd/*))
|
||||||
IMAGE=h44z/wg-portal
|
IMAGE=h44z/wg-portal
|
||||||
|
|
||||||
.PHONY: all test clean phony
|
all: help
|
||||||
|
|
||||||
all: dep build
|
.PHONY: help
|
||||||
|
help:
|
||||||
|
@echo "Usage:"
|
||||||
|
@sed -n 's/^#>//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' # user commands (#>)
|
||||||
|
@echo ""
|
||||||
|
@echo "Advanced commands:"
|
||||||
|
@sed -n 's/^#<//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' # internal commands (#<)
|
||||||
|
|
||||||
build: dep $(addsuffix -amd64,$(addprefix $(BUILDDIR)/,$(BINARIES)))
|
########################################################################################
|
||||||
cp scripts/wg-portal.service $(BUILDDIR)
|
##
|
||||||
cp scripts/wg-portal.env $(BUILDDIR)
|
## DEVELOPER / USER TARGETS
|
||||||
|
##
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
build-cross-plat: dep build $(addsuffix -arm,$(addprefix $(BUILDDIR)/,$(BINARIES))) $(addsuffix -arm64,$(addprefix $(BUILDDIR)/,$(BINARIES)))
|
#> codegen: Re-generate autogenerated files (like API docs)
|
||||||
cp scripts/wg-portal.service $(BUILDDIR)
|
.PHONY: codegen
|
||||||
cp scripts/wg-portal.env $(BUILDDIR)
|
codegen: $(SUBDIRS)
|
||||||
|
|
||||||
build-docker: dep
|
|
||||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 $(GOCMD) build -o $(BUILDDIR)/wgportal -ldflags "-w -s -linkmode external -extldflags \"-static\" -X github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}" -tags netgo cmd/wg-portal/main.go
|
|
||||||
|
|
||||||
dep:
|
|
||||||
$(GOCMD) mod download
|
|
||||||
|
|
||||||
validate: dep
|
|
||||||
$(GOCMD) fmt $(GOFILES)
|
|
||||||
$(GOCMD) vet $(GOFILES)
|
|
||||||
$(GOCMD) test -race $(GOFILES)
|
|
||||||
|
|
||||||
coverage: dep
|
|
||||||
$(GOCMD) fmt $(GOFILES)
|
|
||||||
$(GOCMD) test $(GOFILES) -v -coverprofile .testCoverage.txt
|
|
||||||
$(GOCMD) tool cover -func=.testCoverage.txt # use total:\s+\(statements\)\s+(\d+.\d+\%) as Gitlab CI regextotal:\s+\(statements\)\s+(\d+.\d+\%)
|
|
||||||
|
|
||||||
coverage-html: coverage
|
|
||||||
$(GOCMD) tool cover -html=.testCoverage.txt
|
|
||||||
|
|
||||||
test: dep
|
|
||||||
$(GOCMD) test $(MODULENAME)/... -v -count=1
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(GOCMD) clean $(GOFILES)
|
|
||||||
rm -rf .testCoverage.txt
|
|
||||||
rm -rf $(BUILDDIR)
|
|
||||||
|
|
||||||
docker-build:
|
|
||||||
docker build -t $(IMAGE) .
|
|
||||||
|
|
||||||
docker-push:
|
|
||||||
docker push $(IMAGE)
|
|
||||||
|
|
||||||
api-docs:
|
|
||||||
cd internal; swag init --propertyStrategy pascalcase --parseInternal --generalInfo server/api.go --output server/docs/
|
cd internal; swag init --propertyStrategy pascalcase --parseInternal --generalInfo server/api.go --output server/docs/
|
||||||
$(GOCMD) fmt internal/server/docs/docs.go
|
$(GOCMD) fmt internal/server/docs/docs.go
|
||||||
|
|
||||||
$(BUILDDIR)/%-amd64: cmd/%/main.go dep phony
|
#> update: Update all dependencies
|
||||||
GOOS=linux GOARCH=amd64 $(GOCMD) build -ldflags "-X github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}" -o $@ $<
|
.PHONY: update
|
||||||
|
update:
|
||||||
|
@ $(GOCMD) get -u ./...
|
||||||
|
@ $(GOCMD) mod tidy
|
||||||
|
|
||||||
# On arch-linux install aarch64-linux-gnu-gcc to crosscompile for arm64
|
#> format: Re-format the code
|
||||||
$(BUILDDIR)/%-arm64: cmd/%/main.go dep phony
|
.PHONY: format
|
||||||
CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc GOOS=linux GOARCH=arm64 $(GOCMD) build -ldflags "-linkmode external -extldflags \"-static\" -X github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}" -o $@ $<
|
format:
|
||||||
|
@echo "Formatting code..."
|
||||||
|
@ $(GOCMD) fmt $(GOFILES)
|
||||||
|
|
||||||
# On arch-linux install arm-linux-gnueabihf-gcc to crosscompile for arm
|
########################################################################################
|
||||||
$(BUILDDIR)/%-arm: cmd/%/main.go dep phony
|
##
|
||||||
CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc GOOS=linux GOARCH=arm GOARM=7 $(GOCMD) build -ldflags "-linkmode external -extldflags \"-static\" -X github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}" -o $@ $<
|
## TESTING / CODE QUALITY TARGETS
|
||||||
|
##
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
#> test: Run all kinds of tests, except for integration tests
|
||||||
|
.PHONY: test
|
||||||
|
test: test-vet test-race
|
||||||
|
|
||||||
|
#< test-vet: Static code analysis
|
||||||
|
.PHONY: test-vet
|
||||||
|
test-vet: build-dependencies
|
||||||
|
@$(GOCMD) vet $(GOFILES)
|
||||||
|
|
||||||
|
#< test-race: Race condition test
|
||||||
|
.PHONY: test-race
|
||||||
|
test-race: build-dependencies
|
||||||
|
@$(GOCMD) test -race -short $(GOFILES)
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
##
|
||||||
|
## CI TARGETS
|
||||||
|
##
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
#< clean: Delete all generated executables and test files
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
@rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
|
#< build: Build all executables (architecture depends on build system)
|
||||||
|
.PHONY: build
|
||||||
|
build: build-dependencies
|
||||||
|
CGO_ENABLED=1 $(GOCMD) build -o $(BUILDDIR)/wg-portal \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\" -X 'github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}'" \
|
||||||
|
cmd/wg-portal/main.go
|
||||||
|
|
||||||
|
CGO_ENABLED=0 $(GOCMD) build -o $(BUILDDIR)/hc \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\"" \
|
||||||
|
cmd/hc/main.go
|
||||||
|
|
||||||
|
#< build: Build all executables for AMD64
|
||||||
|
.PHONY: build-amd64
|
||||||
|
build-amd64: build-dependencies
|
||||||
|
CGO_ENABLED=1 $(GOCMD) build -o $(BUILDDIR)/wg-portal-amd64 \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\" -X 'github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}'" \
|
||||||
|
cmd/wg-portal/main.go
|
||||||
|
|
||||||
|
CGO_ENABLED=0 $(GOCMD) build -o $(BUILDDIR)/hc-amd64 \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\"" \
|
||||||
|
cmd/hc/main.go
|
||||||
|
|
||||||
|
#< build-arm64: Build all executables for ARM64
|
||||||
|
.PHONY: build-arm64
|
||||||
|
build-arm64: build-dependencies
|
||||||
|
CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc GOOS=linux GOARCH=arm64 $(GOCMD) build -o $(BUILDDIR)/wg-portal-arm64 \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\" -X 'github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}'" \
|
||||||
|
cmd/wg-portal/main.go
|
||||||
|
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GOCMD) build -o $(BUILDDIR)/hc-arm64 \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\"" \
|
||||||
|
cmd/hc/main.go
|
||||||
|
|
||||||
|
#< build-arm: Build all executables for ARM32
|
||||||
|
.PHONY: build-arm
|
||||||
|
build-arm: build-dependencies
|
||||||
|
CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc GOOS=linux GOARCH=arm GOARM=7 $(GOCMD) build -o $(BUILDDIR)/wg-portal-arm \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\" -X 'github.com/h44z/wg-portal/internal/server.Version=${ENV_BUILD_IDENTIFIER}-${ENV_BUILD_VERSION}'" \
|
||||||
|
cmd/wg-portal/main.go
|
||||||
|
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 $(GOCMD) build -o $(BUILDDIR)/hc-arm \
|
||||||
|
-ldflags "-w -s -extldflags \"-static\"" \
|
||||||
|
cmd/hc/main.go
|
||||||
|
|
||||||
|
#< build-dependencies: Generate the output directory for compiled executables and download dependencies
|
||||||
|
.PHONY: build-dependencies
|
||||||
|
build-dependencies:
|
||||||
|
@$(GOCMD) mod download -x
|
||||||
|
@mkdir -p $(BUILDDIR)
|
||||||
|
cp scripts/wg-portal.service $(BUILDDIR)
|
||||||
|
cp scripts/wg-portal.env $(BUILDDIR)
|
||||||
|
28
README.md
28
README.md
@ -90,16 +90,38 @@ For a full list of configuration options take a look at the source file [interna
|
|||||||
### Standalone
|
### Standalone
|
||||||
For a standalone application, use the Makefile provided in the repository to build the application. Go version 1.16 or higher has to be installed to build WireGuard Portal.
|
For a standalone application, use the Makefile provided in the repository to build the application. Go version 1.16 or higher has to be installed to build WireGuard Portal.
|
||||||
|
|
||||||
```
|
```shell
|
||||||
|
# show all possible make commands
|
||||||
make
|
make
|
||||||
|
|
||||||
# To build for arm architecture as well use:
|
# build wg-portal for current system architecture
|
||||||
make build-cross-plat
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
The compiled binary will be located in the dist folder.
|
The compiled binary will be located in the dist folder.
|
||||||
A detailed description for using this software with a raspberry pi can be found in the [README-RASPBERRYPI.md](README-RASPBERRYPI.md).
|
A detailed description for using this software with a raspberry pi can be found in the [README-RASPBERRYPI.md](README-RASPBERRYPI.md).
|
||||||
|
|
||||||
|
To build the Docker image, Docker (> 20.x) with buildx is required. If you want to build cross-platform images, you need to install qemu.
|
||||||
|
On arch linux for example install: `docker-buildx qemu-user-static qemu-user-static-binfmt`.
|
||||||
|
|
||||||
|
Once the Docker setup is completed, create a new buildx builder:
|
||||||
|
```shell
|
||||||
|
docker buildx create --name wgportalbuilder --platform linux/arm/v7,linux/arm64,linux/amd64
|
||||||
|
docker buildx use wgportalbuilder
|
||||||
|
docker buildx inspect --bootstrap
|
||||||
|
```
|
||||||
|
Now you can compile the Docker image:
|
||||||
|
```shell
|
||||||
|
# multi platform build, can only be exported to tar archives
|
||||||
|
docker buildx build --platform linux/arm/v7,linux/arm64,linux/amd64 --output type=local,dest=docker_images \
|
||||||
|
--build-arg BUILD_IDENTIFIER=dev --build-arg BUILD_VERSION=0.1 -t h44z/wg-portal .
|
||||||
|
|
||||||
|
|
||||||
|
# image for current platform only (same as docker build)
|
||||||
|
docker buildx build --load \
|
||||||
|
--build-arg BUILD_IDENTIFIER=dev --build-arg BUILD_VERSION=0.1 -t h44z/wg-portal .
|
||||||
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
You can configure WireGuard Portal using either environment variables or a yaml configuration file.
|
You can configure WireGuard Portal using either environment variables or a yaml configuration file.
|
||||||
The filepath of the yaml configuration file defaults to **config.yml** in the working directory of the executable.
|
The filepath of the yaml configuration file defaults to **config.yml** in the working directory of the executable.
|
||||||
|
35
cmd/hc/main.go
Normal file
35
cmd/hc/main.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// source taken from https://git.prolicht.digital/golib/healthcheck/-/blob/master/cmd/hc/main.go
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// main checks the given URL, if the response is not 200, it will return with exit code 1
|
||||||
|
// on success, exit code 0 will be returned
|
||||||
|
func main() {
|
||||||
|
os.Exit(checkWebEndpointFromArgs())
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWebEndpointFromArgs() int {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if status := checkWebEndpoint(os.Args[1]); !status {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWebEndpoint(url string) bool {
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: time.Second * 2,
|
||||||
|
}
|
||||||
|
if resp, err := client.Get(url); err != nil || resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
@ -5,10 +5,11 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.prolicht.digital/pub/healthcheck"
|
"git.prolicht.digital/golib/healthcheck"
|
||||||
"github.com/h44z/wg-portal/internal/server"
|
"github.com/h44z/wg-portal/internal/server"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -19,6 +20,7 @@ func main() {
|
|||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
||||||
|
|
||||||
|
logrus.Infof("sysinfo: os=%s, arch=%s", runtime.GOOS, runtime.GOARCH)
|
||||||
logrus.Infof("starting WireGuard Portal Server [%s]...", server.Version)
|
logrus.Infof("starting WireGuard Portal Server [%s]...", server.Version)
|
||||||
|
|
||||||
// Context for clean shutdown
|
// Context for clean shutdown
|
||||||
@ -26,7 +28,7 @@ func main() {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// start health check service on port 11223
|
// start health check service on port 11223
|
||||||
healthcheck.New(healthcheck.WithContext(ctx)).Start()
|
healthcheck.New(healthcheck.ListenOn(":11223")).StartWithContext(ctx)
|
||||||
|
|
||||||
service := server.Server{}
|
service := server.Server{}
|
||||||
if err := service.Setup(ctx); err != nil {
|
if err := service.Setup(ctx); err != nil {
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module github.com/h44z/wg-portal
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.prolicht.digital/pub/healthcheck v1.0.1
|
git.prolicht.digital/golib/healthcheck v1.1.1
|
||||||
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 // indirect
|
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5 // indirect
|
||||||
github.com/evanphx/json-patch v0.5.2
|
github.com/evanphx/json-patch v0.5.2
|
||||||
github.com/gin-contrib/sessions v0.0.5
|
github.com/gin-contrib/sessions v0.0.5
|
||||||
|
4
go.sum
4
go.sum
@ -1,5 +1,5 @@
|
|||||||
git.prolicht.digital/pub/healthcheck v1.0.1 h1:cdNgcSyQL9oveFBC9V+XE4OVbfMEwqPqGdShH79sZ98=
|
git.prolicht.digital/golib/healthcheck v1.1.1 h1:bdx0MuGqAq0PCooPpiuPXsr4/Ok+yfJwq8P9ITq2eLI=
|
||||||
git.prolicht.digital/pub/healthcheck v1.0.1/go.mod h1:5CVsGrijfedtLaYv3KJkfvM0nmzpgndC9MgBjC1tom4=
|
git.prolicht.digital/golib/healthcheck v1.1.1/go.mod h1:wEqVrqHJ8NsSx5qlFGUlw74wJ/wDSKaA34QoyvsEkdc=
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ=
|
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e h1:ZU22z/2YRFLyf/P4ZwUYSdNCWsMEI0VeyrFoI2rAhJQ=
|
||||||
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
@ -29,7 +29,7 @@ type Config struct {
|
|||||||
SyncFilter string `yaml:"syncFilter" envconfig:"LDAP_SYNC_FILTER"`
|
SyncFilter string `yaml:"syncFilter" envconfig:"LDAP_SYNC_FILTER"`
|
||||||
AdminLdapGroup string `yaml:"adminGroup" envconfig:"LDAP_ADMIN_GROUP"` // Members of this group receive admin rights in WG-Portal
|
AdminLdapGroup string `yaml:"adminGroup" envconfig:"LDAP_ADMIN_GROUP"` // Members of this group receive admin rights in WG-Portal
|
||||||
AdminLdapGroup_ *gldap.DN `yaml:"-"`
|
AdminLdapGroup_ *gldap.DN `yaml:"-"`
|
||||||
EveryoneAdmin bool `yaml:"everyoneAdmin" envconfig:"LDAP_EVERYONE_ADMIN"`
|
EveryoneAdmin bool `yaml:"everyoneAdmin" envconfig:"LDAP_EVERYONE_ADMIN"`
|
||||||
LdapCertConn bool `yaml:"ldapCertConn" envconfig:"LDAP_CERT_CONN"`
|
LdapCertConn bool `yaml:"ldapCertConn" envconfig:"LDAP_CERT_CONN"`
|
||||||
LdapTlsCert string `yaml:"ldapTlsCert" envconfig:"LDAPTLS_CERT"`
|
LdapTlsCert string `yaml:"ldapTlsCert" envconfig:"LDAPTLS_CERT"`
|
||||||
LdapTlsKey string `yaml:"ldapTlsKey" envconfig:"LDAPTLS_KEY"`
|
LdapTlsKey string `yaml:"ldapTlsKey" envconfig:"LDAPTLS_KEY"`
|
||||||
|
@ -135,16 +135,16 @@ func (s *Server) GetUserIndex(c *gin.Context) {
|
|||||||
peers := s.peers.GetSortedPeersForEmail(currentSession.SortedBy["userpeers"], currentSession.SortDirection["userpeers"], currentSession.Email)
|
peers := s.peers.GetSortedPeersForEmail(currentSession.SortedBy["userpeers"], currentSession.SortDirection["userpeers"], currentSession.Email)
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "user_index.html", gin.H{
|
c.HTML(http.StatusOK, "user_index.html", gin.H{
|
||||||
"Route": c.Request.URL.Path,
|
"Route": c.Request.URL.Path,
|
||||||
"Alerts": GetFlashes(c),
|
"Alerts": GetFlashes(c),
|
||||||
"Session": currentSession,
|
"Session": currentSession,
|
||||||
"Static": s.getStaticData(),
|
"Static": s.getStaticData(),
|
||||||
"Peers": peers,
|
"Peers": peers,
|
||||||
"TotalPeers": len(peers),
|
"TotalPeers": len(peers),
|
||||||
"Users": []users.User{*s.users.GetUser(currentSession.Email)},
|
"Users": []users.User{*s.users.GetUser(currentSession.Email)},
|
||||||
"Device": s.peers.GetDevice(currentSession.DeviceName),
|
"Device": s.peers.GetDevice(currentSession.DeviceName),
|
||||||
"DeviceNames": s.GetDeviceNames(),
|
"DeviceNames": s.GetDeviceNames(),
|
||||||
"UserManagePeers": s.config.WG.UserManagePeers,
|
"UserManagePeers": s.config.WG.UserManagePeers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ package wireguard
|
|||||||
import "github.com/h44z/wg-portal/internal/common"
|
import "github.com/h44z/wg-portal/internal/common"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DeviceNames []string `yaml:"devices" envconfig:"WG_DEVICES"` // managed devices
|
DeviceNames []string `yaml:"devices" envconfig:"WG_DEVICES"` // managed devices
|
||||||
DefaultDeviceName string `yaml:"defaultDevice" envconfig:"WG_DEFAULT_DEVICE"` // this device is used for auto-created peers, use GetDefaultDeviceName() to access this field
|
DefaultDeviceName string `yaml:"defaultDevice" envconfig:"WG_DEFAULT_DEVICE"` // this device is used for auto-created peers, use GetDefaultDeviceName() to access this field
|
||||||
ConfigDirectoryPath string `yaml:"configDirectory" envconfig:"WG_CONFIG_PATH"` // optional, if set, updates will be written to this path, filename: <devicename>.conf
|
ConfigDirectoryPath string `yaml:"configDirectory" envconfig:"WG_CONFIG_PATH"` // optional, if set, updates will be written to this path, filename: <devicename>.conf
|
||||||
ManageIPAddresses bool `yaml:"manageIPAddresses" envconfig:"MANAGE_IPS"` // handle ip-address setup of interface
|
ManageIPAddresses bool `yaml:"manageIPAddresses" envconfig:"MANAGE_IPS"` // handle ip-address setup of interface
|
||||||
UserManagePeers bool `yaml:"userManagePeers" envconfig:"USER_MANAGE_PEERS"` // user can manage own peers
|
UserManagePeers bool `yaml:"userManagePeers" envconfig:"USER_MANAGE_PEERS"` // user can manage own peers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Config) GetDefaultDeviceName() string {
|
func (c Config) GetDefaultDeviceName() string {
|
||||||
|
@ -302,7 +302,7 @@ type Device struct {
|
|||||||
Peers []Peer `gorm:"foreignKey:DeviceName" binding:"-" json:"-"` // linked WireGuard peers
|
Peers []Peer `gorm:"foreignKey:DeviceName" binding:"-" json:"-"` // linked WireGuard peers
|
||||||
|
|
||||||
Type DeviceType `form:"devicetype" binding:"required,oneof=client server"`
|
Type DeviceType `form:"devicetype" binding:"required,oneof=client server"`
|
||||||
DeviceName string `form:"device" gorm:"primaryKey" binding:"required" validator:"regexp=[0-9a-zA-Z\-]+"`
|
DeviceName string `form:"device" gorm:"primaryKey" binding:"required" validator:"regexp=[0-9a-zA-Z\\-]+"`
|
||||||
DisplayName string `form:"displayname" binding:"omitempty,max=200"`
|
DisplayName string `form:"displayname" binding:"omitempty,max=200"`
|
||||||
|
|
||||||
// Core WireGuard Settings (Interface section)
|
// Core WireGuard Settings (Interface section)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user