Merge remote-tracking branch 'origin/main' into ipv6

This commit is contained in:
Csaba Sarkadi 2022-01-29 15:27:49 +01:00
commit c0c3b7d511
12 changed files with 99 additions and 27 deletions

View File

@ -18,7 +18,7 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.3" go-version: "1.17"
- name: Install dependencies - name: Install dependencies
run: | run: |

View File

@ -14,6 +14,12 @@ jobs:
with: with:
version: latest version: latest
# Only block PRs on new problems.
# If this is not enabled, we will end up having PRs
# blocked because new linters has appared and other
# parts of the code is affected.
only-new-issues: true
prettier-lint: prettier-lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

View File

@ -17,7 +17,7 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.3" go-version: "1.17"
- name: Run Integration tests - name: Run Integration tests
run: go test -tags integration -timeout 30m run: go test -tags integration -timeout 30m

View File

@ -17,7 +17,7 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: "1.17.3" # The Go version to download (if necessary) and use. go-version: "1.17" # The Go version to download (if necessary) and use.
# Install all the dependencies # Install all the dependencies
- name: Install dependencies - name: Install dependencies

View File

@ -2,6 +2,9 @@
**TBD (TBD):** **TBD (TBD):**
- Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278](https://github.com/juanfont/headscale/pull/278)
)
**0.12.3 (2022-01-13):** **0.12.3 (2022-01-13):**
**Changes**: **Changes**:

View File

@ -9,6 +9,7 @@ RUN go mod download
COPY . . COPY . .
RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale
RUN strip /go/bin/headscale
RUN test -e /go/bin/headscale RUN test -e /go/bin/headscale
# Production image # Production image

View File

@ -10,6 +10,7 @@ RUN go mod download
COPY . . COPY . .
RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale
RUN strip /go/bin/headscale
RUN test -e /go/bin/headscale RUN test -e /go/bin/headscale
# Production image # Production image

View File

@ -65,7 +65,7 @@ To contribute to Headscale you would need the lastest version of [Go](https://go
### Code style ### Code style
To ensure we have some consistency with a growing number of contributes, this project has adopted linting and style/formatting rules: To ensure we have some consistency with a growing number of contributions, this project has adopted linting and style/formatting rules:
The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and
formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and
@ -76,7 +76,7 @@ run `make lint` and `make fmt` before committing any code.
The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and
formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html). formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html).
The **rest** (markdown, yaml, etc) is formatted with [`prettier`](https://prettier.io). The **rest** (Markdown, YAML, etc) is formatted with [`prettier`](https://prettier.io).
Check out the `.golangci.yaml` and `Makefile` to see the specific configuration. Check out the `.golangci.yaml` and `Makefile` to see the specific configuration.
@ -92,7 +92,7 @@ make install-protobuf-plugins
### Testing and building ### Testing and building
Some parts of the project requires the generation of Go code from Protobuf (if changes is made in `proto/`) and it must be (re-)generated with: Some parts of the project require the generation of Go code from Protobuf (if changes are made in `proto/`) and it must be (re-)generated with:
```shell ```shell
make generate make generate

3
app.go
View File

@ -722,7 +722,8 @@ func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
return nil, fmt.Errorf("failed to read private key file: %w", err) return nil, fmt.Errorf("failed to read private key file: %w", err)
} }
privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(string(privateKey)) trimmedPrivateKey := strings.TrimSpace(string(privateKey))
privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(trimmedPrivateKey)
var machineKey key.MachinePrivate var machineKey key.MachinePrivate
if err = machineKey.UnmarshalText([]byte(privateKeyEnsurePrefix)); err != nil { if err = machineKey.UnmarshalText([]byte(privateKeyEnsurePrefix)); err != nil {

View File

@ -21,7 +21,7 @@ wget --output-document=/usr/local/bin/headscale \
chmod +x /usr/local/bin/headscale chmod +x /usr/local/bin/headscale
``` ```
3. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database: 3. Prepare a directory to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
```shell ```shell
# Directory for configuration # Directory for configuration
@ -32,7 +32,7 @@ mkdir -p /etc/headscale
mkdir -p /var/lib/headscale mkdir -p /var/lib/headscale
``` ```
4. Create an empty SQlite datebase: 4. Create an empty SQLite database:
```shell ```shell
touch /var/lib/headscale/db.sqlite touch /var/lib/headscale/db.sqlite
@ -106,7 +106,7 @@ tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>
## Running `headscale` in the background with SystemD ## Running `headscale` in the background with SystemD
In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/). This section demonstrates how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/).
This should work on most modern Linux distributions. This should work on most modern Linux distributions.
1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing: 1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing:

View File

@ -362,6 +362,14 @@ func (h *Headscale) DeleteMachine(machine *Machine) error {
return h.RequestMapUpdates(namespaceID) return h.RequestMapUpdates(namespaceID)
} }
func (h *Headscale) TouchMachine(machine *Machine) error {
return h.db.Updates(Machine{
ID: machine.ID,
LastSeen: machine.LastSeen,
LastSuccessfulUpdate: machine.LastSuccessfulUpdate,
}).Error
}
// HardDeleteMachine hard deletes a Machine from the database. // HardDeleteMachine hard deletes a Machine from the database.
func (h *Headscale) HardDeleteMachine(machine *Machine) error { func (h *Headscale) HardDeleteMachine(machine *Machine) error {
err := h.RemoveSharedMachineFromAllNamespaces(machine) err := h.RemoveSharedMachineFromAllNamespaces(machine)

86
poll.go
View File

@ -76,6 +76,8 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
Str("handler", "PollNetMap"). Str("handler", "PollNetMap").
Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String()) Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String())
ctx.String(http.StatusInternalServerError, "") ctx.String(http.StatusInternalServerError, "")
return
} }
log.Trace(). log.Trace().
Str("handler", "PollNetMap"). Str("handler", "PollNetMap").
@ -102,7 +104,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
machine.Endpoints = datatypes.JSON(endpoints) machine.Endpoints = datatypes.JSON(endpoints)
machine.LastSeen = &now machine.LastSeen = &now
} }
h.db.Save(&machine) h.db.Updates(machine)
data, err := h.getMapResponse(machineKey, req, machine) data, err := h.getMapResponse(machineKey, req, machine)
if err != nil { if err != nil {
@ -313,6 +315,10 @@ func (h *Headscale) PollNetMapStream(
Str("channel", "pollData"). Str("channel", "pollData").
Err(err). Err(err).
Msg("Cannot update machine from database") Msg("Cannot update machine from database")
// client has been removed from database
// since the stream opened, terminate connection.
return false
} }
now := time.Now().UTC() now := time.Now().UTC()
machine.LastSeen = &now machine.LastSeen = &now
@ -321,13 +327,22 @@ func (h *Headscale) PollNetMapStream(
Set(float64(now.Unix())) Set(float64(now.Unix()))
machine.LastSuccessfulUpdate = &now machine.LastSuccessfulUpdate = &now
h.db.Save(&machine) err = h.TouchMachine(machine)
log.Trace(). if err != nil {
Str("handler", "PollNetMapStream"). log.Error().
Str("machine", machine.Name). Str("handler", "PollNetMapStream").
Str("channel", "pollData"). Str("machine", machine.Name).
Int("bytes", len(data)). Str("channel", "pollData").
Msg("Machine entry in database updated successfully after sending pollData") Err(err).
Msg("Cannot update machine LastSuccessfulUpdate")
} else {
log.Trace().
Str("handler", "PollNetMapStream").
Str("machine", machine.Name).
Str("channel", "pollData").
Int("bytes", len(data)).
Msg("Machine entry in database updated successfully after sending pollData")
}
return true return true
@ -366,16 +381,29 @@ func (h *Headscale) PollNetMapStream(
Str("channel", "keepAlive"). Str("channel", "keepAlive").
Err(err). Err(err).
Msg("Cannot update machine from database") Msg("Cannot update machine from database")
// client has been removed from database
// since the stream opened, terminate connection.
return false
} }
now := time.Now().UTC() now := time.Now().UTC()
machine.LastSeen = &now machine.LastSeen = &now
h.db.Save(&machine) err = h.TouchMachine(machine)
log.Trace(). if err != nil {
Str("handler", "PollNetMapStream"). log.Error().
Str("machine", machine.Name). Str("handler", "PollNetMapStream").
Str("channel", "keepAlive"). Str("machine", machine.Name).
Int("bytes", len(data)). Str("channel", "keepAlive").
Msg("Machine updated successfully after sending keep alive") Err(err).
Msg("Cannot update machine LastSeen")
} else {
log.Trace().
Str("handler", "PollNetMapStream").
Str("machine", machine.Name).
Str("channel", "keepAlive").
Int("bytes", len(data)).
Msg("Machine updated successfully after sending keep alive")
}
return true return true
@ -443,6 +471,10 @@ func (h *Headscale) PollNetMapStream(
Str("channel", "update"). Str("channel", "update").
Err(err). Err(err).
Msg("Cannot update machine from database") Msg("Cannot update machine from database")
// client has been removed from database
// since the stream opened, terminate connection.
return false
} }
now := time.Now().UTC() now := time.Now().UTC()
@ -450,7 +482,15 @@ func (h *Headscale) PollNetMapStream(
Set(float64(now.Unix())) Set(float64(now.Unix()))
machine.LastSuccessfulUpdate = &now machine.LastSuccessfulUpdate = &now
h.db.Save(&machine) err = h.TouchMachine(machine)
if err != nil {
log.Error().
Str("handler", "PollNetMapStream").
Str("machine", machine.Name).
Str("channel", "update").
Err(err).
Msg("Cannot update machine LastSuccessfulUpdate")
}
} else { } else {
var lastUpdate time.Time var lastUpdate time.Time
if machine.LastSuccessfulUpdate != nil { if machine.LastSuccessfulUpdate != nil {
@ -482,10 +522,22 @@ func (h *Headscale) PollNetMapStream(
Str("channel", "Done"). Str("channel", "Done").
Err(err). Err(err).
Msg("Cannot update machine from database") Msg("Cannot update machine from database")
// client has been removed from database
// since the stream opened, terminate connection.
return false
} }
now := time.Now().UTC() now := time.Now().UTC()
machine.LastSeen = &now machine.LastSeen = &now
h.db.Save(&machine) err = h.TouchMachine(machine)
if err != nil {
log.Error().
Str("handler", "PollNetMapStream").
Str("machine", machine.Name).
Str("channel", "Done").
Err(err).
Msg("Cannot update machine LastSeen")
}
return false return false
} }