mirror of
https://github.com/sablierapp/sablier.git
synced 2026-01-03 03:27:28 +01:00
feat(docker): add docker pause strategy (#755)
* add tmp test * add strategy config * strategy config * pause / unpause strategy impl * Fix tests * fix compilation * add pause / unpause tests * add doc * add config test * start if not paused * remove test files
This commit is contained in:
1
.tool-versions
Normal file
1
.tool-versions
Normal file
@@ -0,0 +1 @@
|
||||
golang 1.25.4
|
||||
@@ -28,7 +28,10 @@ sablier --configFile=path/to/myconfigfile.yml
|
||||
```yaml
|
||||
provider:
|
||||
# Provider to use to manage containers (docker, swarm, kubernetes)
|
||||
name: docker
|
||||
name: docker
|
||||
docker:
|
||||
# Strategy to use for stopping Docker containers: stop or pause (default: stop)
|
||||
strategy: stop
|
||||
server:
|
||||
# The server port to use
|
||||
port: 10000
|
||||
@@ -113,6 +116,7 @@ sablier start --strategy.dynamic.custom-themes-path /my/path
|
||||
|
||||
```
|
||||
-h, --help help for start
|
||||
--provider.docker.strategy string Strategy to use to stop docker containers (stop or pause) (default "stop")
|
||||
--provider.name string Provider to use to manage containers [docker swarm kubernetes] (default "docker")
|
||||
--server.base-path string The base path for the API (default "/")
|
||||
--server.port int The server port to use (default 10000)
|
||||
|
||||
@@ -59,6 +59,66 @@ services:
|
||||
- sablier.group=mygroup
|
||||
```
|
||||
|
||||
## Strategies
|
||||
|
||||
The Docker provider supports two strategies for managing containers:
|
||||
|
||||
### Stop Strategy (default)
|
||||
|
||||
The `stop` strategy completely stops containers when they become idle and starts them again when needed.
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### **File (YAML)**
|
||||
|
||||
```yaml
|
||||
provider:
|
||||
docker:
|
||||
strategy: stop
|
||||
```
|
||||
|
||||
#### **CLI**
|
||||
|
||||
```bash
|
||||
sablier start --provider.docker.strategy=stop
|
||||
```
|
||||
|
||||
#### **Environment Variable**
|
||||
|
||||
```bash
|
||||
PROVIDER_DOCKER_STRATEGY=stop
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
### Pause Strategy
|
||||
|
||||
The `pause` strategy pauses containers instead of stopping them. This is faster than stop/start as the container state remains in memory, but uses more system resources.
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### **File (YAML)**
|
||||
|
||||
```yaml
|
||||
provider:
|
||||
docker:
|
||||
strategy: pause
|
||||
```
|
||||
|
||||
#### **CLI**
|
||||
|
||||
```bash
|
||||
sablier start --provider.docker.strategy=pause
|
||||
```
|
||||
|
||||
#### **Environment Variable**
|
||||
|
||||
```bash
|
||||
PROVIDER_DOCKER_STRATEGY=pause
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
## How does Sablier knows when a container is ready?
|
||||
|
||||
If the container defines a Healthcheck, then it will check for healthiness before stating the `ready` status.
|
||||
|
||||
@@ -12,6 +12,7 @@ type Provider struct {
|
||||
AutoStopOnStartup bool `yaml:"auto-stop-on-startup,omitempty" default:"true"`
|
||||
Kubernetes Kubernetes
|
||||
Podman Podman
|
||||
Docker Docker
|
||||
}
|
||||
|
||||
type Kubernetes struct {
|
||||
@@ -34,7 +35,12 @@ type Podman struct {
|
||||
Uri string `mapstructure:"URI" yaml:"uri,omitempty" default:"unix:///run/podman/podman.sock"`
|
||||
}
|
||||
|
||||
type Docker struct {
|
||||
Strategy string `mapstructure:"STRATEGY" yaml:"strategy,omitempty" default:"stop"`
|
||||
}
|
||||
|
||||
var providers = []string{"docker", "docker_swarm", "swarm", "kubernetes", "podman"}
|
||||
var dockerStrategies = []string{"stop", "pause"}
|
||||
|
||||
func NewProviderConfig() Provider {
|
||||
return Provider{
|
||||
@@ -48,18 +54,36 @@ func NewProviderConfig() Provider {
|
||||
Podman: Podman{
|
||||
Uri: "unix:///run/podman/podman.sock",
|
||||
},
|
||||
Docker: Docker{
|
||||
Strategy: "stop",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (provider Provider) IsValid() error {
|
||||
for _, p := range providers {
|
||||
if p == provider.Name {
|
||||
// Validate Docker-specific settings when using Docker provider
|
||||
if p == "docker" {
|
||||
if err := provider.Docker.IsValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("unrecognized provider %s. providers available: %v", provider.Name, providers)
|
||||
}
|
||||
|
||||
func (docker Docker) IsValid() error {
|
||||
for _, s := range dockerStrategies {
|
||||
if s == docker.Strategy {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("unrecognized docker strategy %s. strategies available: %v", docker.Strategy, dockerStrategies)
|
||||
}
|
||||
|
||||
func GetProviders() []string {
|
||||
return providers
|
||||
}
|
||||
|
||||
141
pkg/config/provider_test.go
Normal file
141
pkg/config/provider_test.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestProvider_IsValid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
provider Provider
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "valid docker provider with stop strategy",
|
||||
provider: Provider{
|
||||
Name: "docker",
|
||||
Docker: Docker{
|
||||
Strategy: "stop",
|
||||
},
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "valid docker provider with pause strategy",
|
||||
provider: Provider{
|
||||
Name: "docker",
|
||||
Docker: Docker{
|
||||
Strategy: "pause",
|
||||
},
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid docker strategy",
|
||||
provider: Provider{
|
||||
Name: "docker",
|
||||
Docker: Docker{
|
||||
Strategy: "invalid",
|
||||
},
|
||||
},
|
||||
wantErr: fmt.Errorf("unrecognized docker strategy invalid. strategies available: [stop pause]"),
|
||||
},
|
||||
{
|
||||
name: "valid kubernetes provider",
|
||||
provider: Provider{
|
||||
Name: "kubernetes",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "valid swarm provider",
|
||||
provider: Provider{
|
||||
Name: "swarm",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "valid docker_swarm provider",
|
||||
provider: Provider{
|
||||
Name: "docker_swarm",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "valid podman provider",
|
||||
provider: Provider{
|
||||
Name: "podman",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid provider name",
|
||||
provider: Provider{
|
||||
Name: "invalid",
|
||||
},
|
||||
wantErr: fmt.Errorf("unrecognized provider invalid. providers available: [docker docker_swarm swarm kubernetes podman]"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.provider.IsValid()
|
||||
if tt.wantErr != nil {
|
||||
assert.Error(t, err, tt.wantErr.Error())
|
||||
} else {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocker_IsValid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
docker Docker
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "valid stop strategy",
|
||||
docker: Docker{
|
||||
Strategy: "stop",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "valid pause strategy",
|
||||
docker: Docker{
|
||||
Strategy: "pause",
|
||||
},
|
||||
wantErr: nil,
|
||||
},
|
||||
{
|
||||
name: "invalid strategy",
|
||||
docker: Docker{
|
||||
Strategy: "restart",
|
||||
},
|
||||
wantErr: fmt.Errorf("unrecognized docker strategy restart. strategies available: [stop pause]"),
|
||||
},
|
||||
{
|
||||
name: "empty strategy",
|
||||
docker: Docker{
|
||||
Strategy: "",
|
||||
},
|
||||
wantErr: fmt.Errorf("unrecognized docker strategy . strategies available: [stop pause]"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.docker.IsValid()
|
||||
if tt.wantErr != nil {
|
||||
assert.Error(t, err, tt.wantErr.Error())
|
||||
} else {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func TestDockerClassicProvider_GetState(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
name, err := tt.args.do(c)
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package docker_test
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/slogt"
|
||||
"github.com/sablierapp/sablier/pkg/provider"
|
||||
"github.com/sablierapp/sablier/pkg/provider/docker"
|
||||
"github.com/sablierapp/sablier/pkg/sablier"
|
||||
"gotest.tools/v3/assert"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDockerClassicProvider_InstanceList(t *testing.T) {
|
||||
@@ -18,7 +19,7 @@ func TestDockerClassicProvider_InstanceList(t *testing.T) {
|
||||
|
||||
ctx := t.Context()
|
||||
dind := setupDinD(t)
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
c1, err := dind.CreateMimic(ctx, MimicOptions{
|
||||
@@ -77,7 +78,7 @@ func TestDockerClassicProvider_GetGroups(t *testing.T) {
|
||||
|
||||
ctx := t.Context()
|
||||
dind := setupDinD(t)
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
c1, err := dind.CreateMimic(ctx, MimicOptions{
|
||||
|
||||
@@ -9,6 +9,13 @@ import (
|
||||
)
|
||||
|
||||
func (p *Provider) InstanceStart(ctx context.Context, name string) error {
|
||||
if p.strategy == "pause" {
|
||||
return p.dockerUnpause(ctx, name)
|
||||
}
|
||||
return p.dockerStart(ctx, name)
|
||||
}
|
||||
|
||||
func (p *Provider) dockerStart(ctx context.Context, name string) error {
|
||||
// TODO: InstanceStart should block until the container is ready.
|
||||
p.l.DebugContext(ctx, "starting container", "name", name)
|
||||
err := p.Client.ContainerStart(ctx, name, container.StartOptions{})
|
||||
@@ -18,3 +25,26 @@ func (p *Provider) InstanceStart(ctx context.Context, name string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) dockerUnpause(ctx context.Context, name string) error {
|
||||
container, inspectErr := p.Client.ContainerInspect(ctx, name)
|
||||
if inspectErr != nil {
|
||||
p.l.ErrorContext(ctx, "cannot inspect container before unpausing", slog.String("name", name), slog.Any("error", inspectErr))
|
||||
return fmt.Errorf("cannot inspect container %s before unpausing: %w", name, inspectErr)
|
||||
}
|
||||
|
||||
if !container.State.Paused {
|
||||
p.l.DebugContext(ctx, "container is not paused, starting container", slog.String("name", name))
|
||||
return p.dockerStart(ctx, name)
|
||||
}
|
||||
|
||||
p.l.DebugContext(ctx, "unpausing container", slog.String("name", name))
|
||||
err := p.Client.ContainerUnpause(ctx, name)
|
||||
if err != nil {
|
||||
p.l.ErrorContext(ctx, "cannot unpause container", slog.String("name", name), slog.Any("error", err))
|
||||
return fmt.Errorf("cannot unpause container %s: %w", name, err)
|
||||
}
|
||||
|
||||
p.l.DebugContext(ctx, "container unpaused", slog.String("name", name))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ package docker_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/neilotoole/slogt"
|
||||
"github.com/sablierapp/sablier/pkg/provider/docker"
|
||||
"gotest.tools/v3/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDockerClassicProvider_Start(t *testing.T) {
|
||||
@@ -47,7 +49,99 @@ func TestDockerClassicProvider_Start(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
name, err := tt.args.do(c)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = p.InstanceStart(t.Context(), name)
|
||||
if tt.err != nil {
|
||||
assert.Error(t, err, tt.err.Error())
|
||||
} else {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerClassicProvider_Unpause(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode.")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
type args struct {
|
||||
do func(dind *dindContainer) (string, error)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "non existing container unpause",
|
||||
args: args{
|
||||
do: func(dind *dindContainer) (string, error) {
|
||||
return "non-existent", nil
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("cannot inspect container non-existent before unpausing: Error response from daemon: No such container: non-existent"),
|
||||
},
|
||||
{
|
||||
name: "container starts because was not paused",
|
||||
args: args{
|
||||
do: func(dind *dindContainer) (string, error) {
|
||||
c, err := dind.CreateMimic(ctx, MimicOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = dind.client.ContainerStop(ctx, c.ID, container.StopOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return c.ID, nil
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "container unpause as expected",
|
||||
args: args{
|
||||
do: func(dind *dindContainer) (string, error) {
|
||||
c, err := dind.CreateMimic(ctx, MimicOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = dind.client.ContainerPause(ctx, c.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return c.ID, nil
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
c := setupDinD(t)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t), "pause")
|
||||
assert.NilError(t, err)
|
||||
|
||||
name, err := tt.args.do(c)
|
||||
|
||||
@@ -9,6 +9,13 @@ import (
|
||||
)
|
||||
|
||||
func (p *Provider) InstanceStop(ctx context.Context, name string) error {
|
||||
if p.strategy == "pause" {
|
||||
return p.dockerPause(ctx, name)
|
||||
}
|
||||
return p.dockerStop(ctx, name)
|
||||
}
|
||||
|
||||
func (p *Provider) dockerStop(ctx context.Context, name string) error {
|
||||
p.l.DebugContext(ctx, "stopping container", slog.String("name", name))
|
||||
err := p.Client.ContainerStop(ctx, name, container.StopOptions{})
|
||||
if err != nil {
|
||||
@@ -30,3 +37,15 @@ func (p *Provider) InstanceStop(ctx context.Context, name string) error {
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) dockerPause(ctx context.Context, name string) error {
|
||||
p.l.DebugContext(ctx, "pausing container", slog.String("name", name))
|
||||
err := p.Client.ContainerPause(ctx, name)
|
||||
if err != nil {
|
||||
p.l.ErrorContext(ctx, "cannot pause container", slog.String("name", name), slog.Any("error", err))
|
||||
return fmt.Errorf("cannot pause container %s: %w", name, err)
|
||||
}
|
||||
|
||||
p.l.DebugContext(ctx, "container paused", slog.String("name", name))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -58,7 +58,70 @@ func TestDockerClassicProvider_Stop(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
name, err := tt.args.do(c)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = p.InstanceStop(t.Context(), name)
|
||||
if tt.err != nil {
|
||||
assert.Error(t, err, tt.err.Error())
|
||||
} else {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerClassicProvider_Pause(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode.")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
type args struct {
|
||||
do func(dind *dindContainer) (string, error)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "non existing container pause",
|
||||
args: args{
|
||||
do: func(dind *dindContainer) (string, error) {
|
||||
return "non-existent", nil
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("cannot pause container non-existent: Error response from daemon: No such container: non-existent"),
|
||||
},
|
||||
{
|
||||
name: "container pause as expected",
|
||||
args: args{
|
||||
do: func(dind *dindContainer) (string, error) {
|
||||
c, err := dind.CreateMimic(ctx, MimicOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = dind.client.ContainerStart(ctx, c.ID, container.StartOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return c.ID, nil
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
c := setupDinD(t)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
p, err := docker.New(ctx, c.client, slogt.New(t), "pause")
|
||||
assert.NilError(t, err)
|
||||
|
||||
name, err := tt.args.do(c)
|
||||
|
||||
@@ -3,9 +3,10 @@ package docker
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/sablierapp/sablier/pkg/sablier"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
// Interface guard
|
||||
@@ -15,10 +16,11 @@ type Provider struct {
|
||||
Client client.APIClient
|
||||
desiredReplicas int32
|
||||
l *slog.Logger
|
||||
strategy string
|
||||
}
|
||||
|
||||
func New(ctx context.Context, cli *client.Client, logger *slog.Logger) (*Provider, error) {
|
||||
logger = logger.With(slog.String("provider", "docker"))
|
||||
func New(ctx context.Context, cli *client.Client, logger *slog.Logger, strategy string) (*Provider, error) {
|
||||
logger = logger.With(slog.String("provider", "docker"), slog.String("strategy", strategy))
|
||||
|
||||
serverVersion, err := cli.ServerVersion(ctx)
|
||||
if err != nil {
|
||||
@@ -33,5 +35,6 @@ func New(ctx context.Context, cli *client.Client, logger *slog.Logger) (*Provide
|
||||
Client: cli,
|
||||
desiredReplicas: 1,
|
||||
l: logger,
|
||||
strategy: strategy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ package docker_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/neilotoole/slogt"
|
||||
"github.com/sablierapp/sablier/pkg/provider/docker"
|
||||
"gotest.tools/v3/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDockerClassicProvider_NotifyInstanceStopped(t *testing.T) {
|
||||
@@ -18,7 +19,7 @@ func TestDockerClassicProvider_NotifyInstanceStopped(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
dind := setupDinD(t)
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t))
|
||||
p, err := docker.New(ctx, dind.client, slogt.New(t), "stop")
|
||||
assert.NilError(t, err)
|
||||
|
||||
c, err := dind.CreateMimic(ctx, MimicOptions{})
|
||||
|
||||
@@ -111,6 +111,7 @@ func TestPrecedence(t *testing.T) {
|
||||
"--provider.kubernetes.burst", "512",
|
||||
"--provider.kubernetes.delimiter", "_",
|
||||
"--provider.podman.uri", "unix:///run/podman/podman.sock.cli",
|
||||
"--provider.docker.strategy", "pause",
|
||||
"--server.port", "3333",
|
||||
"--server.base-path", "/cli/",
|
||||
"--storage.file", "/tmp/cli.json",
|
||||
|
||||
@@ -34,7 +34,7 @@ func setupProvider(ctx context.Context, logger *slog.Logger, config config.Provi
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot create docker client: %v", err)
|
||||
}
|
||||
return docker.New(ctx, cli, logger)
|
||||
return docker.New(ctx, cli, logger, config.Docker.Strategy)
|
||||
case "kubernetes":
|
||||
kubeclientConfig, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
|
||||
@@ -50,6 +50,8 @@ It provides integrations with multiple reverse proxies and different loading str
|
||||
_ = viper.BindPFlag("provider.kubernetes.delimiter", startCmd.Flags().Lookup("provider.kubernetes.delimiter"))
|
||||
startCmd.Flags().StringVar(&conf.Provider.Podman.Uri, "provider.podman.uri", "unix:///run/podman/podman.sock", "Uri is the URI to connect to the Podman service.")
|
||||
_ = viper.BindPFlag("provider.podman.uri", startCmd.Flags().Lookup("provider.podman.uri"))
|
||||
startCmd.Flags().StringVar(&conf.Provider.Docker.Strategy, "provider.docker.strategy", "stop", "Strategy to use to stop docker containers (stop or pause)")
|
||||
_ = viper.BindPFlag("provider.docker.strategy", startCmd.Flags().Lookup("provider.docker.strategy"))
|
||||
|
||||
// Server flags
|
||||
startCmd.Flags().IntVar(&conf.Server.Port, "server.port", 10000, "The server port to use")
|
||||
|
||||
1
pkg/sabliercmd/testdata/config.env
vendored
1
pkg/sabliercmd/testdata/config.env
vendored
@@ -4,6 +4,7 @@ PROVIDER_KUBERNETES_QPS=16
|
||||
PROVIDER_KUBERNETES_BURST=32
|
||||
PROVIDER_KUBERNETES_DELIMITER=/
|
||||
PROVIDER_PODMAN_URI=unix:///run/podman/podman.sock.env
|
||||
PROVIDER_DOCKER_STRATEGY=pause
|
||||
SERVER_PORT=2222
|
||||
SERVER_BASE_PATH=/envvar/
|
||||
STORAGE_FILE=/tmp/envvar.json
|
||||
|
||||
2
pkg/sabliercmd/testdata/config.yml
vendored
2
pkg/sabliercmd/testdata/config.yml
vendored
@@ -7,6 +7,8 @@ provider:
|
||||
delimiter: .
|
||||
podman:
|
||||
uri: unix:///run/podman/podman.sock.yml
|
||||
docker:
|
||||
strategy: pause
|
||||
server:
|
||||
port: 1111
|
||||
base-path: /configfile/
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
},
|
||||
"Podman": {
|
||||
"Uri": "unix:///run/podman/podman.sock.cli"
|
||||
},
|
||||
"Docker": {
|
||||
"Strategy": "pause"
|
||||
}
|
||||
},
|
||||
"Sessions": {
|
||||
|
||||
3
pkg/sabliercmd/testdata/config_default.json
vendored
3
pkg/sabliercmd/testdata/config_default.json
vendored
@@ -16,6 +16,9 @@
|
||||
},
|
||||
"Podman": {
|
||||
"Uri": "unix:///run/podman/podman.sock"
|
||||
},
|
||||
"Docker": {
|
||||
"Strategy": "stop"
|
||||
}
|
||||
},
|
||||
"Sessions": {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
},
|
||||
"Podman": {
|
||||
"Uri": "unix:///run/podman/podman.sock.env"
|
||||
},
|
||||
"Docker": {
|
||||
"Strategy": "pause"
|
||||
}
|
||||
},
|
||||
"Sessions": {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
},
|
||||
"Podman": {
|
||||
"Uri": "unix:///run/podman/podman.sock.yml"
|
||||
},
|
||||
"Docker": {
|
||||
"Strategy": "pause"
|
||||
}
|
||||
},
|
||||
"Sessions": {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
provider:
|
||||
name: docker
|
||||
docker:
|
||||
strategy: stop
|
||||
server:
|
||||
port: 10000
|
||||
base-path: /
|
||||
|
||||
Reference in New Issue
Block a user