Merge branch 'main' into flake-build-env

This commit is contained in:
Kristoffer Dalby 2022-04-21 09:21:10 +01:00 committed by GitHub
commit 5c285afda5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 262 additions and 162 deletions

View file

@ -7,5 +7,5 @@ contact_links:
url: "https://github.com/juanfont/headscale/blob/main/docs" url: "https://github.com/juanfont/headscale/blob/main/docs"
about: "Find documentation about how to configure and run headscale." about: "Find documentation about how to configure and run headscale."
- name: "headscale Discord community" - name: "headscale Discord community"
url: "https://discord.com/invite/XcQxk2VHjx" url: "https://discord.gg/xGj2TuqyxY"
about: "Please ask and answer questions about usage of headscale here." about: "Please ask and answer questions about usage of headscale here."

View file

@ -18,7 +18,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: 1.17.7 go-version: 1.18.0
- name: Install dependencies - name: Install dependencies
run: | run: |

View file

@ -1,6 +1,14 @@
# CHANGELOG # CHANGELOG
## 0.15.0 (2022-xx-xx) ## 0.16.0 (2022-xx-xx)
### Changes
- Headscale fails to serve if the ACL policy file cannot be parsed [#537](https://github.com/juanfont/headscale/pull/537)
- Fix labels cardinality error when registering unknown pre-auth key [#519](https://github.com/juanfont/headscale/pull/519)
- Fix send on closed channel crash in polling [#542](https://github.com/juanfont/headscale/pull/542)
## 0.15.0 (2022-03-20)
**Note:** Take a backup of your database before upgrading. **Note:** Take a backup of your database before upgrading.
@ -19,7 +27,7 @@
- Users can now use emails in ACL's groups [#372](https://github.com/juanfont/headscale/issues/372) - Users can now use emails in ACL's groups [#372](https://github.com/juanfont/headscale/issues/372)
- Add shorthand aliases for commands and subcommands [#376](https://github.com/juanfont/headscale/pull/376) - Add shorthand aliases for commands and subcommands [#376](https://github.com/juanfont/headscale/pull/376)
- Add `/windows` endpoint for Windows configuration instructions + registry file download [#392](https://github.com/juanfont/headscale/pull/392) - Add `/windows` endpoint for Windows configuration instructions + registry file download [#392](https://github.com/juanfont/headscale/pull/392)
- Added embedded DERP server into Headscale [#388](https://github.com/juanfont/headscale/pull/388) - Added embedded DERP (and STUN) server into Headscale [#388](https://github.com/juanfont/headscale/pull/388)
### Changes ### Changes
@ -29,6 +37,8 @@
- Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374) - Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374)
- Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371) - Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371)
- Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363) - Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363)
- Fix a bug that prevented the use of `tailscale logout` with OIDC [#508](https://github.com/juanfont/headscale/issues/508)
- Added Tailscale repo HEAD and unstable releases channel to the integration tests targets [#513](https://github.com/juanfont/headscale/pull/513)
## 0.14.0 (2022-02-24) ## 0.14.0 (2022-02-24)

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-bullseye AS build FROM docker.io/golang:1.18.0-bullseye AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-alpine AS build FROM docker.io/golang:1.18.0-alpine AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

View file

@ -1,5 +1,5 @@
# Builder image # Builder image
FROM docker.io/golang:1.17.8-bullseye AS build FROM docker.io/golang:1.18.0-bullseye AS build
ENV GOPATH /go ENV GOPATH /go
WORKDIR /go/src/headscale WORKDIR /go/src/headscale

View file

@ -1,11 +1,12 @@
FROM ubuntu:latest FROM ubuntu:latest
ARG TAILSCALE_VERSION ARG TAILSCALE_VERSION=*
ARG TAILSCALE_CHANNEL=stable
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y gnupg curl \ && apt-get install -y gnupg curl \
&& curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.gpg | apt-key add - \ && curl -fsSL https://pkgs.tailscale.com/${TAILSCALE_CHANNEL}/ubuntu/focal.gpg | apt-key add - \
&& curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.list | tee /etc/apt/sources.list.d/tailscale.list \ && curl -fsSL https://pkgs.tailscale.com/${TAILSCALE_CHANNEL}/ubuntu/focal.list | tee /etc/apt/sources.list.d/tailscale.list \
&& apt-get update \ && apt-get update \
&& apt-get install -y ca-certificates tailscale=${TAILSCALE_VERSION} dnsutils \ && apt-get install -y ca-certificates tailscale=${TAILSCALE_VERSION} dnsutils \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

21
Dockerfile.tailscale-HEAD Normal file
View file

@ -0,0 +1,21 @@
FROM golang:latest
RUN apt-get update \
&& apt-get install -y ca-certificates dnsutils git iptables \
&& rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/tailscale/tailscale.git
WORKDIR tailscale
RUN sh build_dist.sh tailscale.com/cmd/tailscale
RUN sh build_dist.sh tailscale.com/cmd/tailscaled
RUN cp tailscale /usr/local/bin/
RUN cp tailscaled /usr/local/bin/
ADD integration_test/etc_embedded_derp/tls/server.crt /usr/local/share/ca-certificates/
RUN chmod 644 /usr/local/share/ca-certificates/server.crt
RUN update-ca-certificates

View file

@ -1,5 +1,5 @@
# Calculate version # Calculate version
version = $(shell ./scripts/version-at-commit.sh) version = $(git describe --always --tags --dirty)
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
@ -10,7 +10,7 @@ PROTO_SOURCES = $(call rwildcard,,*.proto)
build: build:
GGO_ENABLED=0 go build -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go CGO_ENABLED=0 go build -trimpath -buildmode=pie -mod=readonly -ldflags "-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$(version)" cmd/headscale/headscale.go
dev: lint test build dev: lint test build

View file

@ -4,7 +4,7 @@
An open source, self-hosted implementation of the Tailscale control server. An open source, self-hosted implementation of the Tailscale control server.
Join our [Discord](https://discord.gg/XcQxk2VHjx) server for a chat. Join our [Discord](https://discord.gg/c84AZQhmpx) server for a chat.
**Note:** Always select the same GitHub tag as the released version you use **Note:** Always select the same GitHub tag as the released version you use
to ensure you have the correct example configuration and documentation. to ensure you have the correct example configuration and documentation.
@ -232,6 +232,13 @@ make build
<sub style="font-size:14px"><b>Nico</b></sub> <sub style="font-size:14px"><b>Nico</b></sub>
</a> </a>
</td> </td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/Niek>
<img src=https://avatars.githubusercontent.com/u/213140?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Niek van der Maas/>
<br />
<sub style="font-size:14px"><b>Niek van der Maas</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/negbie> <a href=https://github.com/negbie>
<img src=https://avatars.githubusercontent.com/u/20154956?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Eugen Biegler/> <img src=https://avatars.githubusercontent.com/u/20154956?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Eugen Biegler/>
@ -239,6 +246,8 @@ make build
<sub style="font-size:14px"><b>Eugen Biegler</b></sub> <sub style="font-size:14px"><b>Eugen Biegler</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/qbit> <a href=https://github.com/qbit>
<img src=https://avatars.githubusercontent.com/u/68368?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Aaron Bieber/> <img src=https://avatars.githubusercontent.com/u/68368?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Aaron Bieber/>
@ -246,8 +255,6 @@ make build
<sub style="font-size:14px"><b>Aaron Bieber</b></sub> <sub style="font-size:14px"><b>Aaron Bieber</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/fdelucchijr> <a href=https://github.com/fdelucchijr>
<img src=https://avatars.githubusercontent.com/u/69133647?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Fernando De Lucchi/> <img src=https://avatars.githubusercontent.com/u/69133647?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Fernando De Lucchi/>
@ -283,6 +290,15 @@ make build
<sub style="font-size:14px"><b>Paul Tötterman</b></sub> <sub style="font-size:14px"><b>Paul Tötterman</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/artemklevtsov>
<img src=https://avatars.githubusercontent.com/u/603798?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Artem Klevtsov/>
<br />
<sub style="font-size:14px"><b>Artem Klevtsov</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/cmars> <a href=https://github.com/cmars>
<img src=https://avatars.githubusercontent.com/u/23741?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Casey Marshall/> <img src=https://avatars.githubusercontent.com/u/23741?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Casey Marshall/>
@ -290,8 +306,6 @@ make build
<sub style="font-size:14px"><b>Casey Marshall</b></sub> <sub style="font-size:14px"><b>Casey Marshall</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/SilverBut> <a href=https://github.com/SilverBut>
<img src=https://avatars.githubusercontent.com/u/6560655?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Silver Bullet/> <img src=https://avatars.githubusercontent.com/u/6560655?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Silver Bullet/>
@ -320,6 +334,8 @@ make build
<sub style="font-size:14px"><b>thomas</b></sub> <sub style="font-size:14px"><b>thomas</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/aberoham> <a href=https://github.com/aberoham>
<img src=https://avatars.githubusercontent.com/u/586805?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Abraham Ingersoll/> <img src=https://avatars.githubusercontent.com/u/586805?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Abraham Ingersoll/>
@ -328,14 +344,12 @@ make build
</a> </a>
</td> </td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/artemklevtsov> <a href=https://github.com/aofei>
<img src=https://avatars.githubusercontent.com/u/603798?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Artem Klevtsov/> <img src=https://avatars.githubusercontent.com/u/5037285?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Aofei Sheng/>
<br /> <br />
<sub style="font-size:14px"><b>Artem Klevtsov</b></sub> <sub style="font-size:14px"><b>Aofei Sheng</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/awoimbee> <a href=https://github.com/awoimbee>
<img src=https://avatars.githubusercontent.com/u/22431493?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Arthur Woimbée/> <img src=https://avatars.githubusercontent.com/u/22431493?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Arthur Woimbée/>
@ -350,6 +364,13 @@ make build
<sub style="font-size:14px"><b>Bryan Stenson</b></sub> <sub style="font-size:14px"><b>Bryan Stenson</b></sub>
</a> </a>
</td> </td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/yangchuansheng>
<img src=https://avatars.githubusercontent.com/u/15308462?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt= Carson Yang/>
<br />
<sub style="font-size:14px"><b> Carson Yang</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/fkr> <a href=https://github.com/fkr>
<img src=https://avatars.githubusercontent.com/u/51063?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Felix Kronlage-Dammers/> <img src=https://avatars.githubusercontent.com/u/51063?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Felix Kronlage-Dammers/>
@ -357,6 +378,8 @@ make build
<sub style="font-size:14px"><b>Felix Kronlage-Dammers</b></sub> <sub style="font-size:14px"><b>Felix Kronlage-Dammers</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/felixonmars> <a href=https://github.com/felixonmars>
<img src=https://avatars.githubusercontent.com/u/1006477?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Felix Yan/> <img src=https://avatars.githubusercontent.com/u/1006477?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Felix Yan/>
@ -378,8 +401,6 @@ make build
<sub style="font-size:14px"><b>Jamie Greeff</b></sub> <sub style="font-size:14px"><b>Jamie Greeff</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/jimt> <a href=https://github.com/jimt>
<img src=https://avatars.githubusercontent.com/u/180326?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Jim Tittsler/> <img src=https://avatars.githubusercontent.com/u/180326?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Jim Tittsler/>
@ -401,6 +422,8 @@ make build
<sub style="font-size:14px"><b>rcursaru</b></sub> <sub style="font-size:14px"><b>rcursaru</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/renovate-bot> <a href=https://github.com/renovate-bot>
<img src=https://avatars.githubusercontent.com/u/25180681?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=WhiteSource Renovate/> <img src=https://avatars.githubusercontent.com/u/25180681?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=WhiteSource Renovate/>
@ -422,8 +445,6 @@ make build
<sub style="font-size:14px"><b>Shaanan Cohney</b></sub> <sub style="font-size:14px"><b>Shaanan Cohney</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/m-tanner-dev0> <a href=https://github.com/m-tanner-dev0>
<img src=https://avatars.githubusercontent.com/u/97977342?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Tanner/> <img src=https://avatars.githubusercontent.com/u/97977342?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Tanner/>
@ -445,6 +466,8 @@ make build
<sub style="font-size:14px"><b>The Gitter Badger</b></sub> <sub style="font-size:14px"><b>The Gitter Badger</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/tianon> <a href=https://github.com/tianon>
<img src=https://avatars.githubusercontent.com/u/161631?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Tianon Gravi/> <img src=https://avatars.githubusercontent.com/u/161631?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Tianon Gravi/>
@ -466,8 +489,6 @@ make build
<sub style="font-size:14px"><b>Yang Bin</b></sub> <sub style="font-size:14px"><b>Yang Bin</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/zekker6> <a href=https://github.com/zekker6>
<img src=https://avatars.githubusercontent.com/u/1367798?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Zakhar Bessarab/> <img src=https://avatars.githubusercontent.com/u/1367798?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Zakhar Bessarab/>
@ -489,6 +510,8 @@ make build
<sub style="font-size:14px"><b>bravechamp</b></sub> <sub style="font-size:14px"><b>bravechamp</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/derelm> <a href=https://github.com/derelm>
<img src=https://avatars.githubusercontent.com/u/465155?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=derelm/> <img src=https://avatars.githubusercontent.com/u/465155?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=derelm/>
@ -496,6 +519,13 @@ make build
<sub style="font-size:14px"><b>derelm</b></sub> <sub style="font-size:14px"><b>derelm</b></sub>
</a> </a>
</td> </td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/nning>
<img src=https://avatars.githubusercontent.com/u/557430?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=henning mueller/>
<br />
<sub style="font-size:14px"><b>henning mueller</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/ignoramous> <a href=https://github.com/ignoramous>
<img src=https://avatars.githubusercontent.com/u/852289?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=ignoramous/> <img src=https://avatars.githubusercontent.com/u/852289?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=ignoramous/>
@ -510,8 +540,6 @@ make build
<sub style="font-size:14px"><b>lion24</b></sub> <sub style="font-size:14px"><b>lion24</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/pernila> <a href=https://github.com/pernila>
<img src=https://avatars.githubusercontent.com/u/12460060?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=pernila/> <img src=https://avatars.githubusercontent.com/u/12460060?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=pernila/>
@ -526,6 +554,8 @@ make build
<sub style="font-size:14px"><b>Wakeful-Cloud</b></sub> <sub style="font-size:14px"><b>Wakeful-Cloud</b></sub>
</a> </a>
</td> </td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/xpzouying> <a href=https://github.com/xpzouying>
<img src=https://avatars.githubusercontent.com/u/3946563?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=zy/> <img src=https://avatars.githubusercontent.com/u/3946563?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=zy/>

2
api.go
View file

@ -573,7 +573,7 @@ func (h *Headscale) handleAuthKey(
machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name).
Inc() Inc()
} else { } else {
machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error").Inc() machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", "unknown").Inc()
} }
return return

23
app.go
View file

@ -47,6 +47,14 @@ import (
"tailscale.com/types/key" "tailscale.com/types/key"
) )
const (
errSTUNAddressNotSet = Error("STUN address not set")
errUnsupportedDatabase = Error("unsupported DB")
errUnsupportedLetsEncryptChallengeType = Error(
"unknown value for Lets Encrypt challenge type",
)
)
const ( const (
AuthPrefix = "Bearer " AuthPrefix = "Bearer "
Postgres = "postgres" Postgres = "postgres"
@ -58,11 +66,6 @@ const (
registerCacheExpiration = time.Minute * 15 registerCacheExpiration = time.Minute * 15
registerCacheCleanup = time.Minute * 20 registerCacheCleanup = time.Minute * 20
errUnsupportedDatabase = Error("unsupported DB")
errUnsupportedLetsEncryptChallengeType = Error(
"unknown value for Lets Encrypt challenge type",
)
DisabledClientAuth = "disabled" DisabledClientAuth = "disabled"
RelaxedClientAuth = "relaxed" RelaxedClientAuth = "relaxed"
EnforcedClientAuth = "enforced" EnforcedClientAuth = "enforced"
@ -124,7 +127,6 @@ type DERPConfig struct {
ServerRegionID int ServerRegionID int
ServerRegionCode string ServerRegionCode string
ServerRegionName string ServerRegionName string
STUNEnabled bool
STUNAddr string STUNAddr string
URLs []url.URL URLs []url.URL
Paths []string Paths []string
@ -500,10 +502,13 @@ func (h *Headscale) Serve() error {
h.DERPMap = GetDERPMap(h.cfg.DERP) h.DERPMap = GetDERPMap(h.cfg.DERP)
if h.cfg.DERP.ServerEnabled { if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region // When embedded DERP is enabled we always need a STUN server
if h.cfg.DERP.STUNEnabled { if h.cfg.DERP.STUNAddr == "" {
go h.ServeSTUN() return errSTUNAddressNotSet
} }
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
go h.ServeSTUN()
} }
if h.cfg.DERP.AutoUpdate { if h.cfg.DERP.AutoUpdate {

View file

@ -23,7 +23,7 @@ func init() {
apiKeysCmd.AddCommand(listAPIKeys) apiKeysCmd.AddCommand(listAPIKeys)
createAPIKeyCmd.Flags(). createAPIKeyCmd.Flags().
DurationP("expiration", "e", DefaultAPIKeyExpiry, "Human-readable expiration of the key (30m, 24h, 365d...)") DurationP("expiration", "e", DefaultAPIKeyExpiry, "Human-readable expiration of the key (e.g. 30m, 24h)")
apiKeysCmd.AddCommand(createAPIKeyCmd) apiKeysCmd.AddCommand(createAPIKeyCmd)

View file

@ -31,7 +31,7 @@ func init() {
createPreAuthKeyCmd.PersistentFlags(). createPreAuthKeyCmd.PersistentFlags().
Bool("ephemeral", false, "Preauthkey for ephemeral nodes") Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
createPreAuthKeyCmd.Flags(). createPreAuthKeyCmd.Flags().
DurationP("expiration", "e", DefaultPreAuthKeyExpiry, "Human-readable expiration of the key (30m, 24h, 365d...)") DurationP("expiration", "e", DefaultPreAuthKeyExpiry, "Human-readable expiration of the key (e.g. 30m, 24h)")
} }
var preauthkeysCmd = &cobra.Command{ var preauthkeysCmd = &cobra.Command{

View file

@ -55,6 +55,9 @@ func LoadConfig(path string) error {
viper.SetDefault("dns_config", nil) viper.SetDefault("dns_config", nil)
viper.SetDefault("derp.server.enabled", false)
viper.SetDefault("derp.server.stun.enabled", true)
viper.SetDefault("unix_socket", "/var/run/headscale.sock") viper.SetDefault("unix_socket", "/var/run/headscale.sock")
viper.SetDefault("unix_socket_permission", "0o770") viper.SetDefault("unix_socket_permission", "0o770")
@ -121,8 +124,11 @@ func GetDERPConfig() headscale.DERPConfig {
serverRegionID := viper.GetInt("derp.server.region_id") serverRegionID := viper.GetInt("derp.server.region_id")
serverRegionCode := viper.GetString("derp.server.region_code") serverRegionCode := viper.GetString("derp.server.region_code")
serverRegionName := viper.GetString("derp.server.region_name") serverRegionName := viper.GetString("derp.server.region_name")
stunEnabled := viper.GetBool("derp.server.stun.enabled") stunAddr := viper.GetString("derp.server.stun_listen_addr")
stunAddr := viper.GetString("derp.server.stun.listen_addr")
if serverEnabled && stunAddr == "" {
log.Fatal().Msg("derp.server.stun_listen_addr must be set if derp.server.enabled is true")
}
urlStrs := viper.GetStringSlice("derp.urls") urlStrs := viper.GetStringSlice("derp.urls")
@ -149,7 +155,6 @@ func GetDERPConfig() headscale.DERPConfig {
ServerRegionID: serverRegionID, ServerRegionID: serverRegionID,
ServerRegionCode: serverRegionCode, ServerRegionCode: serverRegionCode,
ServerRegionName: serverRegionName, ServerRegionName: serverRegionName,
STUNEnabled: stunEnabled,
STUNAddr: stunAddr, STUNAddr: stunAddr,
URLs: urls, URLs: urls,
Paths: paths, Paths: paths,
@ -403,7 +408,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
aclPath := absPath(viper.GetString("acl_policy_path")) aclPath := absPath(viper.GetString("acl_policy_path"))
err = app.LoadACLPolicy(aclPath) err = app.LoadACLPolicy(aclPath)
if err != nil { if err != nil {
log.Error(). log.Fatal().
Str("path", aclPath). Str("path", aclPath).
Err(err). Err(err).
Msg("Could not load the ACL policy") Msg("Could not load the ACL policy")

View file

@ -69,11 +69,11 @@ derp:
region_code: "headscale" region_code: "headscale"
region_name: "Headscale Embedded DERP" region_name: "Headscale Embedded DERP"
# If enabled, also listens in UDP at the configured address for STUN connections to help on NAT traversal # Listens in UDP at the configured address for STUN connections to help on NAT traversal.
# When the embedded DERP server is enabled stun_listen_addr MUST be defined.
#
# For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/ # For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/
stun: stun_listen_addr: "0.0.0.0:3478"
enabled: false
listen_addr: "0.0.0.0:3478"
# List of externally available DERP maps encoded in JSON # List of externally available DERP maps encoded in JSON
urls: urls:

View file

@ -12,4 +12,4 @@ regions:
ipv6: "2604:a880:400:d1::828:b001" ipv6: "2604:a880:400:d1::828:b001"
stunport: 0 stunport: 0
stunonly: false stunonly: false
derptestport: 0 derpport: 0

View file

@ -148,7 +148,9 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
case <-ticker.C: case <-ticker.C:
log.Info().Msg("Fetching DERPMap updates") log.Info().Msg("Fetching DERPMap updates")
h.DERPMap = GetDERPMap(h.cfg.DERP) h.DERPMap = GetDERPMap(h.cfg.DERP)
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region if h.cfg.DERP.ServerEnabled {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
}
namespaces, err := h.ListNamespaces() namespaces, err := h.ListNamespaces()
if err != nil { if err != nil {

View file

@ -77,17 +77,15 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) {
}, },
} }
if h.cfg.DERP.STUNEnabled { _, portSTUNStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr)
_, portStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) if err != nil {
if err != nil { return tailcfg.DERPRegion{}, err
return tailcfg.DERPRegion{}, err
}
port, err := strconv.Atoi(portStr)
if err != nil {
return tailcfg.DERPRegion{}, err
}
localDERPregion.Nodes[0].STUNPort = port
} }
portSTUN, err := strconv.Atoi(portSTUNStr)
if err != nil {
return tailcfg.DERPRegion{}, err
}
localDERPregion.Nodes[0].STUNPort = portSTUN
return localDERPregion, nil return localDERPregion, nil
} }

View file

@ -3,7 +3,7 @@
This page contains the official and community contributed documentation for `headscale`. This page contains the official and community contributed documentation for `headscale`.
If you are having trouble with following the documentation or get unexpected results, If you are having trouble with following the documentation or get unexpected results,
please ask on [Discord](https://discord.gg/XcQxk2VHjx) instead of opening an Issue. please ask on [Discord](https://discord.gg/c84AZQhmpx) instead of opening an Issue.
## Official documentation ## Official documentation

View file

@ -14,8 +14,8 @@ not work with alternatives like [Podman](https://podman.io). The Docker image ca
1. Prepare a directory on the host Docker node in your directory of choice, used to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: 1. Prepare a directory on the host Docker node in your directory of choice, used to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
```shell ```shell
mkdir ./headscale && cd ./headscale mkdir -p ./headscale/config
mkdir ./config cd ./headscale
``` ```
2. Create an empty SQlite datebase in the headscale directory: 2. Create an empty SQlite datebase in the headscale directory:
@ -45,6 +45,17 @@ touch ./config/config.yaml
``` ```
Modify the config file to your preferences before launching Docker container. Modify the config file to your preferences before launching Docker container.
Here are some settings that you likely want:
```yaml
server_url: http://your-host-name:8080 # Change to your hostname or host IP
# Listen to 0.0.0.0 so it's accessible outside the container
metrics_listen_addr: 0.0.0.0:9090
# The default /var/lib/headscale path is not writable in the container
private_key_path: /etc/headscale/private.key
# The default /var/lib/headscale path is not writable in the container
db_path: /etc/headscale/db.sqlite
```
4. Start the headscale server while working in the host headscale directory: 4. Start the headscale server while working in the host headscale directory:
@ -61,6 +72,8 @@ docker run \
``` ```
Note: use `0.0.0.0:8080:8080` instead of `127.0.0.1:8080:8080` if you want to expose the container externally.
This command will mount `config/` under `/etc/headscale`, forward port 8080 out of the container so the This command will mount `config/` under `/etc/headscale`, forward port 8080 out of the container so the
`headscale` instance becomes available and then detach so headscale runs in the background. `headscale` instance becomes available and then detach so headscale runs in the background.
@ -87,7 +100,8 @@ curl http://127.0.0.1:9090/metrics
6. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)): 6. Create a namespace ([tailnet](https://tailscale.com/kb/1136/tailnet/)):
```shell ```shell
docker exec headscale -- headscale namespaces create myfirstnamespace docker exec headscale \
headscale namespaces create myfirstnamespace
``` ```
### Register a machine (normal login) ### Register a machine (normal login)
@ -101,7 +115,7 @@ tailscale up --login-server YOUR_HEADSCALE_URL
To register a machine when running `headscale` in a container, take the headscale command and pass it to the container: To register a machine when running `headscale` in a container, take the headscale command and pass it to the container:
```shell ```shell
docker exec headscale -- \ docker exec headscale \
headscale --namespace myfirstnamespace nodes register --key <YOU_+MACHINE_KEY> headscale --namespace myfirstnamespace nodes register --key <YOU_+MACHINE_KEY>
``` ```
@ -110,7 +124,7 @@ docker exec headscale -- \
Generate a key using the command line: Generate a key using the command line:
```shell ```shell
docker exec headscale -- \ docker exec headscale \
headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h
``` ```

View file

@ -178,7 +178,7 @@ systemctl status headscale
Verify `headscale` is available: Verify `headscale` is available:
```shell ```shell
curl http://127.0.0.1:8080/metrics curl http://127.0.0.1:9090/metrics
``` ```
`headscale` will now run in the background and start at boot. `headscale` will now run in the background and start at boot.

2
go.mod
View file

@ -1,6 +1,6 @@
module github.com/juanfont/headscale module github.com/juanfont/headscale
go 1.17 go 1.18
require ( require (
github.com/AlecAivazis/survey/v2 v2.3.2 github.com/AlecAivazis/survey/v2 v2.3.2

View file

@ -72,7 +72,7 @@ func (s *IntegrationCLITestSuite) SetupTest() {
if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil {
s.headscale = *pheadscale s.headscale = *pheadscale
} else { } else {
log.Fatalf("Could not start resource: %s", err) log.Fatalf("Could not start headscale container: %s", err)
} }
fmt.Println("Created headscale container") fmt.Println("Created headscale container")

View file

@ -20,7 +20,7 @@ var (
IpPrefix4 = netaddr.MustParseIPPrefix("100.64.0.0/10") IpPrefix4 = netaddr.MustParseIPPrefix("100.64.0.0/10")
IpPrefix6 = netaddr.MustParseIPPrefix("fd7a:115c:a1e0::/48") IpPrefix6 = netaddr.MustParseIPPrefix("fd7a:115c:a1e0::/48")
tailscaleVersions = []string{"1.22.0", "1.20.4", "1.18.2", "1.16.2", "1.14.3", "1.12.3"} tailscaleVersions = []string{"head", "unstable", "1.22.2", "1.20.4", "1.18.2", "1.16.2", "1.14.3", "1.12.3"}
) )
type TestNamespace struct { type TestNamespace struct {
@ -128,6 +128,49 @@ func DockerAllowNetworkAdministration(config *docker.HostConfig) {
}) })
} }
func getDockerBuildOptions(version string) *dockertest.BuildOptions {
var tailscaleBuildOptions *dockertest.BuildOptions
switch version {
case "head":
tailscaleBuildOptions = &dockertest.BuildOptions{
Dockerfile: "Dockerfile.tailscale-HEAD",
ContextDir: ".",
BuildArgs: []docker.BuildArg{},
}
case "unstable":
tailscaleBuildOptions = &dockertest.BuildOptions{
Dockerfile: "Dockerfile.tailscale",
ContextDir: ".",
BuildArgs: []docker.BuildArg{
{
Name: "TAILSCALE_VERSION",
Value: "*", // Installs the latest version https://askubuntu.com/a/824926
},
{
Name: "TAILSCALE_CHANNEL",
Value: "unstable",
},
},
}
default:
tailscaleBuildOptions = &dockertest.BuildOptions{
Dockerfile: "Dockerfile.tailscale",
ContextDir: ".",
BuildArgs: []docker.BuildArg{
{
Name: "TAILSCALE_VERSION",
Value: version,
},
{
Name: "TAILSCALE_CHANNEL",
Value: "stable",
},
},
}
}
return tailscaleBuildOptions
}
func getIPs( func getIPs(
tailscales map[string]dockertest.Resource, tailscales map[string]dockertest.Resource,
) (map[string][]netaddr.IP, error) { ) (map[string][]netaddr.IP, error) {

View file

@ -121,7 +121,7 @@ func (s *IntegrationDERPTestSuite) SetupSuite() {
if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil {
s.headscale = *pheadscale s.headscale = *pheadscale
} else { } else {
log.Fatalf("Could not start resource: %s", err) log.Fatalf("Could not start headscale container: %s", err)
} }
log.Println("Created headscale container to test DERP") log.Println("Created headscale container to test DERP")
@ -245,16 +245,8 @@ func (s *IntegrationDERPTestSuite) Join(
func (s *IntegrationDERPTestSuite) tailscaleContainer(identifier, version string, network dockertest.Network, func (s *IntegrationDERPTestSuite) tailscaleContainer(identifier, version string, network dockertest.Network,
) (string, *dockertest.Resource) { ) (string, *dockertest.Resource) {
tailscaleBuildOptions := &dockertest.BuildOptions{ tailscaleBuildOptions := getDockerBuildOptions(version)
Dockerfile: "Dockerfile.tailscale",
ContextDir: ".",
BuildArgs: []docker.BuildArg{
{
Name: "TAILSCALE_VERSION",
Value: version,
},
},
}
hostname := fmt.Sprintf( hostname := fmt.Sprintf(
"tailscale-%s-%s", "tailscale-%s-%s",
strings.Replace(version, ".", "-", -1), strings.Replace(version, ".", "-", -1),
@ -279,7 +271,7 @@ func (s *IntegrationDERPTestSuite) tailscaleContainer(identifier, version string
DockerAllowNetworkAdministration, DockerAllowNetworkAdministration,
) )
if err != nil { if err != nil {
log.Fatalf("Could not start resource: %s", err) log.Fatalf("Could not start tailscale container version %s: %s", version, err)
} }
log.Printf("Created %s container\n", hostname) log.Printf("Created %s container\n", hostname)

View file

@ -168,16 +168,8 @@ func (s *IntegrationTestSuite) Join(
func (s *IntegrationTestSuite) tailscaleContainer( func (s *IntegrationTestSuite) tailscaleContainer(
namespace, identifier, version string, namespace, identifier, version string,
) (string, *dockertest.Resource) { ) (string, *dockertest.Resource) {
tailscaleBuildOptions := &dockertest.BuildOptions{ tailscaleBuildOptions := getDockerBuildOptions(version)
Dockerfile: "Dockerfile.tailscale",
ContextDir: ".",
BuildArgs: []docker.BuildArg{
{
Name: "TAILSCALE_VERSION",
Value: version,
},
},
}
hostname := fmt.Sprintf( hostname := fmt.Sprintf(
"%s-tailscale-%s-%s", "%s-tailscale-%s-%s",
namespace, namespace,
@ -200,7 +192,7 @@ func (s *IntegrationTestSuite) tailscaleContainer(
DockerAllowNetworkAdministration, DockerAllowNetworkAdministration,
) )
if err != nil { if err != nil {
log.Fatalf("Could not start resource: %s", err) log.Fatalf("Could not start tailscale container version %s: %s", version, err)
} }
log.Printf("Created %s container\n", hostname) log.Printf("Created %s container\n", hostname)
@ -249,7 +241,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil {
s.headscale = *pheadscale s.headscale = *pheadscale
} else { } else {
log.Fatalf("Could not start resource: %s", err) log.Fatalf("Could not start headscale container: %s", err)
} }
log.Println("Created headscale container") log.Println("Created headscale container")

View file

@ -24,6 +24,5 @@ derp:
region_id: 999 region_id: 999
region_code: "headscale" region_code: "headscale"
region_name: "Headscale Embedded DERP" region_name: "Headscale Embedded DERP"
stun:
enabled: true stun_listen_addr: "0.0.0.0:3478"
listen_addr: "0.0.0.0:3478"

View file

@ -10,6 +10,7 @@ import (
"html/template" "html/template"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/coreos/go-oidc/v3/oidc" "github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -129,6 +130,10 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code)
if err != nil { if err != nil {
log.Error().
Err(err).
Caller().
Msg("Could not exchange code for token")
ctx.String(http.StatusBadRequest, "Could not exchange code for token") ctx.String(http.StatusBadRequest, "Could not exchange code for token")
return return
@ -229,7 +234,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
Str("machine", machine.Name). Str("machine", machine.Name).
Msg("machine already registered, reauthenticating") Msg("machine already registered, reauthenticating")
h.RefreshMachine(machine, *machine.Expiry) h.RefreshMachine(machine, time.Time{})
var content bytes.Buffer var content bytes.Buffer
if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{

68
poll.go
View file

@ -175,32 +175,13 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
Str("machine", machine.Name). Str("machine", machine.Name).
Msg("Loading or creating update channel") Msg("Loading or creating update channel")
// TODO: could probably remove all that duplication once generics land.
closeChanWithLog := func(channel interface{}, name string) {
log.Trace().
Str("handler", "PollNetMap").
Str("machine", machine.Name).
Str("channel", "Done").
Msg(fmt.Sprintf("Closing %s channel", name))
switch c := channel.(type) {
case (chan struct{}):
close(c)
case (chan []byte):
close(c)
}
}
const chanSize = 8 const chanSize = 8
updateChan := make(chan struct{}, chanSize) updateChan := make(chan struct{}, chanSize)
defer closeChanWithLog(updateChan, "updateChan")
pollDataChan := make(chan []byte, chanSize) pollDataChan := make(chan []byte, chanSize)
defer closeChanWithLog(pollDataChan, "pollDataChan") defer closeChanWithLog(pollDataChan, machine.Name, "pollDataChan")
keepAliveChan := make(chan []byte) keepAliveChan := make(chan []byte)
defer closeChanWithLog(keepAliveChan, "keepAliveChan")
if req.OmitPeers && !req.Stream { if req.OmitPeers && !req.Stream {
log.Info(). log.Info().
@ -273,7 +254,27 @@ func (h *Headscale) PollNetMapStream(
updateChan chan struct{}, updateChan chan struct{},
) { ) {
{ {
ctx, cancel := context.WithCancel(ctx.Request.Context()) machine, err := h.GetMachineByMachineKey(machineKey)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Warn().
Str("handler", "PollNetMap").
Msgf("Ignoring request, cannot find machine with key %s", machineKey.String())
ctx.String(http.StatusUnauthorized, "")
return
}
log.Error().
Str("handler", "PollNetMap").
Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String())
ctx.String(http.StatusInternalServerError, "")
return
}
ctx := context.WithValue(ctx.Request.Context(), "machineName", machine.Name)
ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
go h.scheduledPollWorker( go h.scheduledPollWorker(
@ -564,8 +565,8 @@ func (h *Headscale) PollNetMapStream(
func (h *Headscale) scheduledPollWorker( func (h *Headscale) scheduledPollWorker(
ctx context.Context, ctx context.Context,
updateChan chan<- struct{}, updateChan chan struct{},
keepAliveChan chan<- []byte, keepAliveChan chan []byte,
machineKey key.MachinePublic, machineKey key.MachinePublic,
mapRequest tailcfg.MapRequest, mapRequest tailcfg.MapRequest,
machine *Machine, machine *Machine,
@ -573,6 +574,17 @@ func (h *Headscale) scheduledPollWorker(
keepAliveTicker := time.NewTicker(keepAliveInterval) keepAliveTicker := time.NewTicker(keepAliveInterval)
updateCheckerTicker := time.NewTicker(updateCheckInterval) updateCheckerTicker := time.NewTicker(updateCheckInterval)
defer closeChanWithLog(
updateChan,
fmt.Sprint(ctx.Value("machineName")),
"updateChan",
)
defer closeChanWithLog(
keepAliveChan,
fmt.Sprint(ctx.Value("machineName")),
"updateChan",
)
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -606,3 +618,13 @@ func (h *Headscale) scheduledPollWorker(
} }
} }
} }
func closeChanWithLog[C chan []byte | chan struct{}](channel C, machine, name string) {
log.Trace().
Str("handler", "PollNetMap").
Str("machine", machine).
Str("channel", "Done").
Msg(fmt.Sprintf("Closing %s channel", name))
close(channel)
}

View file

@ -1,39 +0,0 @@
#!/usr/bin/env bash
set -e -o pipefail
commit="$1"
versionglob="v[0-9].[0-9]*.[0-9]*"
devsuffix=".dev"
if [ -z "$commit" ]; then
commit=`git log -n1 --first-parent "--format=format:%h"`
fi
# automatically assign version
#
# handles the following cases:
#
# 0. no tags on the repository. Print "dev".
#
# 1. no local modifications and commit is directly tagged. Print tag.
#
# 2. no local modifications and commit is not tagged. Take greatest version tag in repo X.Y.Z and assign X.Y.(Z+1). Print that + $devsuffix + $timestamp.
#
# 3. local modifications. Print "dev".
tags=$(git tag)
if [[ -z "$tags" ]]; then
echo "dev"
elif `git diff --quiet 2>/dev/null`; then
tagged=$(git tag --points-at "$commit")
if [[ -n "$tagged" ]] ; then
echo $tagged
else
nearest_tag=$(git describe --tags --abbrev=0 --match "$versionglob" "$commit")
v=$(echo $nearest_tag | perl -pe 's/(\d+)$/$1+1/e')
isodate=$(TZ=UTC git log -n1 --format=%cd --date=iso "$commit")
ts=$(TZ=UTC date --date="$isodate" "+%Y%m%d%H%M%S")
echo "${v}${devsuffix}${ts}"
fi
else
echo "dev"
fi