mirror of
https://github.com/juanfont/headscale.git
synced 2026-04-18 23:10:10 +02:00
all: remove deadcode (#2952)
This commit is contained in:
@@ -75,8 +75,8 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
if: always() && steps.changed-files.outputs.files == 'true'
|
if: always() && steps.changed-files.outputs.files == 'true'
|
||||||
with:
|
with:
|
||||||
name: ${{ inputs.database_name }}-${{ inputs.test }}-archives
|
name: ${{ inputs.database_name }}-${{ inputs.test }}-artifacts
|
||||||
path: "control_logs/*/*.tar"
|
path: control_logs/
|
||||||
- name: Setup a blocking tmux session
|
- name: Setup a blocking tmux session
|
||||||
if: ${{ env.HAS_TAILSCALE_SECRET }}
|
if: ${{ env.HAS_TAILSCALE_SECRET }}
|
||||||
uses: alexellis/block-with-tmux-action@master
|
uses: alexellis/block-with-tmux-action@master
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
errPreAuthKeyMalformed = Error("key is malformed. expected 64 hex characters with `nodekey` prefix")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors
|
// Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors
|
||||||
type Error string
|
type Error string
|
||||||
|
|
||||||
|
|||||||
@@ -812,63 +812,3 @@ func extractContainerFiles(ctx context.Context, cli *client.Client, containerID,
|
|||||||
// This function is kept for potential future use or other file types
|
// This function is kept for potential future use or other file types
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// logExtractionError logs extraction errors with appropriate level based on error type.
|
|
||||||
func logExtractionError(artifactType, containerName string, err error, verbose bool) {
|
|
||||||
if errors.Is(err, ErrFileNotFoundInTar) {
|
|
||||||
// File not found is expected and only logged in verbose mode
|
|
||||||
if verbose {
|
|
||||||
log.Printf("No %s found in container %s", artifactType, containerName)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Other errors are actual failures and should be logged as warnings
|
|
||||||
log.Printf("Warning: failed to extract %s from %s: %v", artifactType, containerName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractSingleFile copies a single file from a container.
|
|
||||||
func extractSingleFile(ctx context.Context, cli *client.Client, containerID, sourcePath, fileName, logsDir string, verbose bool) error {
|
|
||||||
tarReader, _, err := cli.CopyFromContainer(ctx, containerID, sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to copy %s from container: %w", sourcePath, err)
|
|
||||||
}
|
|
||||||
defer tarReader.Close()
|
|
||||||
|
|
||||||
// Extract the single file from the tar
|
|
||||||
filePath := filepath.Join(logsDir, fileName)
|
|
||||||
if err := extractFileFromTar(tarReader, filepath.Base(sourcePath), filePath); err != nil {
|
|
||||||
return fmt.Errorf("failed to extract file from tar: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
log.Printf("Extracted %s from %s", fileName, containerID[:12])
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractDirectory copies a directory from a container and extracts its contents.
|
|
||||||
func extractDirectory(ctx context.Context, cli *client.Client, containerID, sourcePath, dirName, logsDir string, verbose bool) error {
|
|
||||||
tarReader, _, err := cli.CopyFromContainer(ctx, containerID, sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to copy %s from container: %w", sourcePath, err)
|
|
||||||
}
|
|
||||||
defer tarReader.Close()
|
|
||||||
|
|
||||||
// Create target directory
|
|
||||||
targetDir := filepath.Join(logsDir, dirName)
|
|
||||||
if err := os.MkdirAll(targetDir, 0o755); err != nil {
|
|
||||||
return fmt.Errorf("failed to create directory %s: %w", targetDir, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the directory from the tar
|
|
||||||
if err := extractDirectoryFromTar(tarReader, targetDir); err != nil {
|
|
||||||
return fmt.Errorf("failed to extract directory from tar: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
log.Printf("Extracted %s/ from %s", dirName, containerID[:12])
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/tar"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrFileNotFoundInTar indicates a file was not found in the tar archive.
|
|
||||||
var ErrFileNotFoundInTar = errors.New("file not found in tar")
|
|
||||||
|
|
||||||
// extractFileFromTar extracts a single file from a tar reader.
|
|
||||||
func extractFileFromTar(tarReader io.Reader, fileName, outputPath string) error {
|
|
||||||
tr := tar.NewReader(tarReader)
|
|
||||||
|
|
||||||
for {
|
|
||||||
header, err := tr.Next()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read tar header: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this is the file we're looking for
|
|
||||||
if filepath.Base(header.Name) == fileName {
|
|
||||||
if header.Typeflag == tar.TypeReg {
|
|
||||||
// Create the output file
|
|
||||||
outFile, err := os.Create(outputPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create output file: %w", err)
|
|
||||||
}
|
|
||||||
defer outFile.Close()
|
|
||||||
|
|
||||||
// Copy file contents
|
|
||||||
if _, err := io.Copy(outFile, tr); err != nil {
|
|
||||||
return fmt.Errorf("failed to copy file contents: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("%w: %s", ErrFileNotFoundInTar, fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// extractDirectoryFromTar extracts all files from a tar reader to a target directory.
|
|
||||||
func extractDirectoryFromTar(tarReader io.Reader, targetDir string) error {
|
|
||||||
tr := tar.NewReader(tarReader)
|
|
||||||
|
|
||||||
for {
|
|
||||||
header, err := tr.Next()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to read tar header: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean the path to prevent directory traversal
|
|
||||||
cleanName := filepath.Clean(header.Name)
|
|
||||||
if strings.Contains(cleanName, "..") {
|
|
||||||
continue // Skip potentially dangerous paths
|
|
||||||
}
|
|
||||||
|
|
||||||
targetPath := filepath.Join(targetDir, cleanName)
|
|
||||||
|
|
||||||
switch header.Typeflag {
|
|
||||||
case tar.TypeDir:
|
|
||||||
// Create directory
|
|
||||||
if err := os.MkdirAll(targetPath, os.FileMode(header.Mode)); err != nil {
|
|
||||||
return fmt.Errorf("failed to create directory %s: %w", targetPath, err)
|
|
||||||
}
|
|
||||||
case tar.TypeReg:
|
|
||||||
// Ensure parent directories exist
|
|
||||||
if err := os.MkdirAll(filepath.Dir(targetPath), 0o755); err != nil {
|
|
||||||
return fmt.Errorf("failed to create parent directories for %s: %w", targetPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create file
|
|
||||||
outFile, err := os.Create(targetPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create file %s: %w", targetPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := io.Copy(outFile, tr); err != nil {
|
|
||||||
outFile.Close()
|
|
||||||
return fmt.Errorf("failed to copy file contents: %w", err)
|
|
||||||
}
|
|
||||||
outFile.Close()
|
|
||||||
|
|
||||||
// Set file permissions
|
|
||||||
if err := os.Chmod(targetPath, os.FileMode(header.Mode)); err != nil {
|
|
||||||
return fmt.Errorf("failed to set file permissions: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -941,18 +941,6 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func notFoundHandler(
|
|
||||||
writer http.ResponseWriter,
|
|
||||||
req *http.Request,
|
|
||||||
) {
|
|
||||||
log.Trace().
|
|
||||||
Interface("header", req.Header).
|
|
||||||
Interface("proto", req.Proto).
|
|
||||||
Interface("url", req.URL).
|
|
||||||
Msg("Request did not match")
|
|
||||||
writer.WriteHeader(http.StatusNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
|
func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
|
||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
err := util.EnsureDir(dir)
|
err := util.EnsureDir(dir)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/chasefleming/elem-go/styles"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/juanfont/headscale/hscontrol/assets"
|
"github.com/juanfont/headscale/hscontrol/assets"
|
||||||
"github.com/juanfont/headscale/hscontrol/templates"
|
"github.com/juanfont/headscale/hscontrol/templates"
|
||||||
@@ -228,13 +227,6 @@ func (h *Headscale) VersionHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var codeStyleRegisterWebAPI = styles.Props{
|
|
||||||
styles.Display: "block",
|
|
||||||
styles.Padding: "20px",
|
|
||||||
styles.Border: "1px solid #bbb",
|
|
||||||
styles.BackgroundColor: "#eee",
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthProviderWeb struct {
|
type AuthProviderWeb struct {
|
||||||
serverURL string
|
serverURL string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ type LockFreeBatcher struct {
|
|||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
totalNodes atomic.Int64
|
totalNodes atomic.Int64
|
||||||
totalUpdates atomic.Int64
|
|
||||||
workQueuedCount atomic.Int64
|
workQueuedCount atomic.Int64
|
||||||
workProcessed atomic.Int64
|
workProcessed atomic.Int64
|
||||||
workErrors atomic.Int64
|
workErrors atomic.Int64
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package mapper
|
|
||||||
|
|
||||||
import "tailscale.com/tailcfg"
|
|
||||||
|
|
||||||
// mergePatch takes the current patch and a newer patch
|
|
||||||
// and override any field that has changed.
|
|
||||||
func mergePatch(currPatch, newPatch *tailcfg.PeerChange) {
|
|
||||||
if newPatch.DERPRegion != 0 {
|
|
||||||
currPatch.DERPRegion = newPatch.DERPRegion
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.Cap != 0 {
|
|
||||||
currPatch.Cap = newPatch.Cap
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.CapMap != nil {
|
|
||||||
currPatch.CapMap = newPatch.CapMap
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.Endpoints != nil {
|
|
||||||
currPatch.Endpoints = newPatch.Endpoints
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.Key != nil {
|
|
||||||
currPatch.Key = newPatch.Key
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.KeySignature != nil {
|
|
||||||
currPatch.KeySignature = newPatch.KeySignature
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.DiscoKey != nil {
|
|
||||||
currPatch.DiscoKey = newPatch.DiscoKey
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.Online != nil {
|
|
||||||
currPatch.Online = newPatch.Online
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.LastSeen != nil {
|
|
||||||
currPatch.LastSeen = newPatch.LastSeen
|
|
||||||
}
|
|
||||||
|
|
||||||
if newPatch.KeyExpiry != nil {
|
|
||||||
currPatch.KeyExpiry = newPatch.KeyExpiry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,31 +32,16 @@ var (
|
|||||||
Name: "mapresponse_sent_total",
|
Name: "mapresponse_sent_total",
|
||||||
Help: "total count of mapresponses sent to clients",
|
Help: "total count of mapresponses sent to clients",
|
||||||
}, []string{"status", "type"})
|
}, []string{"status", "type"})
|
||||||
mapResponseUpdateReceived = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: prometheusNamespace,
|
|
||||||
Name: "mapresponse_updates_received_total",
|
|
||||||
Help: "total count of mapresponse updates received on update channel",
|
|
||||||
}, []string{"type"})
|
|
||||||
mapResponseEndpointUpdates = promauto.NewCounterVec(prometheus.CounterOpts{
|
mapResponseEndpointUpdates = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: prometheusNamespace,
|
Namespace: prometheusNamespace,
|
||||||
Name: "mapresponse_endpoint_updates_total",
|
Name: "mapresponse_endpoint_updates_total",
|
||||||
Help: "total count of endpoint updates received",
|
Help: "total count of endpoint updates received",
|
||||||
}, []string{"status"})
|
}, []string{"status"})
|
||||||
mapResponseReadOnly = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: prometheusNamespace,
|
|
||||||
Name: "mapresponse_readonly_requests_total",
|
|
||||||
Help: "total count of readonly requests received",
|
|
||||||
}, []string{"status"})
|
|
||||||
mapResponseEnded = promauto.NewCounterVec(prometheus.CounterOpts{
|
mapResponseEnded = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||||
Namespace: prometheusNamespace,
|
Namespace: prometheusNamespace,
|
||||||
Name: "mapresponse_ended_total",
|
Name: "mapresponse_ended_total",
|
||||||
Help: "total count of new mapsessions ended",
|
Help: "total count of new mapsessions ended",
|
||||||
}, []string{"reason"})
|
}, []string{"reason"})
|
||||||
mapResponseClosed = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
||||||
Namespace: prometheusNamespace,
|
|
||||||
Name: "mapresponse_closed_total",
|
|
||||||
Help: "total count of calls to mapresponse close",
|
|
||||||
}, []string{"return"})
|
|
||||||
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||||
Namespace: prometheusNamespace,
|
Namespace: prometheusNamespace,
|
||||||
Name: "http_duration_seconds",
|
Name: "http_duration_seconds",
|
||||||
|
|||||||
@@ -29,9 +29,6 @@ const (
|
|||||||
// of length. Then that many bytes of JSON-encoded tailcfg.EarlyNoise.
|
// of length. Then that many bytes of JSON-encoded tailcfg.EarlyNoise.
|
||||||
// The early payload is optional. Some servers may not send it... But we do!
|
// The early payload is optional. Some servers may not send it... But we do!
|
||||||
earlyPayloadMagic = "\xff\xff\xffTS"
|
earlyPayloadMagic = "\xff\xff\xffTS"
|
||||||
|
|
||||||
// EarlyNoise was added in protocol version 49.
|
|
||||||
earlyNoiseCapabilityVersion = 49
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type noiseServer struct {
|
type noiseServer struct {
|
||||||
|
|||||||
@@ -173,11 +173,6 @@ func (a *AuthProviderOIDC) RegisterHandler(
|
|||||||
http.Redirect(writer, req, authURL, http.StatusFound)
|
http.Redirect(writer, req, authURL, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
type oidcCallbackTemplateConfig struct {
|
|
||||||
User string
|
|
||||||
Verb string
|
|
||||||
}
|
|
||||||
|
|
||||||
// OIDCCallbackHandler handles the callback from the OIDC endpoint
|
// OIDCCallbackHandler handles the callback from the OIDC endpoint
|
||||||
// Retrieves the nkey from the state cache and adds the node to the users email user
|
// Retrieves the nkey from the state cache and adds the node to the users email user
|
||||||
// TODO: A confirmation page for new nodes should be added to avoid phishing vulnerabilities
|
// TODO: A confirmation page for new nodes should be added to avoid phishing vulnerabilities
|
||||||
|
|||||||
@@ -319,41 +319,6 @@ var keepAlive = tailcfg.MapResponse{
|
|||||||
KeepAlive: true,
|
KeepAlive: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
func logTracePeerChange(hostname string, hostinfoChange bool, peerChange *tailcfg.PeerChange) {
|
|
||||||
trace := log.Trace().Caller().Uint64("node.id", uint64(peerChange.NodeID)).Str("hostname", hostname)
|
|
||||||
|
|
||||||
if peerChange.Key != nil {
|
|
||||||
trace = trace.Str("node.key", peerChange.Key.ShortString())
|
|
||||||
}
|
|
||||||
|
|
||||||
if peerChange.DiscoKey != nil {
|
|
||||||
trace = trace.Str("disco.key", peerChange.DiscoKey.ShortString())
|
|
||||||
}
|
|
||||||
|
|
||||||
if peerChange.Online != nil {
|
|
||||||
trace = trace.Bool("online", *peerChange.Online)
|
|
||||||
}
|
|
||||||
|
|
||||||
if peerChange.Endpoints != nil {
|
|
||||||
eps := make([]string, len(peerChange.Endpoints))
|
|
||||||
for idx, ep := range peerChange.Endpoints {
|
|
||||||
eps[idx] = ep.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
trace = trace.Strs("endpoints", eps)
|
|
||||||
}
|
|
||||||
|
|
||||||
if hostinfoChange {
|
|
||||||
trace = trace.Bool("hostinfo_changed", hostinfoChange)
|
|
||||||
}
|
|
||||||
|
|
||||||
if peerChange.DERPRegion != 0 {
|
|
||||||
trace = trace.Int("derp_region", peerChange.DERPRegion)
|
|
||||||
}
|
|
||||||
|
|
||||||
trace.Time("last_seen", *peerChange.LastSeen).Msg("PeerChange received")
|
|
||||||
}
|
|
||||||
|
|
||||||
// logf adds common mapSession context to a zerolog event.
|
// logf adds common mapSession context to a zerolog event.
|
||||||
func (m *mapSession) logf(event *zerolog.Event) *zerolog.Event {
|
func (m *mapSession) logf(event *zerolog.Event) *zerolog.Event {
|
||||||
return event.
|
return event.
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ const (
|
|||||||
LabelHostnameLength = 63
|
LabelHostnameLength = 63
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var invalidDNSRegex = regexp.MustCompile("[^a-z0-9-.]+")
|
||||||
invalidDNSRegex = regexp.MustCompile("[^a-z0-9-.]+")
|
|
||||||
invalidCharsInUserRegex = regexp.MustCompile("[^a-z0-9-.]+")
|
|
||||||
)
|
|
||||||
|
|
||||||
var ErrInvalidHostName = errors.New("invalid hostname")
|
var ErrInvalidHostName = errors.New("invalid hostname")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user