mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55773e92ce | ||
|
|
37f543b905 | ||
|
|
e5f96509bf | ||
|
|
2f35ac6498 | ||
|
|
f75afa0cec | ||
|
|
0f38b128fa | ||
|
|
535b91fe52 | ||
|
|
5c8beb8bd3 | ||
|
|
2b4da1e6fe | ||
|
|
be8b4f079f | ||
|
|
59b96cc01f | ||
|
|
4c77fe2cfd | ||
|
|
3b89af4a11 | ||
|
|
1abadaef50 | ||
|
|
3b1ce42dd7 | ||
|
|
1640b4c433 | ||
|
|
44549c00fd | ||
|
|
26f34df3e6 | ||
|
|
89fb9efcfa | ||
|
|
638f320959 | ||
|
|
3f2e60ea74 | ||
|
|
8e0a24e781 | ||
|
|
e3e39dde32 |
@@ -0,0 +1,20 @@
|
||||
# EditorConfig is awesome: https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
# Default settings for all files
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Settings for Go files
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
# Settings for Bash scripts
|
||||
[*.sh]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
@@ -0,0 +1 @@
|
||||
github: [psviderski]
|
||||
@@ -1,5 +1,4 @@
|
||||
name: Go Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -12,10 +11,13 @@ on:
|
||||
paths:
|
||||
- ".github/**"
|
||||
- "**.go"
|
||||
- "**.proto"
|
||||
- "go.*"
|
||||
- "Makefile"
|
||||
- "scripts/**"
|
||||
- "test/**"
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -29,8 +31,37 @@ jobs:
|
||||
go-version: "1.23.2"
|
||||
|
||||
- name: Install dependencies
|
||||
run: go mod tidy
|
||||
run: |
|
||||
go mod tidy
|
||||
git diff --exit-code ||
|
||||
(echo "go.mod or go.sum has changed. Please run 'go mod tidy' and commit the changes." && exit 1)
|
||||
|
||||
- name: Run tests
|
||||
run: make test
|
||||
timeout-minutes: 10
|
||||
|
||||
check-protobuf:
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
# Run on more platforms so that mise lockfile checksums are checked/generated for all platforms.
|
||||
# See https://github.com/jdx/mise/issues/4276 for details.
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Install Mise
|
||||
uses: jdx/mise-action@13abe502c30c1559a5c37dff303831bab82c9402 # v2.2.3
|
||||
with:
|
||||
version: "2025.6.5"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- name: Generate Protobuf files
|
||||
run: |
|
||||
make proto
|
||||
# check if the generated files are up to date
|
||||
git diff --exit-code ||
|
||||
(echo "Generated protobuf files are not up to date. Please run 'make proto' and commit the changes." && exit 1)
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
[tools.go]
|
||||
version = "1.23.10"
|
||||
backend = "core:go"
|
||||
|
||||
[tools.go.checksums]
|
||||
"go1.23.10.darwin-arm64.tar.gz" = "sha256:25c64bfa8a8fd8e7f62fb54afa4354af8409a4bb2358c2699a1003b733e6fce5"
|
||||
"go1.23.10.linux-amd64.tar.gz" = "sha256:535f9f81802499f2a7dbfa70abb8fda3793725fcc29460f719815f6e10b5fd60"
|
||||
|
||||
[tools.protoc]
|
||||
version = "27.3"
|
||||
backend = "aqua:protocolbuffers/protobuf/protoc"
|
||||
|
||||
[tools.protoc.checksums]
|
||||
"protoc-27.3-linux-x86_64.zip" = "sha256:6dab2adab83f915126cab53540d48957c40e9e9023969c3e84d44bfb936c7741"
|
||||
"protoc-27.3-osx-aarch_64.zip" = "sha256:b22116bd97cdbd7ea25346abe635a9df268515fe5ef5afa93cd9a68fc2513f84"
|
||||
|
||||
[tools.protoc-gen-go]
|
||||
version = "1.34.2"
|
||||
backend = "aqua:protocolbuffers/protobuf-go/protoc-gen-go"
|
||||
|
||||
[tools.protoc-gen-go.checksums]
|
||||
"protoc-gen-go.v1.34.2.darwin.arm64.tar.gz" = "sha256:17aca7f948dbb624049030cf841e35895cf34183ba006e721247fdeb95ff2780"
|
||||
"protoc-gen-go.v1.34.2.linux.amd64.tar.gz" = "sha256:b87bc134dee55576a842141bf0ed27761c635d746780fce5dee038c6dd16554f"
|
||||
|
||||
[tools.protoc-gen-go-grpc]
|
||||
version = "1.5.1"
|
||||
backend = "aqua:grpc/grpc-go/protoc-gen-go-grpc"
|
||||
|
||||
[tools.protoc-gen-go-grpc.checksums]
|
||||
"protoc-gen-go-grpc.v1.5.1.darwin.arm64.tar.gz" = "sha256:d6083feb51dcfe59f26793e99ef01ef5eac68b64294ec2546711f614ac5878f3"
|
||||
"protoc-gen-go-grpc.v1.5.1.linux.amd64.tar.gz" = "sha256:a6cac4ea731e54aea304ad44d704a69d1cdc82997084b33637e21a89dc9229d6"
|
||||
@@ -1,5 +1,11 @@
|
||||
[settings]
|
||||
experimental = true
|
||||
|
||||
[tools]
|
||||
go = "1.23"
|
||||
protoc = "27.3"
|
||||
protoc-gen-go = "1.34.2"
|
||||
protoc-gen-go-grpc = "1.5.1"
|
||||
|
||||
[env]
|
||||
_.file = ".env"
|
||||
|
||||
@@ -92,9 +92,3 @@ vet:
|
||||
.PHONY: docs-image-push
|
||||
docs-image:
|
||||
docker buildx build --push --platform linux/amd64,linux/arm64 -t "$(DOCS_IMAGE)" ./docs
|
||||
|
||||
.PHONY: install-dev
|
||||
install-dev:
|
||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
|
||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1
|
||||
# TODO: install a pinned protoc version
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div align="center">
|
||||
<img src="./website/images/logo.svg" height="100" alt="Uncloud logo"/>
|
||||
<img src="./website/images/logo.svg" height="100" width="100" alt="Uncloud logo"/>
|
||||
<h1>Uncloud</h1>
|
||||
<p><strong>Docker simplicity. Multi-machine power.</strong></p>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<a href="https://docs.uncloud.run"><img src="https://img.shields.io/badge/Docs-blue.svg?style=for-the-badge&logo=gitbook&logoColor=white" alt="Documentation"></a>
|
||||
<a href="https://discord.gg/eR35KQJhPu"><img src="https://img.shields.io/badge/discord-5865F2.svg?style=for-the-badge&logo=discord&logoColor=white" alt="Join Discord"></a>
|
||||
<a href="https://x.com/psviderski"><img src="https://img.shields.io/badge/follow-black?style=for-the-badge&logo=X&logoColor=while" alt="Follow on X"></a>
|
||||
<a href="https://github.com/sponsors/psviderski"><img src="https://img.shields.io/badge/Donate-EA4AAA.svg?style=for-the-badge&logo=githubsponsors&logoColor=white" alt="Donate"></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -44,6 +45,11 @@ complexity of Kubernetes.
|
||||
* **Docker-like CLI**: Familiar commands for managing both infrastructure and applications.
|
||||
* **Remote management**: Control your entire infrastructure through SSH access to any single machine in the cluster.
|
||||
|
||||
### 🚀 Coming soon
|
||||
|
||||
* **[Unregistry](https://github.com/psviderski/unregistry) integration**: Push your Docker images directly to your
|
||||
machines without an external registry. It will transfer only the missing layers, making it fast and efficient.
|
||||
|
||||
## 🎬 Quick demo
|
||||
|
||||
The screenshot below demonstrates how I use Uncloud to deploy the [Uncloud Documentation](https://docs.uncloud.run)
|
||||
@@ -90,6 +96,8 @@ platform, whether you're running on a $5 VPS, a spare Mac mini, or a rack of bar
|
||||
# or using curl (macOS/Linux)
|
||||
curl -fsS https://get.uncloud.run/install.sh | sh
|
||||
```
|
||||
|
||||
See [Installation](https://docs.uncloud.run/getting-started/install-cli) for more options.
|
||||
|
||||
2. Initialise your first machine:
|
||||
|
||||
@@ -278,8 +286,11 @@ and there may be breaking changes between releases.
|
||||
We'd love your input! Here's how you can contribute:
|
||||
|
||||
* 🐛 Found a bug? [Open an issue](https://github.com/psviderski/uncloud/issues)
|
||||
* 💡 Have ideas or need help? [Join our Discord community](https://discord.gg/eR35KQJhPu) where we discuss features,
|
||||
roadmap, implementation details, and help each other out.
|
||||
* 💡 Have questions, ideas, or need help?
|
||||
* Start a discussion or join an existing one in
|
||||
the [Discussions](https://github.com/psviderski/uncloud/discussions).
|
||||
* Join our [Discord community](https://discord.gg/eR35KQJhPu) where we discuss features, roadmap, implementation
|
||||
details, and help each other out.
|
||||
|
||||
## 🙏 Inspiration & Acknowledgements
|
||||
|
||||
|
||||
@@ -14,18 +14,18 @@ import (
|
||||
)
|
||||
|
||||
func NewListCommand() *cobra.Command {
|
||||
var clusterContext string
|
||||
var contextName string
|
||||
cmd := &cobra.Command{
|
||||
Use: "ls",
|
||||
Aliases: []string{"list"},
|
||||
Short: "List machines in a cluster.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
||||
return list(cmd.Context(), uncli, clusterContext)
|
||||
return list(cmd.Context(), uncli, contextName)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(
|
||||
&clusterContext, "context", "c", "",
|
||||
&contextName, "context", "c", "",
|
||||
"Name of the cluster context. (default is the current context)",
|
||||
)
|
||||
return cmd
|
||||
@@ -68,7 +68,8 @@ func list(ctx context.Context, uncli *cli.CLI, clusterName string) error {
|
||||
}
|
||||
|
||||
if _, err = fmt.Fprintf(
|
||||
tw, "%s\t%s\t%s\t%s\t%s\n", m.Name, capitalise(member.State.String()), subnet, publicIP, strings.Join(endpoints, ", "),
|
||||
tw, "%s\t%s\t%s\t%s\t%s\n", m.Name, capitalise(member.State.String()), subnet, publicIP,
|
||||
strings.Join(endpoints, ", "),
|
||||
); err != nil {
|
||||
return fmt.Errorf("write row: %w", err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/charmbracelet/lipgloss/tree"
|
||||
"github.com/docker/compose/v2/pkg/progress"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/psviderski/uncloud/internal/cli"
|
||||
"github.com/psviderski/uncloud/pkg/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type removeOptions struct {
|
||||
force bool
|
||||
yes bool
|
||||
context string
|
||||
}
|
||||
|
||||
func NewRmCommand() *cobra.Command {
|
||||
opts := removeOptions{}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "rm MACHINE",
|
||||
Aliases: []string{"remove", "delete"},
|
||||
Short: "Remove a machine from a cluster.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
||||
return remove(cmd.Context(), uncli, args[0], opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&opts.context, "context", "c", "",
|
||||
"Name of the cluster context. (default is the current context)")
|
||||
cmd.Flags().BoolVarP(&opts.yes, "yes", "y", false,
|
||||
"Do not prompt for confirmation before removing the machine.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func remove(ctx context.Context, uncli *cli.CLI, machineName string, opts removeOptions) error {
|
||||
client, err := uncli.ConnectCluster(ctx, opts.context)
|
||||
if err != nil {
|
||||
return fmt.Errorf("connect to cluster: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// Verify the machine exists and list all service containers on it including stopped ones.
|
||||
listCtx, machines, err := api.ProxyMachinesContext(ctx, client, []string{machineName})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(machines) == 0 {
|
||||
return fmt.Errorf("machine '%s' not found in the cluster", machineName)
|
||||
}
|
||||
m := machines[0].Machine
|
||||
|
||||
listOpts := container.ListOptions{All: true}
|
||||
machineContainers, err := client.Docker.ListServiceContainers(listCtx, "", listOpts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("list containers: %w", err)
|
||||
}
|
||||
containers := machineContainers[0].Containers
|
||||
|
||||
if len(containers) > 0 {
|
||||
plural := ""
|
||||
if len(containers) > 1 {
|
||||
plural = "s"
|
||||
}
|
||||
fmt.Printf("Found %d service container%s on machine '%s':\n", len(containers), plural, m.Name)
|
||||
fmt.Println(formatContainerTree(containers))
|
||||
fmt.Println()
|
||||
fmt.Println("This will remove all service containers on the machine, reset it to the uninitialised state, " +
|
||||
"and remove it from the cluster.")
|
||||
} else {
|
||||
fmt.Printf("No service containers found on machine '%s'.\n", m.Name)
|
||||
fmt.Println("This will reset the machine to the uninitialised state and remove it from the cluster.")
|
||||
}
|
||||
|
||||
if !opts.yes {
|
||||
confirmed, err := cli.Confirm()
|
||||
if err != nil {
|
||||
return fmt.Errorf("confirm removal: %w", err)
|
||||
}
|
||||
if !confirmed {
|
||||
fmt.Println("Cancelled. Machine was not removed.")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(containers) > 0 {
|
||||
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)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// TODO: 4. Implement and call Reset via Machine API to reset the machine state to uninitialised.
|
||||
// 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
|
||||
}
|
||||
|
||||
// formatContainerTree formats a list of containers grouped by service as a tree structure.
|
||||
func formatContainerTree(containers []api.ServiceContainer) string {
|
||||
if len(containers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Group containers by service.
|
||||
serviceContainers := make(map[string][]api.ServiceContainer)
|
||||
for _, ctr := range containers {
|
||||
serviceName := ctr.ServiceName()
|
||||
serviceContainers[serviceName] = append(serviceContainers[serviceName], ctr)
|
||||
}
|
||||
|
||||
// Build tree output.
|
||||
var output []string
|
||||
serviceNames := slices.Sorted(maps.Keys(serviceContainers))
|
||||
for _, serviceName := range serviceNames {
|
||||
ctrs := serviceContainers[serviceName]
|
||||
mode := ctrs[0].ServiceMode()
|
||||
|
||||
// Format a tree for the service with its containers.
|
||||
plural := ""
|
||||
if len(ctrs) > 1 {
|
||||
plural = "s"
|
||||
}
|
||||
t := tree.Root(fmt.Sprintf("• %s (%s, %d container%s)", serviceName, mode, len(ctrs), plural)).
|
||||
EnumeratorStyle(lipgloss.NewStyle().MarginLeft(2).MarginRight(1))
|
||||
|
||||
// Add containers as children.
|
||||
for _, ctr := range ctrs {
|
||||
state, _ := ctr.HumanState()
|
||||
info := fmt.Sprintf("%s • %s • %s", ctr.Name, ctr.Config.Image, state)
|
||||
t.Child(info)
|
||||
}
|
||||
|
||||
output = append(output, t.String())
|
||||
}
|
||||
|
||||
return strings.Join(output, "\n")
|
||||
}
|
||||
|
||||
// removeContainers removes the given service containers from the machine.
|
||||
func removeContainers(ctx context.Context, client api.Client, containers []api.ServiceContainer) error {
|
||||
if len(containers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
errCh := make(chan error)
|
||||
|
||||
for _, ctr := range containers {
|
||||
wg.Add(1)
|
||||
go func(c api.ServiceContainer) {
|
||||
defer wg.Done()
|
||||
|
||||
// Gracefully stop the container before removing it.
|
||||
err := client.StopContainer(ctx, c.ServiceID(), c.ID, container.StopOptions{})
|
||||
if err != nil && !errors.Is(err, api.ErrNotFound) {
|
||||
errCh <- fmt.Errorf("stop container '%s': %w", c.ID, err)
|
||||
}
|
||||
|
||||
err = client.RemoveContainer(ctx, c.ServiceID(), c.ID, container.RemoveOptions{
|
||||
// Remove anonymous volumes created by the container.
|
||||
RemoveVolumes: true,
|
||||
})
|
||||
if err != nil && !errors.Is(err, api.ErrNotFound) {
|
||||
errCh <- fmt.Errorf("remove container '%s': %w", c.ID, err)
|
||||
}
|
||||
}(ctr)
|
||||
}
|
||||
|
||||
go func() {
|
||||
wg.Wait()
|
||||
close(errCh)
|
||||
}()
|
||||
|
||||
var err error
|
||||
for e := range errCh {
|
||||
err = errors.Join(err, e)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -14,6 +14,7 @@ func NewRootCommand() *cobra.Command {
|
||||
NewAddCommand(),
|
||||
NewInitCommand(),
|
||||
NewListCommand(),
|
||||
NewRmCommand(),
|
||||
NewTokenCommand(),
|
||||
)
|
||||
return cmd
|
||||
|
||||
@@ -55,5 +55,4 @@ func main() {
|
||||
}()
|
||||
|
||||
cobra.CheckErr(cmd.ExecuteContext(ctx))
|
||||
|
||||
}
|
||||
|
||||
@@ -97,6 +97,22 @@ After installation, verify that `uc` command is working:
|
||||
uc --version
|
||||
```
|
||||
|
||||
## Linux (via package managers)
|
||||
|
||||
### Debian
|
||||
|
||||
Via unofficial repository packages created and maintained at [uncloud-debian](https://github.com/dariogriffo/uncloud-debian/) by @dariogriffo
|
||||
|
||||
You can install uncloud the debian way by running:
|
||||
|
||||
```sh
|
||||
curl -sS https://debian.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/debian.griffo.io.gpg
|
||||
echo "deb https://debian.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/debian.griffo.io.list
|
||||
apt install -y uncloud
|
||||
```
|
||||
|
||||
or in the releases page of the repository [here](https://github.com/dariogriffo/uncloud-debian/releases)
|
||||
|
||||
## Next steps
|
||||
|
||||
Now that you have `uc` installed, you're ready to:
|
||||
|
||||
@@ -169,7 +169,7 @@ as HTTPS endpoint on the previously reserved domain via Caddy.
|
||||
uc run --name excalidraw --publish 80/https excalidraw/excalidraw
|
||||
```
|
||||
|
||||
You'll the progress of the deployment and the public URL where you can access the service:
|
||||
You'll see the progress of the deployment and the public URL where you can access the service:
|
||||
|
||||
```
|
||||
[+] Running service excalidraw (replicated mode) 2/2
|
||||
|
||||
@@ -2,8 +2,6 @@ module github.com/psviderski/uncloud
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.2
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
@@ -37,6 +35,7 @@ require (
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/lmittmann/tint v1.0.5
|
||||
github.com/miekg/dns v1.1.65
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0
|
||||
github.com/siderolabs/discovery-api v0.1.4
|
||||
@@ -215,7 +214,6 @@ require (
|
||||
github.com/moby/sys/signal v0.7.1 // indirect
|
||||
github.com/moby/sys/user v0.3.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
|
||||
@@ -105,6 +105,8 @@ github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
|
||||
github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
|
||||
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
@@ -153,6 +155,8 @@ github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA
|
||||
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
|
||||
github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY=
|
||||
github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
|
||||
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240919170804-a4978c8e603a h1:JMdM89Udp/cOl5tC3MuUJXTPE/nAdU1oyt9jRU44qq8=
|
||||
github.com/charmbracelet/x/exp/strings v0.0.0-20240919170804-a4978c8e603a/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
|
||||
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
|
||||
|
||||
+10
-31
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
composetypes "github.com/compose-spec/compose-go/v2/types"
|
||||
@@ -15,7 +14,9 @@ import (
|
||||
"github.com/docker/docker/api/types/image"
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/moby/term"
|
||||
)
|
||||
|
||||
type BuildOptions struct {
|
||||
@@ -102,19 +103,10 @@ func buildSingleService(ctx context.Context, dockerCli *dockerclient.Client, ser
|
||||
}
|
||||
defer buildResponse.Body.Close()
|
||||
|
||||
// Print the build output
|
||||
decoder := json.NewDecoder(buildResponse.Body)
|
||||
for {
|
||||
var message map[string]interface{}
|
||||
if err := decoder.Decode(&message); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return "", fmt.Errorf("failed to decode build output for service %s: %w", service.Name, err)
|
||||
}
|
||||
|
||||
if stream, ok := message["stream"]; ok {
|
||||
fmt.Print(stream)
|
||||
}
|
||||
// Display the build response
|
||||
fd, isTerminal := term.GetFdInfo(os.Stdout)
|
||||
if err := jsonmessage.DisplayJSONMessagesStream(buildResponse.Body, os.Stdout, fd, isTerminal, nil); err != nil {
|
||||
return "", fmt.Errorf("failed to display build response for service %s: %w", service.Name, err)
|
||||
}
|
||||
|
||||
return imageName, nil
|
||||
@@ -161,24 +153,11 @@ func pushSingleServiceImage(ctx context.Context, dockerCli *dockerclient.Client,
|
||||
}
|
||||
defer pushResponse.Close()
|
||||
|
||||
fmt.Printf("Pushing image %s for service %s\n", imageName, serviceName)
|
||||
fmt.Printf("Pushing image %s for service %s...\n", imageName, serviceName)
|
||||
|
||||
// Handle output and errors
|
||||
decoder := json.NewDecoder(pushResponse)
|
||||
for {
|
||||
var message map[string]interface{}
|
||||
if err := decoder.Decode(&message); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to decode push output for image %s: %w", imageName, err)
|
||||
}
|
||||
if stream, ok := message["stream"]; ok {
|
||||
fmt.Print(stream)
|
||||
} else if errorMessage, ok := message["error"]; ok {
|
||||
return fmt.Errorf("error pushing image %s: %s", imageName, errorMessage)
|
||||
} else if status, ok := message["status"]; ok {
|
||||
fmt.Printf(" %s\n", status)
|
||||
}
|
||||
fd, isTerminal := term.GetFdInfo(os.Stdout)
|
||||
if err := jsonmessage.DisplayJSONMessagesStream(pushResponse, os.Stdout, fd, isTerminal, nil); err != nil {
|
||||
return fmt.Errorf("failed to display push response for image %s: %w", imageName, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Image %s pushed successfully.\n", imageName)
|
||||
|
||||
@@ -21,63 +21,6 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type CheckPrerequisitesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Overall status of the checks.
|
||||
Satisfied bool `protobuf:"varint,1,opt,name=satisfied,proto3" json:"satisfied,omitempty"`
|
||||
// Error message if not satisfied (empty if all checks pass).
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) Reset() {
|
||||
*x = CheckPrerequisitesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CheckPrerequisitesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CheckPrerequisitesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CheckPrerequisitesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) GetSatisfied() bool {
|
||||
if x != nil {
|
||||
return x.Satisfied
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) GetError() string {
|
||||
if x != nil {
|
||||
return x.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type MachineInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -92,7 +35,7 @@ type MachineInfo struct {
|
||||
func (x *MachineInfo) Reset() {
|
||||
*x = MachineInfo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[1]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -105,7 +48,7 @@ func (x *MachineInfo) String() string {
|
||||
func (*MachineInfo) ProtoMessage() {}
|
||||
|
||||
func (x *MachineInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[1]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -118,7 +61,7 @@ func (x *MachineInfo) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use MachineInfo.ProtoReflect.Descriptor instead.
|
||||
func (*MachineInfo) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{1}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *MachineInfo) GetId() string {
|
||||
@@ -163,7 +106,7 @@ type NetworkConfig struct {
|
||||
func (x *NetworkConfig) Reset() {
|
||||
*x = NetworkConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[2]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -176,7 +119,7 @@ func (x *NetworkConfig) String() string {
|
||||
func (*NetworkConfig) ProtoMessage() {}
|
||||
|
||||
func (x *NetworkConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[2]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -189,7 +132,7 @@ func (x *NetworkConfig) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use NetworkConfig.ProtoReflect.Descriptor instead.
|
||||
func (*NetworkConfig) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{2}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *NetworkConfig) GetSubnet() *IPPrefix {
|
||||
@@ -220,6 +163,63 @@ func (x *NetworkConfig) GetPublicKey() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type CheckPrerequisitesResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Overall status of the checks.
|
||||
Satisfied bool `protobuf:"varint,1,opt,name=satisfied,proto3" json:"satisfied,omitempty"`
|
||||
// Error message if not satisfied (empty if all checks pass).
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) Reset() {
|
||||
*x = CheckPrerequisitesResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CheckPrerequisitesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CheckPrerequisitesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CheckPrerequisitesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) GetSatisfied() bool {
|
||||
if x != nil {
|
||||
return x.Satisfied
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *CheckPrerequisitesResponse) GetError() string {
|
||||
if x != nil {
|
||||
return x.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type InitClusterRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -466,6 +466,44 @@ func (x *TokenResponse) GetToken() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type ResetRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *ResetRequest) Reset() {
|
||||
*x = ResetRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ResetRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResetRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ResetRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResetRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ResetRequest) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -480,7 +518,7 @@ type Service struct {
|
||||
func (x *Service) Reset() {
|
||||
*x = Service{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[7]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -493,7 +531,7 @@ func (x *Service) String() string {
|
||||
func (*Service) ProtoMessage() {}
|
||||
|
||||
func (x *Service) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[7]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -506,7 +544,7 @@ func (x *Service) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Service.ProtoReflect.Descriptor instead.
|
||||
func (*Service) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{7}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *Service) GetId() string {
|
||||
@@ -548,7 +586,7 @@ type InspectServiceRequest struct {
|
||||
func (x *InspectServiceRequest) Reset() {
|
||||
*x = InspectServiceRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[8]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -561,7 +599,7 @@ func (x *InspectServiceRequest) String() string {
|
||||
func (*InspectServiceRequest) ProtoMessage() {}
|
||||
|
||||
func (x *InspectServiceRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[8]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -574,7 +612,7 @@ func (x *InspectServiceRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use InspectServiceRequest.ProtoReflect.Descriptor instead.
|
||||
func (*InspectServiceRequest) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{8}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *InspectServiceRequest) GetId() string {
|
||||
@@ -595,7 +633,7 @@ type InspectServiceResponse struct {
|
||||
func (x *InspectServiceResponse) Reset() {
|
||||
*x = InspectServiceResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[9]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -608,7 +646,7 @@ func (x *InspectServiceResponse) String() string {
|
||||
func (*InspectServiceResponse) ProtoMessage() {}
|
||||
|
||||
func (x *InspectServiceResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[9]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -621,7 +659,7 @@ func (x *InspectServiceResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use InspectServiceResponse.ProtoReflect.Descriptor instead.
|
||||
func (*InspectServiceResponse) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{9}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *InspectServiceResponse) GetService() *Service {
|
||||
@@ -644,7 +682,7 @@ type Service_Container struct {
|
||||
func (x *Service_Container) Reset() {
|
||||
*x = Service_Container{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[10]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -657,7 +695,7 @@ func (x *Service_Container) String() string {
|
||||
func (*Service_Container) ProtoMessage() {}
|
||||
|
||||
func (x *Service_Container) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[10]
|
||||
mi := &file_internal_machine_api_pb_machine_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -670,7 +708,7 @@ func (x *Service_Container) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Service_Container.ProtoReflect.Descriptor instead.
|
||||
func (*Service_Container) Descriptor() ([]byte, []int) {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{7, 0}
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescGZIP(), []int{8, 0}
|
||||
}
|
||||
|
||||
func (x *Service_Container) GetMachineId() string {
|
||||
@@ -697,31 +735,31 @@ var file_internal_machine_api_pb_machine_proto_rawDesc = []byte{
|
||||
0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x70, 0x62, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
|
||||
0x50, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69,
|
||||
0x73, 0x69, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x09, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66, 0x69, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x22, 0x85, 0x01, 0x0a, 0x0b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x65, 0x74,
|
||||
0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x12, 0x24, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x50, 0x52,
|
||||
0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x22, 0xae, 0x01, 0x0a, 0x0d, 0x4e, 0x65,
|
||||
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x06, 0x73,
|
||||
0x75, 0x62, 0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x06, 0x73, 0x75, 0x62, 0x6e,
|
||||
0x65, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x5f, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x49, 0x50, 0x52, 0x0c, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x70,
|
||||
0x12, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x50, 0x50, 0x6f, 0x72, 0x74,
|
||||
0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0xc3, 0x01, 0x0a, 0x12, 0x49,
|
||||
0x85, 0x01, 0x0a, 0x0b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f,
|
||||
0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x12, 0x24, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x70, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x50, 0x52, 0x08, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x70, 0x22, 0xae, 0x01, 0x0a, 0x0d, 0x4e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x75, 0x62,
|
||||
0x6e, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x06, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74,
|
||||
0x12, 0x2c, 0x0a, 0x0d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69,
|
||||
0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x50,
|
||||
0x52, 0x0c, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x29,
|
||||
0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x09,
|
||||
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x50, 0x0a, 0x1a, 0x43, 0x68, 0x65, 0x63,
|
||||
0x6b, 0x50, 0x72, 0x65, 0x72, 0x65, 0x71, 0x75, 0x69, 0x73, 0x69, 0x74, 0x65, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x61, 0x74, 0x69, 0x73, 0x66,
|
||||
0x69, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x61, 0x74, 0x69, 0x73,
|
||||
0x66, 0x69, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc3, 0x01, 0x0a, 0x12, 0x49,
|
||||
0x6e, 0x69, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x4e,
|
||||
@@ -748,7 +786,8 @@ var file_internal_machine_api_pb_machine_proto_rawDesc = []byte{
|
||||
0x0d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x25,
|
||||
0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc3, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x0e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
|
||||
0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20,
|
||||
@@ -767,7 +806,7 @@ var file_internal_machine_api_pb_machine_proto_rawDesc = []byte{
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26,
|
||||
0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0x8f, 0x03, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xc3, 0x03, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x6e, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x72, 0x65,
|
||||
0x71, 0x75, 0x69, 0x73, 0x69, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
@@ -787,16 +826,19 @@ var file_internal_machine_api_pb_machine_proto_rawDesc = []byte{
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x49, 0x6e, 0x73, 0x70,
|
||||
0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x49, 0x0a,
|
||||
0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x73, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x6b,
|
||||
0x69, 0x2f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70,
|
||||
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x69, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a,
|
||||
0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x12, 0x49, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63,
|
||||
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x37, 0x5a, 0x35,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x73, 0x76, 0x69, 0x64,
|
||||
0x65, 0x72, 0x73, 0x6b, 0x69, 0x2f, 0x75, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -811,51 +853,54 @@ func file_internal_machine_api_pb_machine_proto_rawDescGZIP() []byte {
|
||||
return file_internal_machine_api_pb_machine_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_internal_machine_api_pb_machine_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_internal_machine_api_pb_machine_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_internal_machine_api_pb_machine_proto_goTypes = []any{
|
||||
(*CheckPrerequisitesResponse)(nil), // 0: api.CheckPrerequisitesResponse
|
||||
(*MachineInfo)(nil), // 1: api.MachineInfo
|
||||
(*NetworkConfig)(nil), // 2: api.NetworkConfig
|
||||
(*MachineInfo)(nil), // 0: api.MachineInfo
|
||||
(*NetworkConfig)(nil), // 1: api.NetworkConfig
|
||||
(*CheckPrerequisitesResponse)(nil), // 2: api.CheckPrerequisitesResponse
|
||||
(*InitClusterRequest)(nil), // 3: api.InitClusterRequest
|
||||
(*InitClusterResponse)(nil), // 4: api.InitClusterResponse
|
||||
(*JoinClusterRequest)(nil), // 5: api.JoinClusterRequest
|
||||
(*TokenResponse)(nil), // 6: api.TokenResponse
|
||||
(*Service)(nil), // 7: api.Service
|
||||
(*InspectServiceRequest)(nil), // 8: api.InspectServiceRequest
|
||||
(*InspectServiceResponse)(nil), // 9: api.InspectServiceResponse
|
||||
(*Service_Container)(nil), // 10: api.Service.Container
|
||||
(*IP)(nil), // 11: api.IP
|
||||
(*IPPrefix)(nil), // 12: api.IPPrefix
|
||||
(*IPPort)(nil), // 13: api.IPPort
|
||||
(*emptypb.Empty)(nil), // 14: google.protobuf.Empty
|
||||
(*ResetRequest)(nil), // 7: api.ResetRequest
|
||||
(*Service)(nil), // 8: api.Service
|
||||
(*InspectServiceRequest)(nil), // 9: api.InspectServiceRequest
|
||||
(*InspectServiceResponse)(nil), // 10: api.InspectServiceResponse
|
||||
(*Service_Container)(nil), // 11: api.Service.Container
|
||||
(*IP)(nil), // 12: api.IP
|
||||
(*IPPrefix)(nil), // 13: api.IPPrefix
|
||||
(*IPPort)(nil), // 14: api.IPPort
|
||||
(*emptypb.Empty)(nil), // 15: google.protobuf.Empty
|
||||
}
|
||||
var file_internal_machine_api_pb_machine_proto_depIdxs = []int32{
|
||||
2, // 0: api.MachineInfo.network:type_name -> api.NetworkConfig
|
||||
11, // 1: api.MachineInfo.public_ip:type_name -> api.IP
|
||||
12, // 2: api.NetworkConfig.subnet:type_name -> api.IPPrefix
|
||||
11, // 3: api.NetworkConfig.management_ip:type_name -> api.IP
|
||||
13, // 4: api.NetworkConfig.endpoints:type_name -> api.IPPort
|
||||
12, // 5: api.InitClusterRequest.network:type_name -> api.IPPrefix
|
||||
11, // 6: api.InitClusterRequest.public_ip:type_name -> api.IP
|
||||
1, // 7: api.InitClusterResponse.machine:type_name -> api.MachineInfo
|
||||
1, // 8: api.JoinClusterRequest.machine:type_name -> api.MachineInfo
|
||||
1, // 9: api.JoinClusterRequest.other_machines:type_name -> api.MachineInfo
|
||||
10, // 10: api.Service.containers:type_name -> api.Service.Container
|
||||
7, // 11: api.InspectServiceResponse.service:type_name -> api.Service
|
||||
14, // 12: api.Machine.CheckPrerequisites:input_type -> google.protobuf.Empty
|
||||
1, // 0: api.MachineInfo.network:type_name -> api.NetworkConfig
|
||||
12, // 1: api.MachineInfo.public_ip:type_name -> api.IP
|
||||
13, // 2: api.NetworkConfig.subnet:type_name -> api.IPPrefix
|
||||
12, // 3: api.NetworkConfig.management_ip:type_name -> api.IP
|
||||
14, // 4: api.NetworkConfig.endpoints:type_name -> api.IPPort
|
||||
13, // 5: api.InitClusterRequest.network:type_name -> api.IPPrefix
|
||||
12, // 6: api.InitClusterRequest.public_ip:type_name -> api.IP
|
||||
0, // 7: api.InitClusterResponse.machine:type_name -> api.MachineInfo
|
||||
0, // 8: api.JoinClusterRequest.machine:type_name -> api.MachineInfo
|
||||
0, // 9: api.JoinClusterRequest.other_machines:type_name -> api.MachineInfo
|
||||
11, // 10: api.Service.containers:type_name -> api.Service.Container
|
||||
8, // 11: api.InspectServiceResponse.service:type_name -> api.Service
|
||||
15, // 12: api.Machine.CheckPrerequisites:input_type -> google.protobuf.Empty
|
||||
3, // 13: api.Machine.InitCluster:input_type -> api.InitClusterRequest
|
||||
5, // 14: api.Machine.JoinCluster:input_type -> api.JoinClusterRequest
|
||||
14, // 15: api.Machine.Token:input_type -> google.protobuf.Empty
|
||||
14, // 16: api.Machine.Inspect:input_type -> google.protobuf.Empty
|
||||
8, // 17: api.Machine.InspectService:input_type -> api.InspectServiceRequest
|
||||
0, // 18: api.Machine.CheckPrerequisites:output_type -> api.CheckPrerequisitesResponse
|
||||
4, // 19: api.Machine.InitCluster:output_type -> api.InitClusterResponse
|
||||
14, // 20: api.Machine.JoinCluster:output_type -> google.protobuf.Empty
|
||||
6, // 21: api.Machine.Token:output_type -> api.TokenResponse
|
||||
1, // 22: api.Machine.Inspect:output_type -> api.MachineInfo
|
||||
9, // 23: api.Machine.InspectService:output_type -> api.InspectServiceResponse
|
||||
18, // [18:24] is the sub-list for method output_type
|
||||
12, // [12:18] is the sub-list for method input_type
|
||||
15, // 15: api.Machine.Token:input_type -> google.protobuf.Empty
|
||||
15, // 16: api.Machine.Inspect:input_type -> google.protobuf.Empty
|
||||
7, // 17: api.Machine.Reset:input_type -> api.ResetRequest
|
||||
9, // 18: api.Machine.InspectService:input_type -> api.InspectServiceRequest
|
||||
2, // 19: api.Machine.CheckPrerequisites:output_type -> api.CheckPrerequisitesResponse
|
||||
4, // 20: api.Machine.InitCluster:output_type -> api.InitClusterResponse
|
||||
15, // 21: api.Machine.JoinCluster:output_type -> google.protobuf.Empty
|
||||
6, // 22: api.Machine.Token:output_type -> api.TokenResponse
|
||||
0, // 23: api.Machine.Inspect:output_type -> api.MachineInfo
|
||||
15, // 24: api.Machine.Reset:output_type -> google.protobuf.Empty
|
||||
10, // 25: api.Machine.InspectService:output_type -> api.InspectServiceResponse
|
||||
19, // [19:26] is the sub-list for method output_type
|
||||
12, // [12:19] is the sub-list for method input_type
|
||||
12, // [12:12] is the sub-list for extension type_name
|
||||
12, // [12:12] is the sub-list for extension extendee
|
||||
0, // [0:12] is the sub-list for field type_name
|
||||
@@ -869,18 +914,6 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
file_internal_machine_api_pb_common_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*CheckPrerequisitesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*MachineInfo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -892,7 +925,7 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*NetworkConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -904,6 +937,18 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*CheckPrerequisitesResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[3].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*InitClusterRequest); i {
|
||||
case 0:
|
||||
@@ -953,7 +998,7 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[7].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Service); i {
|
||||
switch v := v.(*ResetRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -965,7 +1010,7 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[8].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*InspectServiceRequest); i {
|
||||
switch v := v.(*Service); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -977,7 +1022,7 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[9].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*InspectServiceResponse); i {
|
||||
switch v := v.(*InspectServiceRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -989,6 +1034,18 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[10].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*InspectServiceResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_internal_machine_api_pb_machine_proto_msgTypes[11].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Service_Container); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1011,7 +1068,7 @@ func file_internal_machine_api_pb_machine_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_internal_machine_api_pb_machine_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -14,6 +14,9 @@ service Machine {
|
||||
rpc JoinCluster(JoinClusterRequest) returns (google.protobuf.Empty);
|
||||
rpc Token(google.protobuf.Empty) returns (TokenResponse);
|
||||
rpc Inspect(google.protobuf.Empty) returns (MachineInfo);
|
||||
// Reset restores the machine to a clean state, removing all cluster-related сonfiguration and data.
|
||||
rpc Reset(ResetRequest) returns (google.protobuf.Empty);
|
||||
|
||||
rpc InspectService(InspectServiceRequest) returns (InspectServiceResponse);
|
||||
}
|
||||
|
||||
@@ -61,6 +64,9 @@ message TokenResponse {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message ResetRequest {
|
||||
}
|
||||
|
||||
message Service {
|
||||
string id = 1;
|
||||
string name = 2;
|
||||
|
||||
@@ -25,6 +25,7 @@ const (
|
||||
Machine_JoinCluster_FullMethodName = "/api.Machine/JoinCluster"
|
||||
Machine_Token_FullMethodName = "/api.Machine/Token"
|
||||
Machine_Inspect_FullMethodName = "/api.Machine/Inspect"
|
||||
Machine_Reset_FullMethodName = "/api.Machine/Reset"
|
||||
Machine_InspectService_FullMethodName = "/api.Machine/InspectService"
|
||||
)
|
||||
|
||||
@@ -32,11 +33,14 @@ const (
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type MachineClient interface {
|
||||
// CheckPrerequisites verifies if the machine meets all necessary system requirements to participate in the cluster.
|
||||
CheckPrerequisites(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CheckPrerequisitesResponse, error)
|
||||
InitCluster(ctx context.Context, in *InitClusterRequest, opts ...grpc.CallOption) (*InitClusterResponse, error)
|
||||
JoinCluster(ctx context.Context, in *JoinClusterRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
Token(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*TokenResponse, error)
|
||||
Inspect(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*MachineInfo, error)
|
||||
// Reset restores the machine to a clean state, removing all cluster-related сonfiguration and data.
|
||||
Reset(ctx context.Context, in *ResetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
InspectService(ctx context.Context, in *InspectServiceRequest, opts ...grpc.CallOption) (*InspectServiceResponse, error)
|
||||
}
|
||||
|
||||
@@ -98,6 +102,16 @@ func (c *machineClient) Inspect(ctx context.Context, in *emptypb.Empty, opts ...
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *machineClient) Reset(ctx context.Context, in *ResetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, Machine_Reset_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *machineClient) InspectService(ctx context.Context, in *InspectServiceRequest, opts ...grpc.CallOption) (*InspectServiceResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(InspectServiceResponse)
|
||||
@@ -112,11 +126,14 @@ func (c *machineClient) InspectService(ctx context.Context, in *InspectServiceRe
|
||||
// All implementations must embed UnimplementedMachineServer
|
||||
// for forward compatibility.
|
||||
type MachineServer interface {
|
||||
// CheckPrerequisites verifies if the machine meets all necessary system requirements to participate in the cluster.
|
||||
CheckPrerequisites(context.Context, *emptypb.Empty) (*CheckPrerequisitesResponse, error)
|
||||
InitCluster(context.Context, *InitClusterRequest) (*InitClusterResponse, error)
|
||||
JoinCluster(context.Context, *JoinClusterRequest) (*emptypb.Empty, error)
|
||||
Token(context.Context, *emptypb.Empty) (*TokenResponse, error)
|
||||
Inspect(context.Context, *emptypb.Empty) (*MachineInfo, error)
|
||||
// Reset restores the machine to a clean state, removing all cluster-related сonfiguration and data.
|
||||
Reset(context.Context, *ResetRequest) (*emptypb.Empty, error)
|
||||
InspectService(context.Context, *InspectServiceRequest) (*InspectServiceResponse, error)
|
||||
mustEmbedUnimplementedMachineServer()
|
||||
}
|
||||
@@ -143,6 +160,9 @@ func (UnimplementedMachineServer) Token(context.Context, *emptypb.Empty) (*Token
|
||||
func (UnimplementedMachineServer) Inspect(context.Context, *emptypb.Empty) (*MachineInfo, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Inspect not implemented")
|
||||
}
|
||||
func (UnimplementedMachineServer) Reset(context.Context, *ResetRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Reset not implemented")
|
||||
}
|
||||
func (UnimplementedMachineServer) InspectService(context.Context, *InspectServiceRequest) (*InspectServiceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method InspectService not implemented")
|
||||
}
|
||||
@@ -257,6 +277,24 @@ func _Machine_Inspect_Handler(srv interface{}, ctx context.Context, dec func(int
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Machine_Reset_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ResetRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MachineServer).Reset(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Machine_Reset_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MachineServer).Reset(ctx, req.(*ResetRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Machine_InspectService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(InspectServiceRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -302,6 +340,10 @@ var Machine_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Inspect",
|
||||
Handler: _Machine_Inspect_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Reset",
|
||||
Handler: _Machine_Reset_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "InspectService",
|
||||
Handler: _Machine_InspectService_Handler,
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/psviderski/uncloud/internal/machine/dns"
|
||||
"github.com/psviderski/uncloud/internal/machine/firewall"
|
||||
"github.com/psviderski/uncloud/internal/machine/network"
|
||||
"github.com/psviderski/uncloud/pkg/api"
|
||||
)
|
||||
|
||||
// EnsureUncloudNetwork creates the Docker bridge network NetworkName with the provided machine subnet
|
||||
@@ -52,6 +53,14 @@ func (m *Manager) EnsureUncloudNetwork(ctx context.Context, subnet netip.Prefix,
|
||||
},
|
||||
},
|
||||
},
|
||||
Labels: map[string]string{
|
||||
api.LabelManaged: "",
|
||||
},
|
||||
Options: map[string]string{
|
||||
// Starting with Docker 28.2.0 (https://github.com/moby/moby/pull/49832), we have to explicitly
|
||||
// allow direct routing from the WireGuard interface to the bridge network.
|
||||
"com.docker.network.bridge.trusted_host_interfaces": network.WireGuardInterfaceName,
|
||||
},
|
||||
},
|
||||
); err != nil {
|
||||
return fmt.Errorf("create Docker network '%s': %w", NetworkName, err)
|
||||
|
||||
@@ -345,6 +345,12 @@ func (s *Server) CreateVolume(ctx context.Context, req *pb.CreateVolumeRequest)
|
||||
return nil, status.Errorf(codes.InvalidArgument, "unmarshal options: %v", err)
|
||||
}
|
||||
|
||||
// Always add the managed label to the volume to indicate that it is managed by Uncloud.
|
||||
if opts.Labels == nil {
|
||||
opts.Labels = make(map[string]string)
|
||||
}
|
||||
opts.Labels[api.LabelManaged] = ""
|
||||
|
||||
vol, err := s.client.VolumeCreate(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
|
||||
@@ -776,6 +776,22 @@ func (m *Machine) Inspect(_ context.Context, _ *emptypb.Empty) (*pb.MachineInfo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Reset restores the machine to a clean state, removing all cluster-related сonfiguration and data and scheduling
|
||||
// a graceful shutdown. The uncloud daemon will restart the machine if managed by systemd.
|
||||
func (m *Machine) Reset(ctx context.Context, _ *pb.ResetRequest) (*emptypb.Empty, error) {
|
||||
slog.Info("Resetting machine to a clean state.")
|
||||
|
||||
// TODO: stop and remove all managed service containers.
|
||||
// TODO: check if the request is coming from the unix or network socket. For the network socket, the reset should
|
||||
// be called in a separate goroutine to avoid blocking the RPC response.
|
||||
// TODO: stop the network controller
|
||||
// TODO: implement and call Cleanup on the network controller to remove Docker network, WG interface, iptables
|
||||
// rules, corrosion state, ?stop corrosion service.
|
||||
// TODO: stop the machine and remove the machine.json state. The daemon should restart it to a clean state.
|
||||
|
||||
return &emptypb.Empty{}, status.Error(codes.Unimplemented, "reset machine is not implemented yet")
|
||||
}
|
||||
|
||||
// InspectService returns detailed information about a service and its containers stored in the cluster store.
|
||||
func (m *Machine) InspectService(
|
||||
ctx context.Context, req *pb.InspectServiceRequest,
|
||||
|
||||
@@ -191,10 +191,10 @@ func (nc *networkController) Run(ctx context.Context) error {
|
||||
})
|
||||
|
||||
errGroup.Go(func() error {
|
||||
slog.Info("Starting Caddyfile controller.")
|
||||
slog.Info("Starting Caddyconfig controller.")
|
||||
if err := nc.caddyfileCtrl.Run(ctx); err != nil {
|
||||
//goland:noinspection GoErrorStringFormat
|
||||
return fmt.Errorf("Caddyfile controller failed: %w", err)
|
||||
return fmt.Errorf("Caddyconfig controller failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
+11
-4
@@ -30,8 +30,10 @@ const (
|
||||
PullPolicyNever = "never"
|
||||
)
|
||||
|
||||
var serviceIDRegexp = regexp.MustCompile("^[0-9a-f]{32}$")
|
||||
var dnsLabelRegexp = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`)
|
||||
var (
|
||||
serviceIDRegexp = regexp.MustCompile("^[0-9a-f]{32}$")
|
||||
dnsLabelRegexp = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`)
|
||||
)
|
||||
|
||||
func ValidateServiceID(id string) bool {
|
||||
return serviceIDRegexp.MatchString(id)
|
||||
@@ -104,7 +106,7 @@ func (s *ServiceSpec) Validate() error {
|
||||
default:
|
||||
return fmt.Errorf("invalid mode: %q", s.Mode)
|
||||
}
|
||||
|
||||
|
||||
if s.Name != "" {
|
||||
if len(s.Name) > 63 {
|
||||
return fmt.Errorf("service name too long (max 63 characters): %q", s.Name)
|
||||
@@ -146,7 +148,6 @@ func (s *ServiceSpec) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (s *ServiceSpec) Clone() ServiceSpec {
|
||||
spec := *s
|
||||
|
||||
@@ -200,6 +201,12 @@ type ContainerSpec struct {
|
||||
// SetDefaults returns a copy of the container spec with default values set.
|
||||
func (s *ContainerSpec) SetDefaults() ContainerSpec {
|
||||
spec := s.Clone()
|
||||
if spec.LogDriver == nil {
|
||||
spec.LogDriver = &LogDriver{
|
||||
Name: "local",
|
||||
Options: map[string]string{},
|
||||
}
|
||||
}
|
||||
if spec.PullPolicy == "" {
|
||||
spec.PullPolicy = PullPolicyMissing
|
||||
}
|
||||
|
||||
@@ -95,7 +95,10 @@ func (o *RemoveContainerOperation) Execute(ctx context.Context, cli Client) erro
|
||||
if err := cli.StopContainer(ctx, o.ServiceID, o.ContainerID, container.StopOptions{}); err != nil {
|
||||
return fmt.Errorf("stop container: %w", err)
|
||||
}
|
||||
if err := cli.RemoveContainer(ctx, o.ServiceID, o.ContainerID, container.RemoveOptions{}); err != nil {
|
||||
if err := cli.RemoveContainer(ctx, o.ServiceID, o.ContainerID, container.RemoveOptions{
|
||||
// Remove anonymous volumes created by the container.
|
||||
RemoveVolumes: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("remove container: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,10 @@ func (cli *Client) RemoveService(ctx context.Context, id string) error {
|
||||
return
|
||||
}
|
||||
|
||||
err = cli.RemoveContainer(ctx, svc.ID, mc.Container.ID, container.RemoveOptions{})
|
||||
err = cli.RemoveContainer(ctx, svc.ID, mc.Container.ID, container.RemoveOptions{
|
||||
// Remove anonymous volumes created by the container.
|
||||
RemoveVolumes: true,
|
||||
})
|
||||
if err != nil && !errors.Is(err, api.ErrNotFound) {
|
||||
errCh <- fmt.Errorf("remove container '%s': %w", mc.Container.ID, err)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ func assertContainerMatchesSpec(t *testing.T, ctr api.ServiceContainer, spec api
|
||||
assert.Equal(t, spec.Container.Init, ctr.HostConfig.Init)
|
||||
assert.True(t, strings.HasPrefix(ctr.Name, spec.Name+"-"))
|
||||
|
||||
// If LogDriver is not set, any log driver set as default in the Docker daemon config could be used.
|
||||
if spec.Container.LogDriver != nil {
|
||||
assert.Equal(t, spec.Container.LogDriver.Name, ctr.HostConfig.LogConfig.Type)
|
||||
assert.Equal(t, spec.Container.LogDriver.Options, ctr.HostConfig.LogConfig.Config)
|
||||
|
||||
@@ -38,7 +38,9 @@ func TestComposeBuild(t *testing.T) {
|
||||
nat.Port(registryInternalPort): []nat.PortBinding{
|
||||
{
|
||||
HostIP: "127.0.0.1",
|
||||
// Host port is a random available port.
|
||||
// Explicitly specify the mapped host port for the registry because if not specified,
|
||||
// 'docker push' from Docker Desktop is unable to reach the randomly mapped one for some reason.
|
||||
HostPort: "50000",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -103,9 +105,9 @@ func TestComposeBuild(t *testing.T) {
|
||||
// Remove the images after the test
|
||||
removeOptions := image.RemoveOptions{Force: true, PruneChildren: true}
|
||||
_, err := dockerCli.ImageRemove(ctx, serviceImage1, removeOptions)
|
||||
assert.NoErrorf(t, err, "failed to remove image %s on test cleanup: %w", serviceImage1, err)
|
||||
assert.NoErrorf(t, err, "failed to remove image %s on test cleanup", serviceImage1)
|
||||
_, err = dockerCli.ImageRemove(ctx, serviceImage2, removeOptions)
|
||||
assert.NoErrorf(t, err, "failed to remove image %s on test cleanup: %w", serviceImage2, err)
|
||||
assert.NoErrorf(t, err, "failed to remove image %s on test cleanup", serviceImage2)
|
||||
})
|
||||
|
||||
servicesToBuildExpected := map[string]types.ServiceConfig{
|
||||
|
||||
@@ -121,6 +121,9 @@ func TestComposeDeployment(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, volumes, 2, "Expected 2 volumes to be created")
|
||||
// Check that the volumes have the correct labels
|
||||
assert.Equal(t, map[string]string{"uncloud.managed": ""}, volumes[0].Volume.Labels)
|
||||
assert.Equal(t, map[string]string{"uncloud.managed": ""}, volumes[1].Volume.Labels)
|
||||
|
||||
data1Volume, data2Volume := volumes[0], volumes[1]
|
||||
if volumes[0].Volume.Name == "test-compose-volumes-data2" {
|
||||
|
||||
Reference in New Issue
Block a user