mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Merge branch 'main' into flake-build-env
This commit is contained in:
		
						commit
						5c285afda5
					
				
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
								
							| @ -7,5 +7,5 @@ contact_links: | ||||
|     url: "https://github.com/juanfont/headscale/blob/main/docs" | ||||
|     about: "Find documentation about how to configure and run headscale." | ||||
|   - 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." | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @ -18,7 +18,7 @@ jobs: | ||||
|       - name: Set up Go | ||||
|         uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: 1.17.7 | ||||
|           go-version: 1.18.0 | ||||
| 
 | ||||
|       - name: Install dependencies | ||||
|         run: | | ||||
|  | ||||
							
								
								
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,6 +1,14 @@ | ||||
| # 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. | ||||
| 
 | ||||
| @ -19,7 +27,7 @@ | ||||
| - 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 `/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 | ||||
| 
 | ||||
| @ -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) | ||||
| - 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) | ||||
| - 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) | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # 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 | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # 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 | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| # 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 | ||||
| WORKDIR /go/src/headscale | ||||
| 
 | ||||
|  | ||||
| @ -1,11 +1,12 @@ | ||||
| FROM ubuntu:latest | ||||
| 
 | ||||
| ARG TAILSCALE_VERSION | ||||
| ARG TAILSCALE_VERSION=* | ||||
| ARG TAILSCALE_CHANNEL=stable | ||||
| 
 | ||||
| RUN apt-get update \ | ||||
|     && 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/stable/ubuntu/focal.list | tee /etc/apt/sources.list.d/tailscale.list \ | ||||
|     && curl -fsSL https://pkgs.tailscale.com/${TAILSCALE_CHANNEL}/ubuntu/focal.gpg | apt-key add - \ | ||||
|     && curl -fsSL https://pkgs.tailscale.com/${TAILSCALE_CHANNEL}/ubuntu/focal.list | tee /etc/apt/sources.list.d/tailscale.list \ | ||||
|     && apt-get update \ | ||||
|     && apt-get install -y ca-certificates tailscale=${TAILSCALE_VERSION} dnsutils \ | ||||
|     && rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
							
								
								
									
										21
									
								
								Dockerfile.tailscale-HEAD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Dockerfile.tailscale-HEAD
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| # 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)) | ||||
| 
 | ||||
| @ -10,7 +10,7 @@ PROTO_SOURCES = $(call rwildcard,,*.proto) | ||||
| 
 | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										66
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								README.md
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| 
 | ||||
| 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 | ||||
| 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> | ||||
|         </a> | ||||
|     </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"> | ||||
|         <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/> | ||||
| @ -239,6 +246,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>Eugen Biegler</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -246,8 +255,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Aaron Bieber</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -283,6 +290,15 @@ make build | ||||
|             <sub style="font-size:14px"><b>Paul Tötterman</b></sub> | ||||
|         </a> | ||||
|     </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"> | ||||
|         <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/> | ||||
| @ -290,8 +306,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Casey Marshall</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -320,6 +334,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>thomas</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -328,14 +344,12 @@ make build | ||||
|         </a> | ||||
|     </td> | ||||
|     <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/> | ||||
|         <a href=https://github.com/aofei> | ||||
|             <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 /> | ||||
|             <sub style="font-size:14px"><b>Artem Klevtsov</b></sub> | ||||
|             <sub style="font-size:14px"><b>Aofei Sheng</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -350,6 +364,13 @@ make build | ||||
|             <sub style="font-size:14px"><b>Bryan Stenson</b></sub> | ||||
|         </a> | ||||
|     </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"> | ||||
|         <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/> | ||||
| @ -357,6 +378,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>Felix Kronlage-Dammers</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -378,8 +401,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Jamie Greeff</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -401,6 +422,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>rcursaru</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -422,8 +445,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Shaanan Cohney</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -445,6 +466,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>The Gitter Badger</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -466,8 +489,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>Yang Bin</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -489,6 +510,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>bravechamp</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -496,6 +519,13 @@ make build | ||||
|             <sub style="font-size:14px"><b>derelm</b></sub> | ||||
|         </a> | ||||
|     </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"> | ||||
|         <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/> | ||||
| @ -510,8 +540,6 @@ make build | ||||
|             <sub style="font-size:14px"><b>lion24</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
| @ -526,6 +554,8 @@ make build | ||||
|             <sub style="font-size:14px"><b>Wakeful-Cloud</b></sub> | ||||
|         </a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0"> | ||||
|         <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/> | ||||
|  | ||||
							
								
								
									
										2
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								api.go
									
									
									
									
									
								
							| @ -573,7 +573,7 @@ func (h *Headscale) handleAuthKey( | ||||
| 			machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", pak.Namespace.Name). | ||||
| 				Inc() | ||||
| 		} else { | ||||
| 			machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error").Inc() | ||||
| 			machineRegistrations.WithLabelValues("new", RegisterMethodAuthKey, "error", "unknown").Inc() | ||||
| 		} | ||||
| 
 | ||||
| 		return | ||||
|  | ||||
							
								
								
									
										23
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								app.go
									
									
									
									
									
								
							| @ -47,6 +47,14 @@ import ( | ||||
| 	"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 ( | ||||
| 	AuthPrefix         = "Bearer " | ||||
| 	Postgres           = "postgres" | ||||
| @ -58,11 +66,6 @@ const ( | ||||
| 	registerCacheExpiration = time.Minute * 15 | ||||
| 	registerCacheCleanup    = time.Minute * 20 | ||||
| 
 | ||||
| 	errUnsupportedDatabase                 = Error("unsupported DB") | ||||
| 	errUnsupportedLetsEncryptChallengeType = Error( | ||||
| 		"unknown value for Lets Encrypt challenge type", | ||||
| 	) | ||||
| 
 | ||||
| 	DisabledClientAuth = "disabled" | ||||
| 	RelaxedClientAuth  = "relaxed" | ||||
| 	EnforcedClientAuth = "enforced" | ||||
| @ -124,7 +127,6 @@ type DERPConfig struct { | ||||
| 	ServerRegionID   int | ||||
| 	ServerRegionCode string | ||||
| 	ServerRegionName string | ||||
| 	STUNEnabled      bool | ||||
| 	STUNAddr         string | ||||
| 	URLs             []url.URL | ||||
| 	Paths            []string | ||||
| @ -500,10 +502,13 @@ func (h *Headscale) Serve() error { | ||||
| 	h.DERPMap = GetDERPMap(h.cfg.DERP) | ||||
| 
 | ||||
| 	if h.cfg.DERP.ServerEnabled { | ||||
| 		h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 		if h.cfg.DERP.STUNEnabled { | ||||
| 			go h.ServeSTUN() | ||||
| 		// When embedded DERP is enabled we always need a STUN server
 | ||||
| 		if h.cfg.DERP.STUNAddr == "" { | ||||
| 			return errSTUNAddressNotSet | ||||
| 		} | ||||
| 
 | ||||
| 		h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region | ||||
| 		go h.ServeSTUN() | ||||
| 	} | ||||
| 
 | ||||
| 	if h.cfg.DERP.AutoUpdate { | ||||
|  | ||||
| @ -23,7 +23,7 @@ func init() { | ||||
| 	apiKeysCmd.AddCommand(listAPIKeys) | ||||
| 
 | ||||
| 	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) | ||||
| 
 | ||||
|  | ||||
| @ -31,7 +31,7 @@ func init() { | ||||
| 	createPreAuthKeyCmd.PersistentFlags(). | ||||
| 		Bool("ephemeral", false, "Preauthkey for ephemeral nodes") | ||||
| 	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{ | ||||
|  | ||||
| @ -55,6 +55,9 @@ func LoadConfig(path string) error { | ||||
| 
 | ||||
| 	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_permission", "0o770") | ||||
| 
 | ||||
| @ -121,8 +124,11 @@ func GetDERPConfig() headscale.DERPConfig { | ||||
| 	serverRegionID := viper.GetInt("derp.server.region_id") | ||||
| 	serverRegionCode := viper.GetString("derp.server.region_code") | ||||
| 	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") | ||||
| 
 | ||||
| @ -149,7 +155,6 @@ func GetDERPConfig() headscale.DERPConfig { | ||||
| 		ServerRegionID:   serverRegionID, | ||||
| 		ServerRegionCode: serverRegionCode, | ||||
| 		ServerRegionName: serverRegionName, | ||||
| 		STUNEnabled:      stunEnabled, | ||||
| 		STUNAddr:         stunAddr, | ||||
| 		URLs:             urls, | ||||
| 		Paths:            paths, | ||||
| @ -403,7 +408,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { | ||||
| 		aclPath := absPath(viper.GetString("acl_policy_path")) | ||||
| 		err = app.LoadACLPolicy(aclPath) | ||||
| 		if err != nil { | ||||
| 			log.Error(). | ||||
| 			log.Fatal(). | ||||
| 				Str("path", aclPath). | ||||
| 				Err(err). | ||||
| 				Msg("Could not load the ACL policy") | ||||
|  | ||||
| @ -69,11 +69,11 @@ derp: | ||||
|     region_code: "headscale" | ||||
|     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/ | ||||
|     stun: | ||||
|       enabled: false | ||||
|       listen_addr: "0.0.0.0:3478" | ||||
|     stun_listen_addr: "0.0.0.0:3478" | ||||
| 
 | ||||
|   # List of externally available DERP maps encoded in JSON | ||||
|   urls: | ||||
|  | ||||
| @ -12,4 +12,4 @@ regions: | ||||
|         ipv6: "2604:a880:400:d1::828:b001" | ||||
|         stunport: 0 | ||||
|         stunonly: false | ||||
|         derptestport: 0 | ||||
|         derpport: 0 | ||||
|  | ||||
							
								
								
									
										4
									
								
								derp.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								derp.go
									
									
									
									
									
								
							| @ -148,7 +148,9 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) { | ||||
| 		case <-ticker.C: | ||||
| 			log.Info().Msg("Fetching DERPMap updates") | ||||
| 			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() | ||||
| 			if err != nil { | ||||
|  | ||||
| @ -77,17 +77,15 @@ func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) { | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	if h.cfg.DERP.STUNEnabled { | ||||
| 		_, portStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) | ||||
| 		if err != nil { | ||||
| 			return tailcfg.DERPRegion{}, err | ||||
| 		} | ||||
| 		port, err := strconv.Atoi(portStr) | ||||
| 		if err != nil { | ||||
| 			return tailcfg.DERPRegion{}, err | ||||
| 		} | ||||
| 		localDERPregion.Nodes[0].STUNPort = port | ||||
| 	_, portSTUNStr, err := net.SplitHostPort(h.cfg.DERP.STUNAddr) | ||||
| 	if err != nil { | ||||
| 		return tailcfg.DERPRegion{}, err | ||||
| 	} | ||||
| 	portSTUN, err := strconv.Atoi(portSTUNStr) | ||||
| 	if err != nil { | ||||
| 		return tailcfg.DERPRegion{}, err | ||||
| 	} | ||||
| 	localDERPregion.Nodes[0].STUNPort = portSTUN | ||||
| 
 | ||||
| 	return localDERPregion, nil | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| This page contains the official and community contributed documentation for `headscale`. | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
|  | ||||
| @ -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: | ||||
| 
 | ||||
| ```shell | ||||
| mkdir ./headscale && cd ./headscale | ||||
| mkdir ./config | ||||
| mkdir -p ./headscale/config | ||||
| cd ./headscale | ||||
| ``` | ||||
| 
 | ||||
| 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. | ||||
| 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: | ||||
| 
 | ||||
| @ -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 | ||||
| `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/)): | ||||
| 
 | ||||
| ```shell | ||||
| docker exec headscale -- headscale namespaces create myfirstnamespace | ||||
| docker exec headscale \ | ||||
|   headscale namespaces create myfirstnamespace | ||||
| ``` | ||||
| 
 | ||||
| ### 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: | ||||
| 
 | ||||
| ```shell | ||||
| docker exec headscale -- \ | ||||
| docker exec headscale \ | ||||
|   headscale --namespace myfirstnamespace nodes register --key <YOU_+MACHINE_KEY> | ||||
| ``` | ||||
| 
 | ||||
| @ -110,7 +124,7 @@ docker exec headscale -- \ | ||||
| Generate a key using the command line: | ||||
| 
 | ||||
| ```shell | ||||
| docker exec headscale -- \ | ||||
| docker exec headscale \ | ||||
|   headscale --namespace myfirstnamespace preauthkeys create --reusable --expiration 24h | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| @ -178,7 +178,7 @@ systemctl status headscale | ||||
| Verify `headscale` is available: | ||||
| 
 | ||||
| ```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. | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| module github.com/juanfont/headscale | ||||
| 
 | ||||
| go 1.17 | ||||
| go 1.18 | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/AlecAivazis/survey/v2 v2.3.2 | ||||
|  | ||||
| @ -72,7 +72,7 @@ func (s *IntegrationCLITestSuite) SetupTest() { | ||||
| 	if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { | ||||
| 		s.headscale = *pheadscale | ||||
| 	} else { | ||||
| 		log.Fatalf("Could not start resource: %s", err) | ||||
| 		log.Fatalf("Could not start headscale container: %s", err) | ||||
| 	} | ||||
| 	fmt.Println("Created headscale container") | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ var ( | ||||
| 	IpPrefix4 = netaddr.MustParseIPPrefix("100.64.0.0/10") | ||||
| 	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 { | ||||
| @ -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( | ||||
| 	tailscales map[string]dockertest.Resource, | ||||
| ) (map[string][]netaddr.IP, error) { | ||||
|  | ||||
| @ -121,7 +121,7 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { | ||||
| 	if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { | ||||
| 		s.headscale = *pheadscale | ||||
| 	} 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") | ||||
| 
 | ||||
| @ -245,16 +245,8 @@ func (s *IntegrationDERPTestSuite) Join( | ||||
| 
 | ||||
| func (s *IntegrationDERPTestSuite) tailscaleContainer(identifier, version string, network dockertest.Network, | ||||
| ) (string, *dockertest.Resource) { | ||||
| 	tailscaleBuildOptions := &dockertest.BuildOptions{ | ||||
| 		Dockerfile: "Dockerfile.tailscale", | ||||
| 		ContextDir: ".", | ||||
| 		BuildArgs: []docker.BuildArg{ | ||||
| 			{ | ||||
| 				Name:  "TAILSCALE_VERSION", | ||||
| 				Value: version, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	tailscaleBuildOptions := getDockerBuildOptions(version) | ||||
| 
 | ||||
| 	hostname := fmt.Sprintf( | ||||
| 		"tailscale-%s-%s", | ||||
| 		strings.Replace(version, ".", "-", -1), | ||||
| @ -279,7 +271,7 @@ func (s *IntegrationDERPTestSuite) tailscaleContainer(identifier, version string | ||||
| 		DockerAllowNetworkAdministration, | ||||
| 	) | ||||
| 	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) | ||||
| 
 | ||||
|  | ||||
| @ -168,16 +168,8 @@ func (s *IntegrationTestSuite) Join( | ||||
| func (s *IntegrationTestSuite) tailscaleContainer( | ||||
| 	namespace, identifier, version string, | ||||
| ) (string, *dockertest.Resource) { | ||||
| 	tailscaleBuildOptions := &dockertest.BuildOptions{ | ||||
| 		Dockerfile: "Dockerfile.tailscale", | ||||
| 		ContextDir: ".", | ||||
| 		BuildArgs: []docker.BuildArg{ | ||||
| 			{ | ||||
| 				Name:  "TAILSCALE_VERSION", | ||||
| 				Value: version, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	tailscaleBuildOptions := getDockerBuildOptions(version) | ||||
| 
 | ||||
| 	hostname := fmt.Sprintf( | ||||
| 		"%s-tailscale-%s-%s", | ||||
| 		namespace, | ||||
| @ -200,7 +192,7 @@ func (s *IntegrationTestSuite) tailscaleContainer( | ||||
| 		DockerAllowNetworkAdministration, | ||||
| 	) | ||||
| 	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) | ||||
| 
 | ||||
| @ -249,7 +241,7 @@ func (s *IntegrationTestSuite) SetupSuite() { | ||||
| 	if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { | ||||
| 		s.headscale = *pheadscale | ||||
| 	} else { | ||||
| 		log.Fatalf("Could not start resource: %s", err) | ||||
| 		log.Fatalf("Could not start headscale container: %s", err) | ||||
| 	} | ||||
| 	log.Println("Created headscale container") | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,5 @@ derp: | ||||
|     region_id: 999 | ||||
|     region_code: "headscale" | ||||
|     region_name: "Headscale Embedded DERP" | ||||
|     stun: | ||||
|       enabled: true | ||||
|       listen_addr: "0.0.0.0:3478" | ||||
| 
 | ||||
|     stun_listen_addr: "0.0.0.0:3478" | ||||
|  | ||||
							
								
								
									
										7
									
								
								oidc.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								oidc.go
									
									
									
									
									
								
							| @ -10,6 +10,7 @@ import ( | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc/v3/oidc" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| @ -129,6 +130,10 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { | ||||
| 
 | ||||
| 	oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) | ||||
| 	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") | ||||
| 
 | ||||
| 		return | ||||
| @ -229,7 +234,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) { | ||||
| 			Str("machine", machine.Name). | ||||
| 			Msg("machine already registered, reauthenticating") | ||||
| 
 | ||||
| 		h.RefreshMachine(machine, *machine.Expiry) | ||||
| 		h.RefreshMachine(machine, time.Time{}) | ||||
| 
 | ||||
| 		var content bytes.Buffer | ||||
| 		if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{ | ||||
|  | ||||
							
								
								
									
										68
									
								
								poll.go
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								poll.go
									
									
									
									
									
								
							| @ -175,32 +175,13 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { | ||||
| 		Str("machine", machine.Name). | ||||
| 		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 | ||||
| 	updateChan := make(chan struct{}, chanSize) | ||||
| 	defer closeChanWithLog(updateChan, "updateChan") | ||||
| 
 | ||||
| 	pollDataChan := make(chan []byte, chanSize) | ||||
| 	defer closeChanWithLog(pollDataChan, "pollDataChan") | ||||
| 	defer closeChanWithLog(pollDataChan, machine.Name, "pollDataChan") | ||||
| 
 | ||||
| 	keepAliveChan := make(chan []byte) | ||||
| 	defer closeChanWithLog(keepAliveChan, "keepAliveChan") | ||||
| 
 | ||||
| 	if req.OmitPeers && !req.Stream { | ||||
| 		log.Info(). | ||||
| @ -273,7 +254,27 @@ func (h *Headscale) PollNetMapStream( | ||||
| 	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() | ||||
| 
 | ||||
| 		go h.scheduledPollWorker( | ||||
| @ -564,8 +565,8 @@ func (h *Headscale) PollNetMapStream( | ||||
| 
 | ||||
| func (h *Headscale) scheduledPollWorker( | ||||
| 	ctx context.Context, | ||||
| 	updateChan chan<- struct{}, | ||||
| 	keepAliveChan chan<- []byte, | ||||
| 	updateChan chan struct{}, | ||||
| 	keepAliveChan chan []byte, | ||||
| 	machineKey key.MachinePublic, | ||||
| 	mapRequest tailcfg.MapRequest, | ||||
| 	machine *Machine, | ||||
| @ -573,6 +574,17 @@ func (h *Headscale) scheduledPollWorker( | ||||
| 	keepAliveTicker := time.NewTicker(keepAliveInterval) | ||||
| 	updateCheckerTicker := time.NewTicker(updateCheckInterval) | ||||
| 
 | ||||
| 	defer closeChanWithLog( | ||||
| 		updateChan, | ||||
| 		fmt.Sprint(ctx.Value("machineName")), | ||||
| 		"updateChan", | ||||
| 	) | ||||
| 	defer closeChanWithLog( | ||||
| 		keepAliveChan, | ||||
| 		fmt.Sprint(ctx.Value("machineName")), | ||||
| 		"updateChan", | ||||
| 	) | ||||
| 
 | ||||
| 	for { | ||||
| 		select { | ||||
| 		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) | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user