Heric Camargo pushed to branch main at Root / CLI / Mirror Monitor

Commits:

8 changed files:

Changes:

  • .gitignore
    ... ... @@ -3,8 +3,7 @@
    3 3
     #
    
    4 4
     
    
    5 5
     # binaries
    
    6
    -rsyncuptime-server
    
    7
    -rsyncuptime-tui
    
    6
    +mirror-monitor-tui
    
    8 7
     bin/
    
    9 8
     
    
    10 9
     # Binaries for programs and plugins
    

  • Containerfile
    ... ... @@ -3,26 +3,39 @@ FROM golang:1.24 AS builder
    3 3
     
    
    4 4
     WORKDIR /app
    
    5 5
     
    
    6
    -# Copia os arquivos do projeto
    
    6
    +# Copia go.mod e go.sum para melhor cache de layers
    
    7
    +COPY go.mod go.sum ./
    
    8
    +
    
    9
    +# Download das dependências
    
    10
    +RUN go mod download
    
    11
    +
    
    12
    +# Copia o restante dos arquivos do projeto
    
    7 13
     COPY . .
    
    8 14
     
    
    9 15
     # Compilando o binário da API
    
    10
    -RUN go build -o rsyncuptime cmd/api/main.go
    
    16
    +RUN go build -o mirror-monitor ./cmd/api
    
    11 17
     
    
    12 18
     # Etapa final:
    
    13 19
     FROM debian:bookworm-slim
    
    14 20
     
    
    15
    -# Instalando o rsync:
    
    21
    +# Instalando o rsync e criando usuário não-root:
    
    16 22
     RUN apt-get update && \
    
    17
    -    apt-get install -y rsync && \
    
    18
    -    apt-get clean && rm -rf /var/lib/apt/lists/*
    
    23
    +    apt-get install -y rsync ca-certificates && \
    
    24
    +    apt-get clean && rm -rf /var/lib/apt/lists/* && \
    
    25
    +    useradd -r -u 1000 -s /bin/false appuser
    
    19 26
     
    
    20 27
     # Copiando o binário compilado:
    
    21
    -COPY --from=builder /app/rsyncuptime /usr/local/bin/rsyncuptime
    
    28
    +COPY --from=builder /app/mirror-monitor /usr/local/bin/mirror-monitor
    
    29
    +
    
    30
    +# Tornando o binário executável
    
    31
    +RUN chmod +x /usr/local/bin/mirror-monitor
    
    32
    +
    
    33
    +# Mudando para usuário não-root
    
    34
    +USER 1000
    
    22 35
     
    
    23 36
     # Exponha a porta, se necessário: 
    
    24 37
     #Atenção: se você mudar de porta, esse trecho do código deve-se mudar também!
    
    25 38
     EXPOSE 8080
    
    26 39
     
    
    27 40
     # Definindo o comando de entrada:
    
    28
    -CMD ["rsyncuptime"]
    41
    +CMD ["mirror-monitor"]

  • cmd/api/main.go
    ... ... @@ -2,6 +2,7 @@ package main
    2 2
     
    
    3 3
     import (
    
    4 4
     	"bufio"
    
    5
    +	"context"
    
    5 6
     	"encoding/json"
    
    6 7
     	"errors"
    
    7 8
     	"fmt"
    
    ... ... @@ -9,6 +10,7 @@ import (
    9 10
     	"net/http"
    
    10 11
     	"os"
    
    11 12
     	"os/exec"
    
    13
    +	"os/signal"
    
    12 14
     	"regexp"
    
    13 15
     	"strconv"
    
    14 16
     	"strings"
    
    ... ... @@ -332,7 +334,21 @@ func main() {
    332 334
     	})
    
    333 335
     
    
    334 336
     	log.Printf("Starting monitoring server on :%s using rsync URL '%s'", serverPort, rsyncURL)
    
    335
    -	if err := http.ListenAndServe(":"+serverPort, mux); err != nil {
    
    336
    -		log.Fatalf("Server failed to start: %s", err)
    
    337
    +	server := &http.Server{Addr: ":" + serverPort, Handler: mux}
    
    338
    +	// Graceful shutdown on SIGINT/SIGTERM
    
    339
    +	stop := make(chan os.Signal, 1)
    
    340
    +	signal.Notify(stop, os.Interrupt)
    
    341
    +	go func() {
    
    342
    +		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
    
    343
    +			log.Fatalf("Server error: %s", err)
    
    344
    +		}
    
    345
    +	}()
    
    346
    +	<-stop
    
    347
    +	log.Println("Shutting down server...")
    
    348
    +	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    
    349
    +	defer cancel()
    
    350
    +	if err := server.Shutdown(ctx); err != nil {
    
    351
    +		log.Fatalf("Server Shutdown Failed:%+v", err)
    
    337 352
     	}
    
    353
    +	log.Println("Server exited gracefully")
    
    338 354
     }

  • deploy/k8s/deployment.yaml
    1
    +# Kubernetes Deployment for the mirror-monitor API service
    
    2
    +apiVersion: apps/v1
    
    3
    +kind: Deployment
    
    4
    +metadata:
    
    5
    +  name: mirror-monitor-api
    
    6
    +  labels:
    
    7
    +    app: mirror-monitor-api
    
    8
    +    version: v1
    
    9
    +    component: api
    
    10
    +spec:
    
    11
    +  replicas: 1
    
    12
    +  selector:
    
    13
    +    matchLabels:
    
    14
    +      app: mirror-monitor-api
    
    15
    +  template:
    
    16
    +    metadata:
    
    17
    +      labels:
    
    18
    +        app: mirror-monitor-api
    
    19
    +        version: v1
    
    20
    +        component: api
    
    21
    +    spec:
    
    22
    +      containers:
    
    23
    +      - name: api
    
    24
    +        image: mirror-monitor-api:latest
    
    25
    +        imagePullPolicy: IfNotPresent
    
    26
    +        ports:
    
    27
    +        - containerPort: 8080
    
    28
    +        env:
    
    29
    +        - name: RSYNC_URL
    
    30
    +          value: "rsync://sagres.c3sl.ufpr.br/"
    
    31
    +        - name: POLLING_INTERVAL_SECONDS
    
    32
    +          value: "300"
    
    33
    +        - name: PORT
    
    34
    +          value: "8080"
    
    35
    +        resources:
    
    36
    +          requests:
    
    37
    +            memory: "64Mi"
    
    38
    +            cpu: "50m"
    
    39
    +          limits:
    
    40
    +            memory: "128Mi"
    
    41
    +            cpu: "100m"
    
    42
    +        livenessProbe:
    
    43
    +          httpGet:
    
    44
    +            path: /modules
    
    45
    +            port: 8080
    
    46
    +          initialDelaySeconds: 30
    
    47
    +          periodSeconds: 30
    
    48
    +          timeoutSeconds: 5
    
    49
    +          failureThreshold: 3
    
    50
    +        readinessProbe:
    
    51
    +          httpGet:
    
    52
    +            path: /modules
    
    53
    +            port: 8080
    
    54
    +          initialDelaySeconds: 5
    
    55
    +          periodSeconds: 10
    
    56
    +          timeoutSeconds: 3
    
    57
    +          failureThreshold: 3
    
    58
    +        # Security context for better security
    
    59
    +        securityContext:
    
    60
    +          allowPrivilegeEscalation: false
    
    61
    +          runAsNonRoot: true
    
    62
    +          runAsUser: 1000
    
    63
    +          readOnlyRootFilesystem: true
    
    64
    +          capabilities:
    
    65
    +            drop:
    
    66
    +              - ALL

  • deploy/k8s/ingress.yaml
    1
    +# Optional Ingress for exposing the mirror-monitor API externally
    
    2
    +apiVersion: networking.k8s.io/v1
    
    3
    +kind: Ingress
    
    4
    +metadata:
    
    5
    +  name: mirror-monitor-api-ingress
    
    6
    +  annotations:
    
    7
    +    # Remove the rewrite rule since we want to preserve the API paths
    
    8
    +    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    
    9
    +spec:
    
    10
    +  rules:
    
    11
    +  - host: mirror-monitor.local
    
    12
    +    http:
    
    13
    +      paths:
    
    14
    +      - path: /
    
    15
    +        pathType: Prefix
    
    16
    +        backend:
    
    17
    +          service:
    
    18
    +            name: mirror-monitor-api
    
    19
    +            port:
    
    20
    +              number: 80

  • deploy/k8s/service.yaml
    1
    +# Kubernetes Service for the mirror-monitor API
    
    2
    +apiVersion: v1
    
    3
    +kind: Service
    
    4
    +metadata:
    
    5
    +  name: mirror-monitor-api
    
    6
    +spec:
    
    7
    +  type: ClusterIP
    
    8
    +  selector:
    
    9
    +    app: mirror-monitor-api
    
    10
    +  ports:
    
    11
    +    - name: http
    
    12
    +      port: 80
    
    13
    +      targetPort: 8080  # Match the containerPort in your Deployment

  • deploy/rsyncuptime.servicedeploy/mirror-monitor.service

  • shell.nix
    1
    -# Nix shell para desenvolvimento do servidor web rsyncuptime
    
    1
    +# Nix shell para desenvolvimento do servidor web mirror-monitor
    
    2 2
     
    
    3 3
     { pkgs ? import <nixpkgs> {} }:
    
    4 4
     
    
    ... ... @@ -8,6 +8,11 @@ pkgs.mkShell {
    8 8
         pkgs.rsync
    
    9 9
         pkgs.jq
    
    10 10
         pkgs.mage
    
    11
    +
    
    12
    +    # kubernetes
    
    13
    +    pkgs.kubectl
    
    14
    +    pkgs.kind
    
    15
    +    pkgs.docker
    
    11 16
       ];
    
    12 17
     
    
    13 18
       shellHook = ''