diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..c200f675 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,40 @@ +.DS_Store +/.git +/.github +/.vscode +.idea +/AdGuardHome +/AdGuardHome.exe +/AdGuardHome.yaml +/AdGuardHome.log +/data +/build +/dist +/client/node_modules +/.gitattributes +/.gitignore +/.goreleaser.yml +/changelog.config.js +/coverage.txt +/Dockerfile +/LICENSE.txt +/Makefile +/querylog.json +/querylog.json.1 +/*.md + +# Test output +dnsfilter/tests/top-1m.csv +dnsfilter/tests/dnsfilter.TestLotsOfRules*.pprof + +# Snapcraft build temporary files +*.snap +launchpad_credentials +snapcraft_login +snapcraft.yaml.bak + +# IntelliJ IDEA project files +*.iml + +# Packr +*-packr.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..5c75c8ba --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,172 @@ +name: build + +env: + GO_VERSION: 1.14 + NODE_VERSION: 13 + +on: + push: + branches: + - '*' + tags: + - v* + pull_request: + +jobs: + + test: + runs-on: ${{ matrix.os }} + env: + GO111MODULE: on + GOPROXY: https://goproxy.io + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - macOS-latest + - windows-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - + name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: ${{ env.NODE_VERSION }} + - + name: Set up Go modules cache + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - + name: Get npm cache directory + id: npm-cache + run: | + echo "::set-output name=dir::$(npm config get cache)" + - + name: Set up npm cache + uses: actions/cache@v2 + with: + path: ${{ steps.npm-cache.outputs.dir }} + key: ${{ runner.os }}-node-${{ hashFiles('client/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - + name: Run make ci + shell: bash + run: | + make ci + - + name: Upload coverage + uses: codecov/codecov-action@v1 + if: success() && matrix.os == 'ubuntu-latest' + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./coverage.txt + + app: + runs-on: ubuntu-latest + needs: test + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + - + name: Set up Node + uses: actions/setup-node@v1 + with: + node-version: ${{ env.NODE_VERSION }} + - + name: Set up Go modules cache + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - + name: Get npm cache directory + id: npm-cache + run: | + echo "::set-output name=dir::$(npm config get cache)" + - + name: Set up node_modules cache + uses: actions/cache@v2 + with: + path: ${{ steps.npm-cache.outputs.dir }} + key: ${{ runner.os }}-node-${{ hashFiles('client/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + - + name: Set up Snapcraft + run: | + sudo apt-get -yq --no-install-suggests --no-install-recommends install snapcraft + - + name: Set up GoReleaser + run: | + curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | BINDIR="$(go env GOPATH)/bin" sh + - + name: Run snapshot build + run: | + make release + + docker: + runs-on: ubuntu-latest + needs: test + steps: + - + name: Set up Docker Buildx + uses: crazy-max/ghaction-docker-buildx@v1 + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Docker Buildx (build) + run: | + make docker-multi-arch + - + name: Clear + if: always() && startsWith(github.ref, 'refs/tags/v') + run: | + rm -f ${HOME}/.docker/config.json + + notify: + needs: [app, docker] + # Secrets are not passed to workflows that are triggered by a pull request from a fork + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + steps: + - + name: Conclusion + uses: technote-space/workflow-conclusion-action@v1 + - + name: Send Slack notif + uses: 8398a7/action-slack@v3 + with: + status: ${{ env.WORKFLOW_CONCLUSION }} + fields: repo,message,commit,author + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..99fcefc4 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,47 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - '*' + pull_request: +jobs: + golangci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v1 + with: + # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. + version: v1.27 + + eslint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install modules + run: npm --prefix client ci + - name: Run ESLint + run: npm --prefix client run lint + + + notify: + needs: [golangci,eslint] + # Secrets are not passed to workflows that are triggered by a pull request from a fork + if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + steps: + - + name: Conclusion + uses: technote-space/workflow-conclusion-action@v1 + - + name: Send Slack notif + uses: 8398a7/action-slack@v3 + with: + status: ${{ env.WORKFLOW_CONCLUSION }} + fields: repo,message,commit,author + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index d47eef0c..e7f55736 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ /client/node_modules/ /querylog.json /querylog.json.1 -/a_main-packr.go coverage.txt # Test output @@ -26,3 +25,6 @@ snapcraft.yaml.bak # IntelliJ IDEA project files *.iml + +# Packr +*-packr.go diff --git a/.golangci.yml b/.golangci.yml index 47425e3f..be43ec74 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,6 +15,9 @@ run: - dnsfilter/rule_to_regexp.go - util/pprof.go - ".*_test.go" + - client/.* + - build/.* + - dist/.* # all available settings of specific linters diff --git a/.gometalinter.json b/.gometalinter.json deleted file mode 100644 index 10de7f42..00000000 --- a/.gometalinter.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Vendor": true, - "Test": true, - "Deadline": "2m", - "Sort": ["linter", "severity", "path", "line"], - "Exclude": [ - ".*generated.*", - "dnsfilter/rule_to_regexp.go" - ], - "EnableGC": true, - "Linters": { - "nakedret": { - "Command": "nakedret", - "Pattern": "^(?P.*?\\.go):(?P\\d+)\\s*(?P.*)$" - } - }, - "WarnUnmatchedDirective": true, - - "EnableAll": true, - "DisableAll": false, - "Disable": [ - "maligned", - "goconst", - "vetshadow" - ], - - "Cyclo": 20, - "LineLength": 200 -} \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..b2e11b09 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,90 @@ +project_name: AdGuardHome + +env: + - GO111MODULE=on + - GOPROXY=https://goproxy.io + +before: + hooks: + - go mod download + - go generate ./... + +builds: + - + main: ./main.go + ldflags: + - -s -w -X main.version={{.Version}} -X main.channel={{.Env.CHANNEL}} -X main.goarm={{.Env.GOARM}} + env: + - CGO_ENABLED=0 + goos: + - darwin + - linux + - freebsd + - windows + goarch: + - 386 + - amd64 + - arm + - arm64 + - mips + - mipsle + - mips64 + - mips64le + goarm: + - 5 + - 6 + - 7 + gomips: + - softfloat + ignore: + - goos: freebsd + goarch: mips + - goos: freebsd + goarch: mipsle + +archives: + - + # Archive name template. + # Defaults: + # - if format is `tar.gz`, `tar.xz`, `gz` or `zip`: + # - `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}` + # - if format is `binary`: + # - `{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}` + name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" + wrap_in_directory: "AdGuardHome" + format_overrides: + - goos: windows + format: zip + - goos: darwin + format: zip + files: + - LICENSE.txt + - README.md + +snapcrafts: + - + name: adguard-home + base: core18 + name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' + summary: Network-wide ads & trackers blocking DNS server + description: | + AdGuard Home is a network-wide software for blocking ads & tracking. After + you set it up, it'll cover ALL your home devices, and you don't need any + client-side software for that. + + It operates as a DNS server that re-routes tracking domains to a "black hole," + thus preventing your devices from connecting to those servers. It's based + on software we use for our public AdGuard DNS servers -- both share a lot + of common code. + grade: stable + confinement: strict + publish: false + license: GPL-3.0 + apps: + adguard-home: + command: AdGuardHome -w $SNAP_DATA --no-check-update + plugs: [ network-bind ] + daemon: simple + +checksum: + name_template: 'checksums.txt' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b2e5a2dd..00000000 --- a/.travis.yml +++ /dev/null @@ -1,121 +0,0 @@ -if: repo = AdguardTeam/AdGuardHome -language: go -sudo: false - -go: - - 1.14.x -os: - - linux - - osx - - windows - -before_install: - - |- - case $TRAVIS_OS_NAME in - linux | osx) - nvm install node - npm install -g npm - curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.23.8 - ;; - windows) - # Using NVS for managing Node.js versions on Windows - NVS_HOME="C:\ProgramData\nvs" - git clone --single-branch https://github.com/jasongin/nvs $NVS_HOME - source $NVS_HOME/nvs.sh - nvs add latest - nvs use latest - ;; - esac - -install: - - |- - case $TRAVIS_OS_NAME in - linux | osx) - node --version - npm --version - npm --prefix client ci - ;; - windows) - node --version - npm --version - nvs --version - npm --prefix client ci - ;; - esac - -cache: - directories: - - $HOME/.cache/go-build - - $HOME/gopath/pkg/mod - - $HOME/Library/Caches/go-build - -script: - - |- - case $TRAVIS_OS_NAME in - linux | osx) - /bin/bash ci.sh - ;; - windows) - npm --prefix client run build-prod - go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./... - ;; - esac - -after_success: - - |- - case $TRAVIS_OS_NAME in - linux) - bash <(curl -s https://codecov.io/bash) - ;; - esac - -notifications: - slack: performix:yXTihlSzsLFSZiqbXMNzvTSX - -matrix: - include: - # Release build configuration - - if: repo = AdguardTeam/AdGuardHome - - name: release - go: - - 1.14.x - os: - - linux - - script: - - node -v - - npm -v - # Prepare releases - - ./build_release.sh - - ls -l dist - - deploy: - provider: releases - api_key: $GITHUB_TOKEN - file: - - dist/AdGuardHome_* - on: - repo: AdguardTeam/AdGuardHome - tags: true - draft: true - file_glob: true - skip_cleanup: true - - # Docker build configuration - - if: repo = AdguardTeam/AdGuardHome - - name: docker - if: type != pull_request AND (branch = master OR tag IS present) AND repo = AdguardTeam/AdGuardHome - go: - - 1.14.x - os: - - linux - services: - - docker - before_script: - - nvm install node - - npm install -g npm - script: - - docker login -u="$DOCKER_USER" -p="$DOCKER_PASSWORD" - - ./build_docker.sh - after_script: - - docker images diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..49ff6118 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,78 @@ +FROM --platform=${BUILDPLATFORM:-linux/amd64} tonistiigi/xx:golang AS xgo +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.14-alpine as builder + +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION=dev +ARG CHANNEL=release + +ENV CGO_ENABLED 0 +ENV GO111MODULE on +ENV GOPROXY https://goproxy.io + +COPY --from=xgo / / +RUN go env + +RUN apk --update --no-cache add \ + build-base \ + gcc \ + git \ + npm \ + && rm -rf /tmp/* /var/cache/apk/* + +WORKDIR /app + +COPY . ./ + +# Prepare the client code +RUN npm --prefix client ci && npm --prefix client run build-prod + +# Download go dependencies +RUN go mod download +RUN go generate ./... + +# It's important to place TARGET* arguments here to avoid running npm and go mod download for every platform +ARG TARGETPLATFORM +ARG TARGETOS +ARG TARGETARCH +RUN go build -ldflags="-s -w -X main.version=${VERSION} -X main.channel=${CHANNEL} -X main.goarm=${GOARM}" + +FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:latest + +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION +ARG CHANNEL + +LABEL maintainer="AdGuard Team " \ + org.opencontainers.image.created=$BUILD_DATE \ + org.opencontainers.image.url="https://adguard.com/adguard-home.html" \ + org.opencontainers.image.source="https://github.com/AdguardTeam/AdGuardHome" \ + org.opencontainers.image.version=$VERSION \ + org.opencontainers.image.revision=$VCS_REF \ + org.opencontainers.image.vendor="AdGuard" \ + org.opencontainers.image.title="AdGuard Home" \ + org.opencontainers.image.description="Network-wide ads & trackers blocking DNS server" \ + org.opencontainers.image.licenses="GPL-3.0" + +RUN apk --update --no-cache add \ + ca-certificates \ + libcap \ + libressl \ + tzdata \ + && rm -rf /tmp/* /var/cache/apk/* + +COPY --from=builder --chown=nobody:nogroup /app/AdGuardHome /opt/adguardhome/AdGuardHome +COPY --from=builder --chown=nobody:nogroup /usr/local/go/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip + +RUN /opt/adguardhome/AdGuardHome --version \ + && mkdir -p /opt/adguardhome/conf /opt/adguardhome/work \ + && chown -R nobody: /opt/adguardhome \ + && setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome + +EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp +WORKDIR /opt/adguardhome/work +VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"] + +ENTRYPOINT ["/opt/adguardhome/AdGuardHome"] +CMD ["-h", "0.0.0.0", "-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"] diff --git a/Dockerfile.travis b/Dockerfile.travis deleted file mode 100644 index 0e11574e..00000000 --- a/Dockerfile.travis +++ /dev/null @@ -1,23 +0,0 @@ -FROM alpine:latest -LABEL maintainer="AdGuard Team " - -# Update CA certs -RUN apk --no-cache --update add ca-certificates libcap && \ - rm -rf /var/cache/apk/* && \ - mkdir -p /opt/adguardhome/conf /opt/adguardhome/work && \ - chown -R nobody: /opt/adguardhome - -COPY --chown=nobody:nogroup ./AdGuardHome /opt/adguardhome/AdGuardHome - -RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome - -EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp - -VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"] - -WORKDIR /opt/adguardhome/work - -#USER nobody - -ENTRYPOINT ["/opt/adguardhome/AdGuardHome"] -CMD ["-h", "0.0.0.0", "-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"] diff --git a/Makefile b/Makefile index 65cea96f..f577ea7c 100644 --- a/Makefile +++ b/Makefile @@ -1,43 +1,226 @@ -GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags) -NATIVE_GOOS = $(shell unset GOOS; go env GOOS) -NATIVE_GOARCH = $(shell unset GOARCH; go env GOARCH) +# +# Available targets +# +# * build -- builds AdGuardHome for the current platform +# * client -- builds client-side code of AdGuard Home +# * client-watch -- builds client-side code of AdGuard Home and watches for changes there +# * docker -- builds a docker image for the current platform +# * clean -- clean everything created by previous builds +# * lint -- run all linters +# * test -- run all unit-tests +# * dependencies -- installs dependencies (go and npm modules) +# * ci -- installs dependencies, runs linters and tests, intended to be used by CI/CD +# +# Building releases: +# +# * release -- builds AdGuard Home distros. CHANNEL must be specified (edge, release or beta). +# * docker-multi-arch -- builds a multi-arch image. If you want it to be pushed to docker hub, +# you must specify: +# * DOCKER_IMAGE_NAME - adguard/adguard-home +# * DOCKER_OUTPUT - type=image,name=adguard/adguard-home,push=true + GOPATH := $(shell go env GOPATH) -JSFILES = $(shell find client -path client/node_modules -prune -o -type f -name '*.js') -STATIC = build/static/index.html -CHANNEL ?= release -DOCKER_IMAGE_DEV_NAME=adguardhome-dev -DOCKERFILE=packaging/docker/Dockerfile -DOCKERFILE_HUB=packaging/docker/Dockerfile.travis - +PWD := $(shell pwd) TARGET=AdGuardHome +BASE_URL="https://static.adguard.com/adguardhome/$(CHANNEL)" -.PHONY: all build clean +# See release target +DIST_DIR=dist + +# Update channel. Can be release, beta or edge. Uses edge by default. +CHANNEL ?= edge + +# Validate channel +ifneq ($(CHANNEL),relese) +ifneq ($(CHANNEL),beta) +ifneq ($(CHANNEL),edge) +$(error CHANNEL value is not valid. Valid values are release,beta or edge) +endif +endif +endif + +# goreleaser command depends on the $CHANNEL +GORELEASER_COMMAND=goreleaser release --rm-dist --skip-publish --snapshot +ifneq ($(CHANNEL),edge) + # If this is not an "edge" build, use normal release command + GORELEASER_COMMAND=goreleaser release --rm-dist --skip-publish +endif + +# Version properties +COMMIT=$(shell git rev-parse --short HEAD) +TAG_NAME=$(shell git describe --abbrev=0) +RELEASE_VERSION=$(TAG_NAME) +SNAPSHOT_VERSION=$(RELEASE_VERSION)-SNAPSHOT-$(COMMIT) + +# Set proper version +VERSION= +ifeq ($(TAG_NAME),$(shell git describe --abbrev=4)) + VERSION=$(RELEASE_VERSION) +else + VERSION=$(SNAPSHOT_VERSION) +endif + +# Docker target parameters +DOCKER_IMAGE_NAME ?= adguardhome-dev +DOCKER_IMAGE_FULL_NAME = $(DOCKER_IMAGE_NAME):$(VERSION) +DOCKER_PLATFORMS=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le +DOCKER_OUTPUT ?= type=image,name=$(DOCKER_IMAGE_NAME),push=false +BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') + +# Docker tags (can be redefined) +DOCKER_TAGS ?= +ifndef DOCKER_TAGS + ifeq ($(CHANNEL),release) + DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):latest + endif + ifeq ($(CHANNEL),beta) + DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):beta + endif + ifeq ($(CHANNEL),edge) + # Don't set the version tag when pushing to "edge" + DOCKER_IMAGE_FULL_NAME := $(DOCKER_IMAGE_NAME):edge + # DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):edge + endif +endif + +# Validate docker build arguments +ifndef DOCKER_IMAGE_NAME +$(error DOCKER_IMAGE_NAME value is not set) +endif + +.PHONY: all build client client-watch docker lint test dependencies clean release docker-multi-arch all: build -build: $(TARGET) - -client/node_modules: client/package.json client/package-lock.json - npm --prefix client ci - touch client/node_modules - -$(STATIC): $(JSFILES) client/node_modules - npm --prefix client run build-prod - -$(TARGET): $(STATIC) *.go home/*.go dhcpd/*.go dnsfilter/*.go dnsforward/*.go - GOOS=$(NATIVE_GOOS) GOARCH=$(NATIVE_GOARCH) GO111MODULE=off go get -v github.com/gobuffalo/packr/... - PATH=$(GOPATH)/bin:$(PATH) packr -z - CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$(GIT_VERSION) -X main.channel=$(CHANNEL) -X main.goarm=$(GOARM)" -asmflags="-trimpath=$(PWD)" -gcflags="-trimpath=$(PWD)" +build: dependencies client + go generate ./... + CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$(VERSION) -X main.channel=$(CHANNEL) -X main.goarm=$(GOARM)" PATH=$(GOPATH)/bin:$(PATH) packr clean +client: + npm --prefix client run build-prod + +client-watch: + npm --prefix client run watch + docker: - docker build -t "$(DOCKER_IMAGE_DEV_NAME)" -f "$(DOCKERFILE)" . + DOCKER_CLI_EXPERIMENTAL=enabled \ + docker buildx build \ + --build-arg VERSION=$(VERSION) \ + --build-arg CHANNEL=$(CHANNEL) \ + --build-arg VCS_REF=$(COMMIT) \ + --build-arg BUILD_DATE=$(BUILD_DATE) \ + $(DOCKER_TAGS) \ + --load \ + -t "$(DOCKER_IMAGE_NAME)" -f ./Dockerfile . + @echo Now you can run the docker image: - @echo docker run --name "$(DOCKER_IMAGE_DEV_NAME)" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_DEV_NAME) + @echo docker run --name "adguard-home" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_NAME) + +lint: + @echo Running linters + golangci-lint run ./... + npm --prefix client run lint + +test: + @echo Running unit-tests + go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./... + +ci: dependencies client test + +dependencies: + npm --prefix client ci + go mod download clean: - $(MAKE) cleanfast + # make build output + rm -f AdGuardHome + rm -f AdGuardHome.exe + # tests output + rm -rf data + rm -f coverage.txt + # static build output rm -rf build + # dist folder + rm -rf $(DIST_DIR) + # client deps rm -rf client/node_modules + # packr-generated files + PATH=$(GOPATH)/bin:$(PATH) packr clean || true -cleanfast: - rm -f $(TARGET) +docker-multi-arch: + DOCKER_CLI_EXPERIMENTAL=enabled \ + docker buildx build \ + --platform $(DOCKER_PLATFORMS) \ + --build-arg VERSION=$(VERSION) \ + --build-arg CHANNEL=$(CHANNEL) \ + --build-arg VCS_REF=$(COMMIT) \ + --build-arg BUILD_DATE=$(BUILD_DATE) \ + $(DOCKER_TAGS) \ + --output "$(DOCKER_OUTPUT)" \ + -t "$(DOCKER_IMAGE_FULL_NAME)" -f ./Dockerfile . + + @echo If the image was pushed to the registry, you can now run it: + @echo docker run --name "adguard-home" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_NAME) + +release: dependencies client + @echo Starting release build: version $(VERSION), channel $(CHANNEL) + CHANNEL=$(CHANNEL) $(GORELEASER_COMMAND) + $(call write_version_file,$(VERSION)) + PATH=$(GOPATH)/bin:$(PATH) packr clean + +define write_version_file + $(eval version := $(1)) + + @echo Writing version file: $(version) + + # Variables for CI + rm -f $(DIST_DIR)/version.txt + echo "version=$(version)" > $(DIST_DIR)/version.txt + + # Prepare the version.json file + rm -f $(DIST_DIR)/version.json + echo "{" >> $(DIST_DIR)/version.json + echo " \"version\": \"$(version)\"," >> $(DIST_DIR)/version.json + echo " \"announcement\": \"AdGuard Home $(version) is now available!\"," >> $(DIST_DIR)/version.json + echo " \"announcement_url\": \"https://github.com/AdguardTeam/AdGuardHome/releases\"," >> $(DIST_DIR)/version.json + echo " \"selfupdate_min_version\": \"v0.0\"," >> $(DIST_DIR)/version.json + + # Windows builds + echo " \"download_windows_amd64\": \"$(BASE_URL)/AdGuardHome_windows_amd64.zip\"," >> $(DIST_DIR)/version.json + echo " \"download_windows_386\": \"$(BASE_URL)/AdGuardHome_windows_386.zip\"," >> $(DIST_DIR)/version.json + + # MacOS builds + echo " \"download_darwin_amd64\": \"$(BASE_URL)/AdGuardHome_darwin_amd64.zip\"," >> $(DIST_DIR)/version.json + echo " \"download_darwin_386\": \"$(BASE_URL)/AdGuardHome_darwin_386.zip\"," >> $(DIST_DIR)/version.json + + # Linux + echo " \"download_linux_amd64\": \"$(BASE_URL)/AdGuardHome_linux_amd64.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_386\": \"$(BASE_URL)/AdGuardHome_linux_386.tar.gz\"," >> $(DIST_DIR)/version.json + + # Linux, all kinds of ARM + echo " \"download_linux_arm\": \"$(BASE_URL)/AdGuardHome_linux_armv6.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_armv5\": \"$(BASE_URL)/AdGuardHome_linux_armv5.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_armv6\": \"$(BASE_URL)/AdGuardHome_linux_armv6.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_armv7\": \"$(BASE_URL)/AdGuardHome_linux_armv7.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_arm64\": \"$(BASE_URL)/AdGuardHome_linux_arm64.tar.gz\"," >> $(DIST_DIR)/version.json + + # Linux, MIPS + echo " \"download_linux_mips\": \"$(BASE_URL)/AdGuardHome_linux_mips_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_mipsle\": \"$(BASE_URL)/AdGuardHome_linux_mipsle_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_mips64\": \"$(BASE_URL)/AdGuardHome_linux_mips64_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_linux_mips64le\": \"$(BASE_URL)/AdGuardHome_linux_mips64le_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json + + # FreeBSD + echo " \"download_freebsd_386\": \"$(BASE_URL)/AdGuardHome_freebsd_386.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_freebsd_amd64\": \"$(BASE_URL)/AdGuardHome_freebsd_amd64.tar.gz\"," >> $(DIST_DIR)/version.json + + # FreeBSD, all kinds of ARM + echo " \"download_freebsd_arm\": \"$(BASE_URL)/AdGuardHome_freebsd_armv6.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_freebsd_armv5\": \"$(BASE_URL)/AdGuardHome_freebsd_armv5.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_freebsd_armv6\": \"$(BASE_URL)/AdGuardHome_freebsd_armv6.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_freebsd_armv7\": \"$(BASE_URL)/AdGuardHome_freebsd_armv7.tar.gz\"," >> $(DIST_DIR)/version.json + echo " \"download_freebsd_arm64\": \"$(BASE_URL)/AdGuardHome_freebsd_arm64.tar.gz\"" >> $(DIST_DIR)/version.json + + # Finish + echo "}" >> $(DIST_DIR)/version.json +endef \ No newline at end of file diff --git a/README.md b/README.md index 83aa32fb..17421a5d 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,6 @@ Twitter | Telegram

- - Build status - Code Coverage @@ -153,17 +150,11 @@ Is there a chance to handle this in the future? DNS will never be enough to do t ### Prerequisites -You will need: +You will need this to build AdGuard Home: * [go](https://golang.org/dl/) v1.14 or later. * [node.js](https://nodejs.org/en/download/) v10 or later. -You can either install them via the provided links or use [brew.sh](https://brew.sh/) if you're on Mac: - -```bash -brew install go node -``` - ### Building Open Terminal and execute these commands: @@ -174,15 +165,38 @@ cd AdGuardHome make ``` -#### (For devs) Upload translations -``` -node upload.js -``` +Check the [`Makefile`](https://github.com/AdguardTeam/AdGuardHome/blob/master/Makefile) to learn about other commands. -#### (For devs) Download translations -``` -node download.js -``` +#### Preparing release + +You'll need this to prepare a release build: + +* [goreleaser](https://goreleaser.com/) +* [snapcraft](https://snapcraft.io/) + +Commands: + +* `make release` - builds a snapshot build (CHANNEL=edge) +* `CHANNEL=beta make release` - builds beta version, tag is mandatory. +* `CHANNEL=release make release` - builds release version, tag is mandatory. + +#### Docker image + +* Run `make docker` to build the Docker image locally. +* Run `make docker-multi-arch` to build the multi-arch Docker image (the one that we publish to Docker Hub). + +Please note, that we're using [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/) to build our official image. + +You may need to prepare before using these builds: + +* (Linux-only) Install Qemu: `docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes` +* Prepare builder: `docker buildx create --name buildx-builder --driver docker-container --use` + + +### Resources that we update periodically + +* `scripts/translations` +* `scripts/whotracksme` ## Contributing @@ -192,26 +206,41 @@ You are welcome to fork this repository, make your changes and submit a pull req ### Test unstable versions +There are two update channels that you can use: + +* `beta` - beta version of AdGuard Home. More or less stable versions. +* `edge` - the newest version of AdGuard Home. New updates are pushed to this channel daily and it is the closest to the master branch you can get. + +There are three options how you can install an unstable version: + +1. [Snap Store](https://snapcraft.io/adguard-home) -- look for "beta" and "edge" channels there. +2. [Docker Hub](https://hub.docker.com/r/adguard/adguardhome) -- look for "beta" and "edge" tags there. +3. Standalone builds. Look for the available builds below. + There are three options how you can install an unstable version. 1. You can either install a beta version of AdGuard Home which we update periodically. 2. You can use the Docker image from the `edge` tag, which is synced with the repo master branch. 3. You can install AdGuard Home from `beta` or `edge` channels on the Snap Store. -* Beta builds - * [Raspberry Pi (32-bit ARMv6)](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm.tar.gz) - * [MacOS](https://static.adguard.com/adguardhome/beta/AdGuardHome_MacOS.zip) - * [Windows 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_Windows_amd64.zip) - * [Windows 32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_Windows_386.zip) - * [Linux 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz) - * [Linux 32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_386.tar.gz) - * [FreeBSD 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz) - * [Linux 64-bit ARM](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz) - * [Linux 32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz) - * [MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips.tar.gz) - * [MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mipsle.tar.gz) -* [Docker Hub](https://hub.docker.com/r/adguard/adguardhome) -* [Snap Store](https://snapcraft.io/adguard-home) +* Beta channel builds + * Linux: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_386.tar.gz) + * Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz) (recommended for Rapsberry Pi), [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz) + * Linux MIPS: [32-bit MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz), [32-bit MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mipsle_softfloat.tar.gz), [64-bit MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips64_softfloat.tar.gz), [64-bit MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips64le_softfloat.tar.gz) + * Windows: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_windows_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_windows_386.zip) + * MacOS: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_darwin_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_darwin_386.zip) + * FreeBSD: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_386.tar.gz) + * FreeBSD ARM: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv5.tar.gz), [32-bit ARMv6](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv7.tar.gz) + +* Edge channel builds + * Linux: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_386.tar.gz) + * Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv6.tar.gz) (recommended for Rapsberry Pi), [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv7.tar.gz) + * Linux MIPS: [32-bit MIPS](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips_softfloat.tar.gz), [32-bit MIPSLE](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mipsle_softfloat.tar.gz), [64-bit MIPS](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips64_softfloat.tar.gz), [64-bit MIPSLE](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips64le_softfloat.tar.gz) + * Windows: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_windows_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_windows_386.zip) + * MacOS: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_darwin_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_darwin_386.zip) + * FreeBSD: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_386.tar.gz) + * FreeBSD ARM: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv5.tar.gz), [32-bit ARMv6](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv6.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv7.tar.gz) + ### Report issues diff --git a/build_docker.sh b/build_docker.sh deleted file mode 100755 index 81173574..00000000 --- a/build_docker.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash - -set -eE -set -o pipefail -set -x - -DOCKERFILE="packaging/docker/Dockerfile.hub" -IMAGE_NAME="adguard/adguardhome" - -if [[ "${TRAVIS_BRANCH}" == "master" ]] -then - VERSION="edge" -else - VERSION=`git describe --abbrev=4 --dirty --always --tags` -fi - -build_image() { - from="$(awk '$1 == toupper("FROM") { print $2 }' ${DOCKERFILE})" - - # See https://hub.docker.com/r/multiarch/alpine/tags - case "${GOARCH}" in - arm64) - alpineArch='arm64-edge' - imageArch='arm64' - ;; - arm) - alpineArch='armhf-edge' - imageArch='armhf' - ;; - 386) - alpineArch='i386-edge' - imageArch='i386' - ;; - amd64) - alpineArch='amd64-edge' - ;; - *) - alpineArch='amd64-edge' - ;; - esac - - if [[ "${GOOS}" == "linux" ]] && [[ "${GOARCH}" == "amd64" ]] - then - image="${IMAGE_NAME}:${VERSION}" - else - image="${IMAGE_NAME}:${imageArch}-${VERSION}" - fi - - make cleanfast; CGO_DISABLED=1 make - - docker pull "multiarch/alpine:${alpineArch}" - docker tag "multiarch/alpine:${alpineArch}" "$from" - docker build -t "${image}" -f ${DOCKERFILE} . - docker push ${image} - if [[ "${VERSION}" != "edge" ]] - then - latest=${image/$VERSION/latest} - docker tag "${image}" "${latest}" - docker push ${latest} - docker rmi ${latest} - fi - docker rmi "$from" -} - -# prepare qemu -docker run --rm --privileged multiarch/qemu-user-static:register --reset - -make clean - -# Prepare releases -GOOS=linux GOARCH=amd64 build_image -GOOS=linux GOARCH=386 build_image -GOOS=linux GOARCH=arm GOARM=6 build_image -GOOS=linux GOARCH=arm64 GOARM=6 build_image diff --git a/build_release.sh b/build_release.sh deleted file mode 100755 index 4f2a4c42..00000000 --- a/build_release.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash - -set -eE -set -o pipefail -set -x - -channel=${1:-release} -baseUrl="https://static.adguard.com/adguardhome/$channel" -dst=dist -version=`git describe --abbrev=4 --dirty --always --tags` - -f() { - make cleanfast; CGO_DISABLED=1 make - if [[ $GOOS == darwin ]]; then - zip $dst/AdGuardHome_MacOS.zip AdGuardHome README.md LICENSE.txt - elif [[ $GOOS == windows ]]; then - zip $dst/AdGuardHome_Windows_"$GOARCH".zip AdGuardHome.exe README.md LICENSE.txt - else - rm -rf dist/AdguardHome - mkdir -p dist/AdGuardHome - cp -pv {AdGuardHome,LICENSE.txt,README.md} dist/AdGuardHome/ - pushd dist - if [[ $GOARCH == arm ]] && [[ $GOARM != 6 ]]; then - tar zcvf AdGuardHome_"$GOOS"_armv"$GOARM".tar.gz AdGuardHome/ - else - tar zcvf AdGuardHome_"$GOOS"_"$GOARCH".tar.gz AdGuardHome/ - fi - popd - rm -rf dist/AdguardHome - fi -} - -# Clean dist and build -make clean -rm -rf $dst - -# Prepare the dist folder -mkdir -p $dst - -# Prepare releases -CHANNEL=$channel GOOS=darwin GOARCH=amd64 f -CHANNEL=$channel GOOS=linux GOARCH=amd64 f -CHANNEL=$channel GOOS=linux GOARCH=386 GO386=387 f -CHANNEL=$channel GOOS=linux GOARCH=arm GOARM=5 f -CHANNEL=$channel GOOS=linux GOARCH=arm GOARM=6 f -CHANNEL=$channel GOOS=linux GOARCH=arm64 GOARM=6 f -CHANNEL=$channel GOOS=windows GOARCH=amd64 f -CHANNEL=$channel GOOS=windows GOARCH=386 f -CHANNEL=$channel GOOS=linux GOARCH=mipsle GOMIPS=softfloat f -CHANNEL=$channel GOOS=linux GOARCH=mips GOMIPS=softfloat f -CHANNEL=$channel GOOS=freebsd GOARCH=amd64 f - -# Variables for CI -echo "version=$version" > $dst/version.txt - -# Prepare the version.json file -echo "{" >> $dst/version.json -echo " \"version\": \"$version\"," >> $dst/version.json -echo " \"announcement\": \"AdGuard Home $version is now available!\"," >> $dst/version.json -echo " \"announcement_url\": \"https://github.com/AdguardTeam/AdGuardHome/releases\"," >> $dst/version.json -echo " \"download_windows_amd64\": \"$baseUrl/AdGuardHome_Windows_amd64.zip\"," >> $dst/version.json -echo " \"download_windows_386\": \"$baseUrl/AdGuardHome_Windows_386.zip\"," >> $dst/version.json -echo " \"download_darwin_amd64\": \"$baseUrl/AdGuardHome_MacOS.zip\"," >> $dst/version.json -echo " \"download_linux_amd64\": \"$baseUrl/AdGuardHome_linux_amd64.tar.gz\"," >> $dst/version.json -echo " \"download_linux_386\": \"$baseUrl/AdGuardHome_linux_386.tar.gz\"," >> $dst/version.json -echo " \"download_linux_arm\": \"$baseUrl/AdGuardHome_linux_arm.tar.gz\"," >> $dst/version.json -echo " \"download_linux_armv5\": \"$baseUrl/AdGuardHome_linux_armv5.tar.gz\"," >> $dst/version.json -echo " \"download_linux_arm64\": \"$baseUrl/AdGuardHome_linux_arm64.tar.gz\"," >> $dst/version.json -echo " \"download_linux_mips\": \"$baseUrl/AdGuardHome_linux_mips.tar.gz\"," >> $dst/version.json -echo " \"download_linux_mipsle\": \"$baseUrl/AdGuardHome_linux_mipsle.tar.gz\"," >> $dst/version.json -echo " \"download_freebsd_amd64\": \"$baseUrl/AdGuardHome_freebsd_amd64.tar.gz\"," >> $dst/version.json -echo " \"selfupdate_min_version\": \"v0.0\"" >> $dst/version.json -echo "}" >> $dst/version.json diff --git a/build_snap.sh b/build_snap.sh deleted file mode 100755 index 13dae65f..00000000 --- a/build_snap.sh +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/env bash - -set -eE -set -o pipefail -set -x - -BUILDER_IMAGE="adguard/snapcraft:1.0" -SNAPCRAFT_TMPL="packaging/snap/snapcraft.yaml" -SNAP_NAME="adguard-home" -LAUNCHPAD_CREDENTIALS_DIR=".local/share/snapcraft/provider/launchpad" - -if [[ -z ${VERSION} ]]; then - VERSION=$(git describe --abbrev=4 --dirty --always --tags) - echo "VERSION env variable is not set, getting it from git: ${VERSION}" -fi - -# If bash is interactive, set `-it` parameter for docker run -INTERACTIVE="" -if [ -t 0 ]; then - INTERACTIVE="-it" -fi - -function usage() { - cat <launchpad_credentials - - # Snapcraft login data - # It can be exported using snapcraft export-login command - echo "[login.ubuntu.com] - macaroon = ${SNAPCRAFT_MACAROON} - unbound_discharge = ${SNAPCRAFT_UBUNTU_DISCHARGE} - email = ${SNAPCRAFT_EMAIL}" >snapcraft_login - - # Prepare the snap configuration - cp ${SNAPCRAFT_TMPL} ./snapcraft.yaml - sed -i.bak 's/dev_version/'"${VERSION}"'/g' ./snapcraft.yaml - rm -f snapcraft.yaml.bak -} - -build_snap() { - # prepare credentials - prepare - - # copy them to the directory where snapcraft will be able to read them - mkdir -p ~/${LAUNCHPAD_CREDENTIALS_DIR} - cp -f snapcraft_login ~/${LAUNCHPAD_CREDENTIALS_DIR}/credentials - chmod 600 ~/${LAUNCHPAD_CREDENTIALS_DIR}/credentials - - # run the build - snapcraft remote-build --build-on=${ARCH} --launchpad-accept-public-upload - - # remove the credentials - we don't need them anymore - rm -rf ~/${LAUNCHPAD_CREDENTIALS_DIR} - - # remove version from the file name - rename_snap_file - - # cleanup credentials - cleanup -} - -build_snap_docker() { - # prepare credentials - prepare - - docker run ${INTERACTIVE} --rm \ - -v $(pwd):/build \ - -v $(pwd)/launchpad_credentials:/root/${LAUNCHPAD_CREDENTIALS_DIR}/credentials:ro \ - ${BUILDER_IMAGE} \ - snapcraft remote-build --build-on=${ARCH} --launchpad-accept-public-upload - - # remove version from the file name - rename_snap_file - - # cleanup credentials - cleanup -} - -rename_snap_file() { - # In order to make working with snaps easier later on - # we remove version from the file name - - # Check that the snap file exists - snapFile="${SNAP_NAME}_${VERSION}_${ARCH}.snap" - if [ ! -f ${snapFile} ]; then - echo "Snap file ${snapFile} not found!" - exit 1 - fi - - mv -f ${snapFile} "${SNAP_NAME}_${ARCH}.snap" -} - -publish_snap() { - # prepare credentials - prepare - - # Check that the snap file exists - snapFile="${SNAP_NAME}_${ARCH}.snap" - if [ ! -f ${snapFile} ]; then - echo "Snap file ${snapFile} not found!" - exit 1 - fi - - # Login if necessary - snapcraft login --with=snapcraft_login - - # Push to the channel - snapcraft push --release=${CHANNEL} ${snapFile} - - # cleanup credentials - cleanup -} - -publish_snap_docker() { - # prepare credentials - prepare - - # Check that the snap file exists - snapFile="${SNAP_NAME}_${ARCH}.snap" - if [ ! -f ${snapFile} ]; then - echo "Snap file ${snapFile} not found!" - exit 1 - fi - - # Login and publish the snap - docker run ${INTERACTIVE} --rm \ - -v $(pwd):/build \ - ${BUILDER_IMAGE} \ - sh -c "snapcraft login --with=/build/snapcraft_login && snapcraft push --release=${CHANNEL} /build/${snapFile}" - - # cleanup credentials - cleanup -} - -####################################### -# main functions -####################################### - -build() { - if [[ -n "$1" ]]; then - echo "ARCH is set to $1" - ARCH=$1 build_snap - else - ARCH=i386 build_snap - ARCH=arm64 build_snap - ARCH=armhf build_snap - ARCH=amd64 build_snap - fi -} - -build_docker() { - if [[ -n "$1" ]]; then - echo "ARCH is set to $1" - ARCH=$1 build_snap_docker - else - ARCH=i386 build_snap_docker - ARCH=arm64 build_snap_docker - ARCH=armhf build_snap_docker - ARCH=amd64 build_snap_docker - fi -} - -publish_docker() { - if [[ -z $1 ]]; then - echo "No channel specified" - exit 1 - fi - CHANNEL="${1}" - if [ "$CHANNEL" != "stable" ] && [ "$CHANNEL" != "beta" ]; then - echo "$CHANNEL is an invalid value for the update channel!" - exit 1 - fi - - if [[ -n "$2" ]]; then - echo "ARCH is set to $2" - ARCH=$2 publish_snap_docker - else - ARCH=i386 publish_snap_docker - ARCH=arm64 publish_snap_docker - ARCH=armhf publish_snap_docker - ARCH=amd64 publish_snap_docker - fi -} - -publish() { - if [[ -z $1 ]]; then - echo "No channel specified" - exit 1 - fi - CHANNEL="${1}" - if [ "$CHANNEL" != "stable" ] && [ "$CHANNEL" != "beta" ]; then - echo "$CHANNEL is an invalid value for the update channel!" - exit 1 - fi - - if [[ -n "$2" ]]; then - echo "ARCH is set to $2" - ARCH=$2 publish_snap - else - ARCH=i386 publish_snap - ARCH=arm64 publish_snap - ARCH=armhf publish_snap - ARCH=amd64 publish_snap - fi -} - -cleanup() { - rm -f launchpad_credentials - rm -f snapcraft.yaml - rm -f snapcraft.yaml.bak - rm -f snapcraft_login - git checkout snapcraft.yaml -} - -####################################### -# main -####################################### -if [[ -z $1 || $1 == "--help" || $1 == "-h" ]]; then - usage -fi - -case "$1" in -"build-docker") build_docker $2 ;; -"build") build $2 ;; -"publish-docker-beta") publish_docker beta $2 ;; -"publish-docker-release") publish_docker stable $2 ;; -"publish-beta") publish beta $2 ;; -"publish-release") publish stable $2 ;; -"prepare") prepare ;; -"cleanup") cleanup ;; -*) usage ;; -esac - -exit 0 diff --git a/ci.sh b/ci.sh deleted file mode 100755 index 544f0109..00000000 --- a/ci.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -set -e -set -x - -echo "Starting AdGuard Home CI script" - -# Print the current directory contents -ls -la - -# Check versions and current directory -node -v -npm -v -go version -golangci-lint --version - -# Run linter -golangci-lint run - -# Make -make clean -make build/static/index.html -make - -# Run tests -go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./... - -# if [[ -z "$(git status --porcelain)" ]]; then -# # Working directory clean -# echo "Git status is clean" -# else -# echo "Git status is not clean and contains uncommited changes" -# echo "Please make sure there are no changes" -# exit 1 -# fi - -echo "AdGuard Home CI script finished successfully" \ No newline at end of file diff --git a/go.sum b/go.sum index 6d05c0a3..19938814 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ github.com/AdguardTeam/dnsproxy v0.29.1 h1:Stc+JLh67C9K38vbrH2920+3FnbXKkFzYQqRiu5auUo= github.com/AdguardTeam/dnsproxy v0.29.1/go.mod h1:hOYFV9TW+pd5XKYz7KZf2FFD8SvSPqjyGTxUae86s58= -github.com/AdguardTeam/golibs v0.4.0 h1:4VX6LoOqFe9p9Gf55BeD8BvJD6M6RDYmgEiHrENE9KU= github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/golibs v0.4.2 h1:7M28oTZFoFwNmp8eGPb3ImmYbxGaJLyQXeIFVHjME0o= github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= @@ -42,15 +41,17 @@ github.com/go-test/deep v1.0.5 h1:AKODKU3pDH1RzZzm6YZu77YWtEAq6uh1rLIAQlay2qc= github.com/go-test/deep v1.0.5/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/logger v1.0.0 h1:xw9Ko9EcC5iAFprrjJ6oZco9UpzS5MQ4jAwghsLHdy4= github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= +github.com/gobuffalo/packr/v2 v2.5.1 h1:TFOeY2VoGamPjQLiNDT3mn//ytzk236VMO2j7iHxJR4= github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= @@ -58,13 +59,13 @@ github.com/joomcode/errorx v1.0.1 h1:CalpDWz14ZHd68fIqluJasJosAewpz2TFaJALrUxjrk github.com/joomcode/errorx v1.0.1/go.mod h1:kgco15ekB6cs+4Xjzo7SPeXzx38PbJzBwbnu9qfVNHQ= github.com/kardianos/service v1.0.0 h1:HgQS3mFfOlyntWX8Oke98JcJLqt1DBcHR4kxShpYef0= github.com/kardianos/service v1.0.0/go.mod h1:8CzDhVuCuugtsHyZoTvsOBuvonN/UDBvl0kH+BUxvbo= +github.com/karrick/godirwalk v1.10.12 h1:BqUm+LuJcXjGv1d2mj3gBiQyrQ57a0rYoAmhvJQ7RDU= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -90,11 +91,13 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shirou/gopsutil v2.20.3+incompatible h1:0JVooMPsT7A7HqEYdydp/OfjSOYSjhXV7w1hkKj/NPQ= github.com/shirou/gopsutil v2.20.3+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c h1:gqEdF4VwBu3lTKGHS9rXE9x1/pEaSwCXRLOZRF6qtlw= github.com/sparrc/go-ping v0.0.0-20190613174326-4e5b6552494c/go.mod h1:eMyUVp6f/5jnzM+3zahzl7q6UXLbgSc3MKg/+ow9QW0= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= @@ -102,9 +105,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -112,9 +113,7 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -124,37 +123,32 @@ golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425 h1:VvQyQJN0tSuecqgcIxMWnnfG5kSmgy9KZR9sW3W5QeA= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= diff --git a/home/control_update.go b/home/control_update.go index 6115fac1..d734f4d1 100644 --- a/home/control_update.go +++ b/home/control_update.go @@ -18,61 +18,20 @@ import ( "time" "github.com/AdguardTeam/AdGuardHome/util" - "github.com/AdguardTeam/golibs/log" ) -// Convert version.json data to our JSON response -func getVersionResp(data []byte) []byte { - versionJSON := make(map[string]interface{}) - err := json.Unmarshal(data, &versionJSON) - if err != nil { - log.Error("version.json: %s", err) - return []byte{} - } - - ret := make(map[string]interface{}) - ret["can_autoupdate"] = false - - var ok1, ok2, ok3 bool - ret["new_version"], ok1 = versionJSON["version"].(string) - ret["announcement"], ok2 = versionJSON["announcement"].(string) - ret["announcement_url"], ok3 = versionJSON["announcement_url"].(string) - selfUpdateMinVersion, ok4 := versionJSON["selfupdate_min_version"].(string) - if !ok1 || !ok2 || !ok3 || !ok4 { - log.Error("version.json: invalid data") - return []byte{} - } - - // the key is download_linux_arm or download_linux_arm64 for regular ARM versions - dloadName := fmt.Sprintf("download_%s_%s", runtime.GOOS, runtime.GOARCH) - if runtime.GOARCH == "arm" && ARMVersion == "5" { - // the key is download_linux_armv5 for ARMv5 - dloadName = fmt.Sprintf("download_%s_%sv%s", runtime.GOOS, runtime.GOARCH, ARMVersion) - } - _, ok := versionJSON[dloadName] - if ok && ret["new_version"] != versionString && versionString >= selfUpdateMinVersion { - canUpdate := true - - tlsConf := tlsConfigSettings{} - Context.tls.WriteDiskConfig(&tlsConf) - - if runtime.GOOS != "windows" && - ((tlsConf.Enabled && (tlsConf.PortHTTPS < 1024 || tlsConf.PortDNSOverTLS < 1024)) || - config.BindPort < 1024 || - config.DNS.Port < 1024) { - // On UNIX, if we're running under a regular user, - // but with CAP_NET_BIND_SERVICE set on a binary file, - // and we're listening on ports <1024, - // we won't be able to restart after we replace the binary file, - // because we'll lose CAP_NET_BIND_SERVICE capability. - canUpdate, _ = util.HaveAdminRights() - } - ret["can_autoupdate"] = canUpdate - } - - d, _ := json.Marshal(ret) - return d +type updateInfo struct { + pkgURL string // URL for the new package + pkgName string // Full path to package file + newVer string // New version string + updateDir string // Full path to the directory containing unpacked files from the new package + backupDir string // Full path to backup directory + configName string // Full path to the current configuration file + updateConfigName string // Full path to the configuration file to check by the new binary + curBinName string // Full path to the current executable file + bkpBinName string // Full path to the current executable file in backup directory + newBinName string // Full path to the new executable file } type getVersionJSONRequest struct { @@ -81,16 +40,18 @@ type getVersionJSONRequest struct { // Get the latest available version from the Internet func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) { - if Context.disableUpdate { return } req := getVersionJSONRequest{} - err := json.NewDecoder(r.Body).Decode(&req) - if err != nil { - httpError(w, http.StatusBadRequest, "JSON parse: %s", err) - return + var err error + if r.ContentLength != 0 { + err = json.NewDecoder(r.Body).Decode(&req) + if err != nil { + httpError(w, http.StatusBadRequest, "JSON parse: %s", err) + return + } } now := time.Now() @@ -103,7 +64,7 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) { if cached { log.Tracef("Returning cached data") w.Header().Set("Content-Type", "application/json") - w.Write(getVersionResp(data)) + _, _ = w.Write(getVersionResp(data)) return } } @@ -146,6 +107,80 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) { } } +// Perform an update procedure to the latest available version +func handleUpdate(w http.ResponseWriter, r *http.Request) { + if len(config.versionCheckJSON) == 0 { + httpError(w, http.StatusBadRequest, "/update request isn't allowed now") + return + } + + u, err := getUpdateInfo(config.versionCheckJSON) + if err != nil { + httpError(w, http.StatusInternalServerError, "%s", err) + return + } + + err = doUpdate(u) + if err != nil { + httpError(w, http.StatusInternalServerError, "%s", err) + return + } + + returnOK(w) + if f, ok := w.(http.Flusher); ok { + f.Flush() + } + + go finishUpdate(u) +} + +// Convert version.json data to our JSON response +func getVersionResp(data []byte) []byte { + versionJSON := make(map[string]interface{}) + err := json.Unmarshal(data, &versionJSON) + if err != nil { + log.Error("version.json: %s", err) + return []byte{} + } + + ret := make(map[string]interface{}) + ret["can_autoupdate"] = false + + var ok1, ok2, ok3 bool + ret["new_version"], ok1 = versionJSON["version"].(string) + ret["announcement"], ok2 = versionJSON["announcement"].(string) + ret["announcement_url"], ok3 = versionJSON["announcement_url"].(string) + selfUpdateMinVersion, ok4 := versionJSON["selfupdate_min_version"].(string) + if !ok1 || !ok2 || !ok3 || !ok4 { + log.Error("version.json: invalid data") + return []byte{} + } + + _, ok := getDownloadURL(versionJSON) + if ok && ret["new_version"] != versionString && versionString >= selfUpdateMinVersion { + canUpdate := true + + tlsConf := tlsConfigSettings{} + Context.tls.WriteDiskConfig(&tlsConf) + + if runtime.GOOS != "windows" && + ((tlsConf.Enabled && (tlsConf.PortHTTPS < 1024 || tlsConf.PortDNSOverTLS < 1024)) || + config.BindPort < 1024 || + config.DNS.Port < 1024) { + // On UNIX, if we're running under a regular user, + // but with CAP_NET_BIND_SERVICE set on a binary file, + // and we're listening on ports <1024, + // we won't be able to restart after we replace the binary file, + // because we'll lose CAP_NET_BIND_SERVICE capability. + canUpdate, _ = util.HaveAdminRights() + } + ret["can_autoupdate"] = canUpdate + } + + d, _ := json.Marshal(ret) + return d +} + // Copy file on disk func copyFile(src, dst string) error { d, e := ioutil.ReadFile(src) @@ -159,19 +194,6 @@ func copyFile(src, dst string) error { return nil } -type updateInfo struct { - pkgURL string // URL for the new package - pkgName string // Full path to package file - newVer string // New version string - updateDir string // Full path to the directory containing unpacked files from the new package - backupDir string // Full path to backup directory - configName string // Full path to the current configuration file - updateConfigName string // Full path to the configuration file to check by the new binary - curBinName string // Full path to the current executable file - bkpBinName string // Full path to the current executable file in backup directory - newBinName string // Full path to the new executable file -} - // Fill in updateInfo object func getUpdateInfo(jsonData []byte) (*updateInfo, error) { var u updateInfo @@ -184,7 +206,12 @@ func getUpdateInfo(jsonData []byte) (*updateInfo, error) { return nil, fmt.Errorf("JSON parse: %s", err) } - u.pkgURL = versionJSON[fmt.Sprintf("download_%s_%s", runtime.GOOS, runtime.GOARCH)].(string) + pkgURL, ok := getDownloadURL(versionJSON) + if !ok { + return nil, fmt.Errorf("failed to get download URL") + } + + u.pkgURL = pkgURL u.newVer = versionJSON["version"].(string) if len(u.pkgURL) == 0 || len(u.newVer) == 0 { return nil, fmt.Errorf("invalid JSON") @@ -226,6 +253,33 @@ func getUpdateInfo(jsonData []byte) (*updateInfo, error) { return &u, nil } +// getDownloadURL - gets download URL for the current GOOS/GOARCH +// returns +func getDownloadURL(json map[string]interface{}) (string, bool) { + var key string + + if runtime.GOARCH == "arm" && ARMVersion != "" { + // the key is: + // download_linux_armv5 for ARMv5 + // download_linux_armv6 for ARMv6 + // download_linux_armv7 for ARMv7 + key = fmt.Sprintf("download_%s_%sv%s", runtime.GOOS, runtime.GOARCH, ARMVersion) + } + + u, ok := json[key] + if !ok { + // the key is download_linux_arm or download_linux_arm64 for regular ARM versions + key = fmt.Sprintf("download_%s_%s", runtime.GOOS, runtime.GOARCH) + u, ok = json[key] + } + + if !ok { + return "", false + } + + return u.(string), true +} + // Unpack all files from .zip file to the specified directory // Existing files are overwritten // Return the list of files (not directories) written @@ -526,31 +580,3 @@ func finishUpdate(u *updateInfo) { // Unreachable code } } - -// Perform an update procedure to the latest available version -func handleUpdate(w http.ResponseWriter, r *http.Request) { - - if len(config.versionCheckJSON) == 0 { - httpError(w, http.StatusBadRequest, "/update request isn't allowed now") - return - } - - u, err := getUpdateInfo(config.versionCheckJSON) - if err != nil { - httpError(w, http.StatusInternalServerError, "%s", err) - return - } - - err = doUpdate(u) - if err != nil { - httpError(w, http.StatusInternalServerError, "%s", err) - return - } - - returnOK(w) - if f, ok := w.(http.Flusher); ok { - f.Flush() - } - - go finishUpdate(u) -} diff --git a/home/home.go b/home/home.go index 077455e8..79cf0843 100644 --- a/home/home.go +++ b/home/home.go @@ -134,6 +134,15 @@ func Main(version string, channel string, armVer string) { run(args) } +// version - returns the current version string +func version() string { + msg := "AdGuard Home, version %s, channel %s, arch %s %s" + if ARMVersion != "" { + msg = msg + " v" + ARMVersion + } + return fmt.Sprintf(msg, versionString, updateChannel, runtime.GOOS, runtime.GOARCH) +} + // run initializes configuration and runs the AdGuard Home // run is a blocking method! // nolint @@ -153,11 +162,7 @@ func run(args options) { configureLogger(args) // print the first message after logger is configured - msg := "AdGuard Home, version %s, channel %s, arch %s %s" - if ARMVersion != "" { - msg = msg + " v" + ARMVersion - } - log.Printf(msg, versionString, updateChannel, runtime.GOOS, runtime.GOARCH) + log.Println(version()) log.Debug("Current working directory is %s", Context.workDir) if args.runningAsService { log.Info("AdGuard Home is running as a service") @@ -564,7 +569,7 @@ func loadOptions() options { {"verbose", "v", "Enable verbose output", nil, func() { o.verbose = true }}, {"glinet", "", "Run in GL-Inet compatibility mode", nil, func() { o.glinetMode = true }}, {"version", "", "Show the version and exit", nil, func() { - fmt.Printf("AdGuardHome %s\n", versionString) + fmt.Println(version()) os.Exit(0) }}, {"help", "", "Print this help", nil, func() { diff --git a/main.go b/main.go index 449e3834..eebcd5c4 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,6 @@ +//go:generate go install -v github.com/gobuffalo/packr/packr +//go:generate packr clean +//go:generate packr -z package main import ( diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile deleted file mode 100644 index 6677d928..00000000 --- a/packaging/docker/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM golang:alpine AS build - -RUN apk add --update git make build-base npm && \ - rm -rf /var/cache/apk/* - -WORKDIR /src/AdGuardHome -COPY . /src/AdGuardHome -RUN make - -FROM alpine:latest -LABEL maintainer="AdGuard Team " - -# Update CA certs -RUN apk --no-cache --update add ca-certificates libcap && \ - rm -rf /var/cache/apk/* && \ - mkdir -p /opt/adguardhome/conf /opt/adguardhome/work && \ - chown -R nobody: /opt/adguardhome - -COPY --from=build --chown=nobody:nogroup /src/AdGuardHome/AdGuardHome /opt/adguardhome/AdGuardHome - -RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome - -EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp - -VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"] - -WORKDIR /opt/adguardhome/work - -#USER nobody - -ENTRYPOINT ["/opt/adguardhome/AdGuardHome"] -CMD ["-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"] diff --git a/packaging/docker/Dockerfile.hub b/packaging/docker/Dockerfile.hub deleted file mode 100644 index 0e11574e..00000000 --- a/packaging/docker/Dockerfile.hub +++ /dev/null @@ -1,23 +0,0 @@ -FROM alpine:latest -LABEL maintainer="AdGuard Team " - -# Update CA certs -RUN apk --no-cache --update add ca-certificates libcap && \ - rm -rf /var/cache/apk/* && \ - mkdir -p /opt/adguardhome/conf /opt/adguardhome/work && \ - chown -R nobody: /opt/adguardhome - -COPY --chown=nobody:nogroup ./AdGuardHome /opt/adguardhome/AdGuardHome - -RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome - -EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp - -VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"] - -WORKDIR /opt/adguardhome/work - -#USER nobody - -ENTRYPOINT ["/opt/adguardhome/AdGuardHome"] -CMD ["-h", "0.0.0.0", "-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"] diff --git a/packaging/docker/README.md b/packaging/docker/README.md deleted file mode 100644 index 0d7ff06f..00000000 --- a/packaging/docker/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Docker images - -* `Dockerfile` is used for local development. Build it using `make docker` command. - -* `Dockerfile.hub` is used to publish AdGuard images to Docker Hub: https://hub.docker.com/r/adguard/adguardhome - Check out `build_docker.sh` for the details. \ No newline at end of file diff --git a/packaging/snap/README.md b/packaging/snap/README.md deleted file mode 100644 index 764100ff..00000000 --- a/packaging/snap/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Snapcraft - -Configuration for our snap. - -Check out `build_snap.sh` for more details. \ No newline at end of file diff --git a/packaging/snap/snapcraft.yaml b/packaging/snap/snapcraft.yaml deleted file mode 100644 index 1d6c5274..00000000 --- a/packaging/snap/snapcraft.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: adguard-home -base: core18 -version: 'dev_version' -summary: Network-wide ads & trackers blocking DNS server -description: | - AdGuard Home is a network-wide software for blocking ads & tracking. After - you set it up, it'll cover ALL your home devices, and you don't need any - client-side software for that. - - It operates as a DNS server that re-routes tracking domains to a "black hole," - thus preventing your devices from connecting to those servers. It's based - on software we use for our public AdGuard DNS servers -- both share a lot - of common code. -grade: stable -confinement: strict - -parts: - adguard-home: - plugin: make - source: . - build-snaps: [ node/13/stable, go ] - build-packages: [ git, build-essential ] - override-build: | - make clean - make - cp AdGuardHome ${SNAPCRAFT_PART_INSTALL}/ -apps: - adguard-home: - command: AdGuardHome -w ${SNAP_DATA} --no-check-update - plugs: [ network-bind ] - daemon: simple - restart-condition: always \ No newline at end of file diff --git a/snapcraft.yaml b/snapcraft.yaml deleted file mode 100644 index c5cda82b..00000000 --- a/snapcraft.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# Note that this snapcraft.yaml file is used for automatic Edge channel builds ONLY! -# We use packaging/snap/snapcraft.yaml for beta and release builds -# Check out build_snap.sh for more details -name: adguard-home -base: core18 -version: 'edge' -summary: Network-wide ads & trackers blocking DNS server -description: | - AdGuard Home is a network-wide software for blocking ads & tracking. After - you set it up, it'll cover ALL your home devices, and you don't need any - client-side software for that. - - It operates as a DNS server that re-routes tracking domains to a "black hole," - thus preventing your devices from connecting to those servers. It's based - on software we use for our public AdGuard DNS servers -- both share a lot - of common code. -grade: stable -confinement: strict - -architectures: - - build-on: amd64 - - build-on: armhf - - build-on: i386 - - build-on: arm64 - -parts: - adguard-home: - plugin: make - source: . - build-snaps: [ node/13/stable, go ] - build-packages: [ git, build-essential ] - override-build: | - make clean - make - cp AdGuardHome ${SNAPCRAFT_PART_INSTALL}/ -apps: - adguard-home: - command: AdGuardHome -w ${SNAP_DATA} --no-check-update - plugs: [ network-bind ] - daemon: simple - restart-condition: always diff --git a/tools.go b/tools.go new file mode 100644 index 00000000..350f00a6 --- /dev/null +++ b/tools.go @@ -0,0 +1,8 @@ +// +build tools + +package tools + +import ( + // Import packr + _ "github.com/gobuffalo/packr/packr" +)