E2E tests use repeated strings for test data where constants add no value (#97)

---------

Co-authored-by: Pasha Sviderski <me@psviderski.name>
Co-authored-by: Anton Ovchinnikov <anton@tonyo.info>
This commit is contained in:
Evgenii Orlov
2025-07-21 19:30:02 +02:00
committed by GitHub
co-authored by Pasha Sviderski Anton Ovchinnikov
parent 6fb07db4b2
commit da3634b690
56 changed files with 170 additions and 116 deletions
+5 -5
View File
@@ -25,15 +25,15 @@ jobs:
with:
go-version: "1.23.2"
- name: golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
with:
version: v2.2.2
- name: Format code
run: |
make format
git diff --exit-code ||
(echo "Code is not formatted. Please run 'make format' and commit the changes." && exit 1)
- name: golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
with:
version: v2.2.2
timeout-minutes: 10
+14 -2
View File
@@ -1,4 +1,10 @@
version: "2"
run:
concurrency: 4
tests: true
timeout: 5m
linters:
default: none
enable:
@@ -23,8 +29,14 @@ linters:
# - unparam
# - unused
- whitespace
exclusions:
rules:
- path: ^test/e2e
linters:
- goconst # constants here add no value, so we skip goconst only for test/e2e.
formatters:
enable:
- gofmt
# - goimports
- gofumpt
- goimports
+6 -4
View File
@@ -89,9 +89,9 @@ test-clean:
vet:
go vet ./...
.PHONY: format
format:
go fmt ./...
.PHONY: format fmt
format fmt:
GOOS=linux golangci-lint fmt
LINT_TARGETS := lint lint-and-fix
.PHONY: $(LINT_TARGETS) _lint
@@ -99,7 +99,9 @@ $(LINT_TARGETS): _lint
lint: ARGS=
lint-and-fix: ARGS=--fix
_lint:
golangci-lint run $(ARGS)
# Explicitly set OS to Linux to not skip *_linux.go files when running on macOS.
# Uncloud daemon won't likely support OS other than Linux anytime soon, so for now we can rely on that.
GOOS=linux golangci-lint run $(ARGS)
.PHONY: docs-image-push
docs-image-push:
+1
View File
@@ -2,6 +2,7 @@ package cluster
import (
"fmt"
"github.com/psviderski/uncloud/internal/ucind"
"github.com/spf13/cobra"
)
+1
View File
@@ -2,6 +2,7 @@ package cluster
import (
"fmt"
"github.com/psviderski/uncloud/internal/ucind"
"github.com/spf13/cobra"
)
+1 -1
View File
@@ -13,7 +13,7 @@ func NewRootCommand() *cobra.Command {
}
cmd.AddCommand(
NewCreateCommand(),
//NewListCommand(),
// NewListCommand(),
NewRemoveCommand(),
)
return cmd
+2 -3
View File
@@ -101,7 +101,6 @@ func remove(ctx context.Context, uncli *cli.CLI, machineName string, opts remove
err = progress.RunWithTitle(ctx, func(ctx context.Context) error {
return removeContainers(ctx, client, containers)
}, uncli.ProgressOut(), "Removing containers")
if err != nil {
return fmt.Errorf("remove containers: %w", err)
}
@@ -112,8 +111,8 @@ func remove(ctx context.Context, uncli *cli.CLI, machineName string, opts remove
// TODO: 5. Remove the machine from the cluster store.
return fmt.Errorf("resetting machine is not fully implemented yet")
//fmt.Printf("Machine '%s' removed from the cluster.\n", m.Name)
//return nil
// fmt.Printf("Machine '%s' removed from the cluster.\n", m.Name)
// return nil
}
// formatContainerTree formats a list of containers grouped by service as a tree structure.
+1
View File
@@ -2,6 +2,7 @@ package machine
import (
"fmt"
"github.com/psviderski/uncloud/internal/daemon"
"github.com/psviderski/uncloud/internal/machine"
"github.com/spf13/cobra"
-1
View File
@@ -9,7 +9,6 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
"github.com/psviderski/uncloud/internal/cli"
"github.com/spf13/cobra"
)
+3 -2
View File
@@ -3,10 +3,11 @@ package main
import (
"context"
"fmt"
"github.com/hashicorp/serf/serf"
crdt "github.com/ipfs/go-ds-crdt"
"log/slog"
"time"
"github.com/hashicorp/serf/serf"
crdt "github.com/ipfs/go-ds-crdt"
)
// Implements the Broadcaster interface.
+2 -1
View File
@@ -2,9 +2,10 @@ package main
import (
"fmt"
"github.com/dgraph-io/badger/v3"
"log"
"time"
"github.com/dgraph-io/badger/v3"
)
func customTimeEncoder(t time.Time) string {
+2 -1
View File
@@ -2,9 +2,10 @@ package main
import (
"fmt"
"github.com/ipfs/go-log/v2"
"log/slog"
"os"
"github.com/ipfs/go-log/v2"
)
// ipfsLogger is an slog logger that implements the IPFS go-log StandardLogger interface.
+2 -1
View File
@@ -2,12 +2,13 @@ package main
import (
"fmt"
"github.com/docker/docker/libnetwork/networkdb"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"github.com/docker/docker/libnetwork/networkdb"
)
func main() {
+13 -12
View File
@@ -4,6 +4,13 @@ import (
"context"
"flag"
"fmt"
"log/slog"
"net"
"os"
"os/signal"
"syscall"
"time"
"github.com/hashicorp/memberlist"
"github.com/hashicorp/serf/cmd/serf/command/agent"
"github.com/hashicorp/serf/serf"
@@ -11,12 +18,6 @@ import (
badger "github.com/ipfs/go-ds-badger3"
crdt "github.com/ipfs/go-ds-crdt"
"github.com/lmittmann/tint"
"log/slog"
"net"
"os"
"os/signal"
"syscall"
"time"
)
func createSerfAgentConfig(name, bindAddr, rpcAddr, profile string) *agent.Config {
@@ -49,9 +50,9 @@ func createSerfAgent(config *agent.Config) (*agent.Agent, error) {
serfConfig.MemberlistConfig.BindAddr = bindIP
serfConfig.MemberlistConfig.BindPort = bindPort
//serfConfig.MemberlistConfig.AdvertiseAddr = advertiseIP
//serfConfig.MemberlistConfig.AdvertisePort = advertisePort
//serfConfig.MemberlistConfig.SecretKey = encryptKey
// serfConfig.MemberlistConfig.AdvertiseAddr = advertiseIP
// serfConfig.MemberlistConfig.AdvertisePort = advertisePort
// serfConfig.MemberlistConfig.SecretKey = encryptKey
serfConfig.NodeName = config.NodeName
serfConfig.Tags = config.Tags
serfConfig.SnapshotPath = config.SnapshotPath
@@ -129,7 +130,7 @@ func main() {
logger := slog.New(tint.NewHandler(os.Stdout, &tint.Options{
AddSource: true,
Level: slog.LevelDebug,
//Level: slog.LevelInfo,
// Level: slog.LevelInfo,
TimeFormat: time.RFC3339Nano,
}))
slog.SetDefault(logger)
@@ -164,7 +165,7 @@ func main() {
opts := crdt.DefaultOptions()
opts.Logger = newIPFSLogger(logger)
//opts.MultiHeadProcessing = true
// opts.MultiHeadProcessing = true
// TODO: debug why the heads count may grow on the receiving side if the event backlog is huge and the processing
// is slow.
store, err := crdt.New(localStore, ds.NewKey("/"), syncer, broadcaster, opts)
@@ -172,7 +173,7 @@ func main() {
panic(err)
}
//ticker := time.NewTicker(10 * time.Millisecond)
// ticker := time.NewTicker(10 * time.Millisecond)
ticker := time.NewTicker(3 * time.Second)
go func() {
for {
+3 -2
View File
@@ -6,12 +6,13 @@ import (
"crypto/cipher"
"encoding/hex"
"fmt"
"net/netip"
"time"
"github.com/psviderski/uncloud/internal/machine/network"
"github.com/siderolabs/discovery-api/api/v1alpha1/client/pb"
discovery "github.com/siderolabs/discovery-client/pkg/client"
"go.uber.org/zap"
"net/netip"
"time"
)
const (
+2 -2
View File
@@ -53,11 +53,11 @@ func (c *Config) Read() error {
func (c *Config) Save() error {
dir, _ := filepath.Split(c.path)
if err := os.MkdirAll(dir, 0700); err != nil {
if err := os.MkdirAll(dir, 0o700); err != nil {
return fmt.Errorf("create config directory '%s': %w", dir, err)
}
f, err := os.OpenFile(c.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
f, err := os.OpenFile(c.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
if err != nil {
return fmt.Errorf("write config file '%s': %w", c.path, err)
}
+3 -2
View File
@@ -5,14 +5,15 @@ import (
"crypto/tls"
"errors"
"fmt"
"github.com/cenkalti/backoff/v4"
"golang.org/x/net/http2"
"log/slog"
"net"
"net/http"
"net/netip"
"net/url"
"time"
"github.com/cenkalti/backoff/v4"
"golang.org/x/net/http2"
)
const (
+2 -1
View File
@@ -6,11 +6,12 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/cenkalti/backoff/v4"
"io"
"log/slog"
"net/http"
"strconv"
"github.com/cenkalti/backoff/v4"
)
type ChangeType string
+2 -1
View File
@@ -3,9 +3,10 @@ package daemon
import (
"context"
"fmt"
"log/slog"
systemd "github.com/coreos/go-systemd/daemon"
"github.com/psviderski/uncloud/internal/machine"
"log/slog"
)
type Daemon struct {
+3 -2
View File
@@ -3,10 +3,11 @@ package daemon
import (
"errors"
"fmt"
"github.com/psviderski/uncloud/internal/machine"
"github.com/psviderski/uncloud/internal/machine/network"
"net/netip"
"os"
"github.com/psviderski/uncloud/internal/machine"
"github.com/psviderski/uncloud/internal/machine/network"
)
// MachineToken returns the local machine's token that can be used for adding the machine to a cluster.
+3 -2
View File
@@ -4,10 +4,11 @@ import (
"context"
"errors"
"fmt"
"github.com/cenkalti/backoff/v4"
"github.com/docker/docker/client"
"log/slog"
"time"
"github.com/cenkalti/backoff/v4"
"github.com/docker/docker/client"
)
// WaitDaemonReady waits for the Docker daemon to start and be ready to serve requests.
+1
View File
@@ -2,6 +2,7 @@ package proxy
import (
"fmt"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protowire"
+2 -1
View File
@@ -2,11 +2,12 @@ package proxy
import (
"context"
"sync"
"github.com/siderolabs/grpc-proxy/proxy"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"sync"
)
// Director manages routing of gRPC requests between local and remote backends.
+2 -1
View File
@@ -2,11 +2,12 @@ package proxy
import (
"context"
"sync"
"github.com/siderolabs/grpc-proxy/proxy"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"sync"
)
// LocalBackend is a proxy.One2ManyResponder implementation that proxies to a local gRPC server listening on a Unix socket.
+4 -3
View File
@@ -3,14 +3,15 @@ package proxy
import (
"context"
"fmt"
"net/netip"
"sync"
"time"
"github.com/siderolabs/grpc-proxy/proxy"
"google.golang.org/grpc"
"google.golang.org/grpc/backoff"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"net/netip"
"sync"
"time"
)
// RemoteBackend is a proxy.One2ManyResponder implementation that proxies to a remote gRPC server, injecting machine metadata
+2 -2
View File
@@ -29,7 +29,7 @@ type Controller struct {
func NewController(store *store.Store, path string, verifyResponse string) (*Controller, error) {
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0750); err != nil {
if err := os.MkdirAll(dir, 0o750); err != nil {
return nil, fmt.Errorf("create parent directory for Caddy configuration '%s': %w", dir, err)
}
if err := fs.Chown(dir, "", CaddyGroup); err != nil {
@@ -114,7 +114,7 @@ func (c *Controller) generateConfig(containers []api.ServiceContainer) error {
return fmt.Errorf("marshal Caddy configuration: %w", err)
}
if err = os.WriteFile(c.path, configBytes, 0640); err != nil {
if err = os.WriteFile(c.path, configBytes, 0o640); err != nil {
return fmt.Errorf("write Caddy configuration to file '%s': %w", c.path, err)
}
if err = fs.Chown(c.path, "", CaddyGroup); err != nil {
+4 -3
View File
@@ -5,6 +5,10 @@ import (
"context"
"errors"
"fmt"
"log/slog"
"net/netip"
"time"
"github.com/psviderski/uncloud/internal/corrosion"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/internal/machine/network"
@@ -13,9 +17,6 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"log/slog"
"net/netip"
"time"
)
type Cluster struct {
+1
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
"github.com/psviderski/uncloud/internal/dns"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"github.com/psviderski/uncloud/internal/machine/store"
+2 -1
View File
@@ -3,8 +3,9 @@ package cluster
import (
"errors"
"fmt"
"go4.org/netipx"
"net/netip"
"go4.org/netipx"
)
const DefaultSubnetBits = 24
+1
View File
@@ -2,6 +2,7 @@ package cluster
import (
"fmt"
"github.com/psviderski/uncloud/internal/secret"
)
+6 -5
View File
@@ -3,11 +3,12 @@ package corroservice
import (
"bytes"
"fmt"
"github.com/BurntSushi/toml"
"github.com/psviderski/uncloud/internal/fs"
"net/netip"
"os"
"path/filepath"
"github.com/BurntSushi/toml"
"github.com/psviderski/uncloud/internal/fs"
)
const (
@@ -50,7 +51,7 @@ func (c *Config) Write(path, owner string) error {
if err := encoder.Encode(c); err != nil {
return fmt.Errorf("encode config: %w", err)
}
if err := os.WriteFile(path, data.Bytes(), 0600); err != nil {
if err := os.WriteFile(path, data.Bytes(), 0o600); err != nil {
return err
}
if err := fs.Chown(path, owner, owner); err != nil {
@@ -62,10 +63,10 @@ func (c *Config) Write(path, owner string) error {
func MkDataDir(dir, owner string) error {
parent, _ := filepath.Split(dir)
// Use 0711 for parent directories to allow `owner` to access its nested data directory.
if err := os.MkdirAll(parent, 0711); err != nil {
if err := os.MkdirAll(parent, 0o711); err != nil {
return fmt.Errorf("create directory %q: %w", parent, err)
}
if err := os.Mkdir(dir, 0700); err != nil {
if err := os.Mkdir(dir, 0o700); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("create directory %q: %w", dir, err)
}
+5 -4
View File
@@ -3,15 +3,16 @@ package corroservice
import (
"context"
"fmt"
"io"
"log/slog"
"path/filepath"
"time"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"io"
"log/slog"
"path/filepath"
"time"
)
const (
+2 -2
View File
@@ -111,8 +111,8 @@ func (s *SubprocessService) startProcess(ctx context.Context) error {
// TODO: figure out the waiting process
// Wait for initialization
//timer := time.NewTimer(2 * time.Second)
//defer timer.Stop()
// timer := time.NewTimer(2 * time.Second)
// defer timer.Stop()
//select {
////case <-timer.C:
+2 -2
View File
@@ -14,13 +14,13 @@ const DBFileName = "machine.db"
func NewDB(path string) (*sqlx.DB, error) {
// Create the database file with 0600 permissions if it doesn't exist, or update permissions if exists.
if _, err := os.Stat(path); os.IsNotExist(err) {
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0o600)
if err != nil {
return nil, fmt.Errorf("create SQLite database '%s': %w", path, err)
}
file.Close()
} else {
if err = os.Chmod(path, 0600); err != nil {
if err = os.Chmod(path, 0o600); err != nil {
return nil, fmt.Errorf("update SQLite database permissions '%s': %w", path, err)
}
}
+2 -2
View File
@@ -501,7 +501,7 @@ func listenUnixSocket(path string) (net.Listener, error) {
// Ensure the parent directory exists and has the correct group permissions.
parent, _ := filepath.Split(path)
if err = os.MkdirAll(parent, 0750); err != nil {
if err = os.MkdirAll(parent, 0o750); err != nil {
return nil, fmt.Errorf("create directory %q: %w", parent, err)
}
if err = os.Chown(parent, -1, gid); err != nil {
@@ -555,7 +555,7 @@ func (m *Machine) configureCorrosion() error {
return fmt.Errorf("write corrosion config: %w", err)
}
if err := os.WriteFile(schemaPath, []byte(store.Schema), 0644); err != nil {
if err := os.WriteFile(schemaPath, []byte(store.Schema), 0o644); err != nil {
return fmt.Errorf("write corrosion schema: %w", err)
}
+2 -1
View File
@@ -1,11 +1,12 @@
package network
import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"log/slog"
"net/netip"
"slices"
"time"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
const (
+4 -3
View File
@@ -3,13 +3,14 @@ package tunnel
import (
"context"
"fmt"
"net"
"net/netip"
"time"
"github.com/psviderski/uncloud/internal/secret"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun/netstack"
"net"
"net/netip"
"time"
)
const (
+3 -2
View File
@@ -2,10 +2,11 @@ package network
import (
"fmt"
"github.com/psviderski/uncloud/internal/secret"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"net/netip"
"time"
"github.com/psviderski/uncloud/internal/secret"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
const (
+7 -6
View File
@@ -6,18 +6,19 @@ import (
"context"
"errors"
"fmt"
"github.com/psviderski/uncloud/internal/secret"
"github.com/vishvananda/netlink"
"go4.org/netipx"
"golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"log/slog"
"net"
"net/netip"
"slices"
"sync"
"time"
"github.com/psviderski/uncloud/internal/secret"
"github.com/vishvananda/netlink"
"go4.org/netipx"
"golang.org/x/sys/unix"
"golang.zx2c4.com/wireguard/wgctrl"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
type WireGuardNetwork struct {
+4 -3
View File
@@ -3,10 +3,11 @@ package machine
import (
"encoding/json"
"fmt"
"github.com/psviderski/uncloud/internal/machine/network"
"os"
"path/filepath"
"sync"
"github.com/psviderski/uncloud/internal/machine/network"
)
const (
@@ -71,7 +72,7 @@ func (c *State) Save() error {
return fmt.Errorf("state path not set")
}
dir, _ := filepath.Split(c.path)
if err := os.MkdirAll(dir, 0711); err != nil {
if err := os.MkdirAll(dir, 0o711); err != nil {
return fmt.Errorf("create state directory %q: %w", dir, err)
}
@@ -79,5 +80,5 @@ func (c *State) Save() error {
if err != nil {
return err
}
return os.WriteFile(c.path, data, 0600)
return os.WriteFile(c.path, data, 0o600)
}
+3 -2
View File
@@ -4,11 +4,12 @@ import (
"context"
"encoding/json"
"fmt"
sq "github.com/Masterminds/squirrel"
"github.com/psviderski/uncloud/pkg/api"
"log/slog"
"strings"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/psviderski/uncloud/pkg/api"
)
const (
+2 -1
View File
@@ -5,10 +5,11 @@ import (
_ "embed"
"errors"
"fmt"
"log/slog"
"github.com/psviderski/uncloud/internal/corrosion"
"github.com/psviderski/uncloud/internal/machine/api/pb"
"google.golang.org/protobuf/encoding/protojson"
"log/slog"
)
var (
+2 -1
View File
@@ -4,9 +4,10 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/psviderski/uncloud/internal/secret"
"net/netip"
"strings"
"github.com/psviderski/uncloud/internal/secret"
)
const (
+2 -1
View File
@@ -3,9 +3,10 @@ package sshexec
import (
"context"
"fmt"
"golang.org/x/crypto/ssh"
"io"
"strings"
"golang.org/x/crypto/ssh"
)
type Remote struct {
+1
View File
@@ -2,6 +2,7 @@ package ucind
import (
"errors"
"github.com/docker/docker/client"
)
+3 -2
View File
@@ -1,10 +1,11 @@
package api
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/netip"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPortSpec_Validate(t *testing.T) {
+2 -1
View File
@@ -1,10 +1,11 @@
package client
import (
"testing"
"github.com/distribution/reference"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
)
func TestLatestCaddyImage(t *testing.T) {
+1 -1
View File
@@ -128,7 +128,7 @@ func convertServicePortConfigToPortSpec(port types.ServicePortConfig) (api.PortS
// convertStandardPortsToPortSpecs converts []types.ServicePortConfig directly to api.PortSpecs.
func convertStandardPortsToPortSpecs(ports []types.ServicePortConfig) ([]api.PortSpec, error) {
var specs = make([]api.PortSpec, 0, len(ports))
specs := make([]api.PortSpec, 0, len(ports))
for _, port := range ports {
spec, err := convertServicePortConfigToPortSpec(port)
+3 -2
View File
@@ -3,13 +3,14 @@ package connector
import (
"context"
"fmt"
"net"
"strings"
"github.com/psviderski/uncloud/internal/machine"
"github.com/psviderski/uncloud/internal/sshexec"
"golang.org/x/crypto/ssh"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"net"
"strings"
)
type SSHConnectorConfig struct {
+2 -1
View File
@@ -3,9 +3,10 @@ package connector
import (
"context"
"fmt"
"net/netip"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"net/netip"
)
// TCPConnector establishes a connection to the machine API through a direct TCP connection to an API endpoint.
+4 -3
View File
@@ -3,6 +3,10 @@ package connector
import (
"context"
"fmt"
"net"
"net/netip"
"strconv"
"github.com/psviderski/uncloud/internal/cli/config"
machine2 "github.com/psviderski/uncloud/internal/machine"
"github.com/psviderski/uncloud/internal/machine/network"
@@ -10,9 +14,6 @@ import (
"github.com/psviderski/uncloud/pkg/client"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"net"
"net/netip"
"strconv"
)
// WireGuardConnector establishes a connection to the cluster API through a WireGuard tunnel
+5 -3
View File
@@ -11,9 +11,11 @@ import (
type ContainerSpecStatus string
const ContainerUpToDate ContainerSpecStatus = "up-to-date"
const ContainerNeedsUpdate ContainerSpecStatus = "needs-update"
const ContainerNeedsRecreate ContainerSpecStatus = "needs-recreate"
const (
ContainerUpToDate ContainerSpecStatus = "up-to-date"
ContainerNeedsUpdate ContainerSpecStatus = "needs-update"
ContainerNeedsRecreate ContainerSpecStatus = "needs-recreate"
)
func EvalContainerSpecChange(current api.ServiceSpec, new api.ServiceSpec) ContainerSpecStatus {
current = current.SetDefaults()
+5 -4
View File
@@ -4,6 +4,11 @@ import (
"context"
"errors"
"fmt"
"io"
"net/http"
"sync"
"time"
"github.com/cenkalti/backoff/v4"
"github.com/docker/compose/v2/pkg/progress"
"github.com/psviderski/uncloud/internal/machine/api/pb"
@@ -11,10 +16,6 @@ import (
"github.com/psviderski/uncloud/pkg/api"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"io"
"net/http"
"sync"
"time"
)
// GetDomain returns the cluster domain name or ErrNotFound if it hasn't been reserved yet.
+2 -1
View File
@@ -2,10 +2,11 @@ package client
import (
"fmt"
"net/netip"
"github.com/psviderski/uncloud/internal/machine/network"
"github.com/psviderski/uncloud/internal/secret"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"net/netip"
)
type User struct {
-1
View File
@@ -20,7 +20,6 @@ import (
"github.com/psviderski/uncloud/pkg/api"
"github.com/psviderski/uncloud/pkg/client/compose"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
+6 -6
View File
@@ -259,8 +259,8 @@ func TestDeployment(t *testing.T) {
assert.Len(t, machines.ToSlice(), 3, "Expected 1 container on each machine")
// TODO: update the container spec in-place if only the placement constraint has changed.
//containers = serviceContainerIDs(svc)
//assert.True(t, initialContainers.IsSubset(containers), "Expected all initial containers to remain")
// containers = serviceContainerIDs(svc)
// assert.True(t, initialContainers.IsSubset(containers), "Expected all initial containers to remain")
})
t.Run("caddy", func(t *testing.T) {
@@ -334,7 +334,7 @@ func TestDeployment(t *testing.T) {
assertServiceMatchesSpec(t, svc, deployment.Spec)
assert.Equal(t, c.Machines[0].ID, svc.Containers[0].MachineID)
//initialContainerID := svc.Containers[0].Container.ID
// initialContainerID := svc.Containers[0].Container.ID
// Deploy to all machines without a placement constraint.
deployment, err = cli.NewCaddyDeployment(image, api.Placement{})
@@ -352,8 +352,8 @@ func TestDeployment(t *testing.T) {
machines := serviceMachines(svc)
assert.Len(t, machines.ToSlice(), 3, "Expected 1 container on each machine")
// TODO: update the container spec in-place if only the placement constraint has changed.
//containers := serviceContainerIDs(svc)
//assert.True(t, containers.Contains(initialContainerID), "Expected initial container to remain")
// containers := serviceContainerIDs(svc)
// assert.True(t, containers.Contains(initialContainerID), "Expected initial container to remain")
})
t.Run("replicated", func(t *testing.T) {
@@ -587,7 +587,7 @@ func TestDeployment(t *testing.T) {
require.Error(t, err, "Deployment should fail when volume doesn't exist")
require.Contains(t, err.Error(), "no machines available")
// TODO: implement and check for more details about the failed constraints.
//require.Contains(t, err.Error(), "volume 'non-existent-volume' not found")
// require.Contains(t, err.Error(), "volume 'non-existent-volume' not found")
})
// Tests that when a volume exists on a single machine, all requested replicas will be deployed to that machine,