Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.
5 changes: 5 additions & 0 deletions cmd/common/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ var ValidateNonEmptyOpt = func(inp *textinput.TextInput) *textinput.TextInput {
return inp
}

var ValidateAbsPathOpt = func(inp *textinput.TextInput) *textinput.TextInput {
inp.Validate = ValidateAbsolutePath
return inp
}

var ValidateEmailOpt = func(inp *textinput.TextInput) *textinput.TextInput {
inp.Validate = ValidateEmail
return inp
Expand Down
7 changes: 7 additions & 0 deletions cmd/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math"
"net/mail"
"net/url"
"path"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -74,6 +75,12 @@ var ValidateURL = func(input string) error {
return err
}

var ValidateAbsolutePath = func(input string) error {
if abs := path.IsAbs(input); !abs {
return errors.InvalidArgumentErrorf("must be an absolute path")
}
return nil
}
var ValidateImage = func(input string) error {
_, err := reference.ParseDockerRef(input)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/rig/cmd/capsule/get_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func GetResources(ctx context.Context, cmd *cobra.Command, capsuleID CapsuleID,
t.AppendRows([]table.Row{
{"CPU", milliIntToString(uint64(requests.Cpu)), milliIntToString(uint64(limits.Cpu))},
{"Memory", intToByteString(requests.Memory), intToByteString(limits.Memory)},
{"Ephemeral Storage", intToByteString(requests.EphemeralStorage), intToByteString(limits.EphemeralStorage)},
})
cmd.Println(t.Render())

Expand Down
37 changes: 27 additions & 10 deletions cmd/rig/cmd/capsule/set_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
)

var (
requestCPU string
requestMemory string
limitCPU string
limitMemory string
requestCPU string
requestMemory string
requestEphemeral string
limitCPU string
limitMemory string
limitEphemeral string
)

func setupSetResources(parent *cobra.Command) {
Expand All @@ -31,9 +33,11 @@ func setupSetResources(parent *cobra.Command) {

setResources.Flags().StringVar(&requestCPU, "request-cpu", "", "Minimum CPU cores per container")
setResources.Flags().StringVar(&requestMemory, "request-memory", "", "Minimum memory per container")
setResources.Flags().StringVar(&requestEphemeral, "request-ephemeral", "", "Minimum ephemeral storage per container")

setResources.Flags().StringVar(&limitCPU, "limit-cpu", "", "Maximum CPU cores per container")
setResources.Flags().StringVar(&limitMemory, "limit-memory", "", "Maximum memory per container")
setResources.Flags().StringVar(&limitEphemeral, "limit-ephemeral", "", "Maximum ephemeral storage per container")

parent.AddCommand(setResources)
}
Expand Down Expand Up @@ -98,8 +102,9 @@ func setResourcesInteractive(curResources *capsule.Resources) error {

var cpu string
var mem string
var ephemeral string
for {
i, _, err := common.PromptSelect(fmt.Sprintf("Which resource %s to update", name), []string{"CPU", "Memory", "Done"})
i, _, err := common.PromptSelect(fmt.Sprintf("Which resource %s to update", name), []string{"CPU", "Memory", "Ephemeral Storage", "Done"})
if err != nil {
return err
}
Expand All @@ -116,6 +121,10 @@ func setResourcesInteractive(curResources *capsule.Resources) error {
name = "memory"
current = intToByteString(curR.Memory)
resourceString = &mem
case 2:
name = "ephemeral storage"
current = intToByteString(curR.EphemeralStorage)
resourceString = &ephemeral
default:
done = true
}
Expand All @@ -129,7 +138,7 @@ func setResourcesInteractive(curResources *capsule.Resources) error {
return err
}
}
if err := updateResources(curR, cpu, mem); err != nil {
if err := updateResources(curR, cpu, mem, ephemeral); err != nil {
return err
}
}
Expand All @@ -146,18 +155,18 @@ func intToByteString(i uint64) string {
}

func setResourcesFromFlags(curResources *capsule.Resources) error {
if err := updateResources(curResources.Requests, requestCPU, requestMemory); err != nil {
if err := updateResources(curResources.Requests, requestCPU, requestMemory, requestEphemeral); err != nil {
return err
}

if err := updateResources(curResources.Limits, limitCPU, limitMemory); err != nil {
if err := updateResources(curResources.Limits, limitCPU, limitMemory, limitEphemeral); err != nil {
return err
}

return nil
}

func updateResources(resources *capsule.ResourceList, cpu, mem string) error {
func updateResources(resources *capsule.ResourceList, cpu, mem, ephemeral string) error {
if cpu != "" {
milliCPU, err := parseMilli(cpu)
if err != nil {
Expand All @@ -174,6 +183,14 @@ func updateResources(resources *capsule.ResourceList, cpu, mem string) error {
resources.Memory = mem
}

if ephemeral != "" {
storage, err := parseBytes(ephemeral)
if err != nil {
return nil
}
resources.EphemeralStorage = storage
}

return nil
}

Expand All @@ -200,6 +217,6 @@ func parseBytes(s string) (uint64, error) {
}

func allFlagsEmpty() bool {
return requestCPU == "" && requestMemory == "" && limitCPU == "" && limitMemory == ""
return requestCPU == "" && requestMemory == "" && requestEphemeral == "" && limitCPU == "" && limitMemory == "" && limitEphemeral == ""

}
7 changes: 4 additions & 3 deletions internal/client/docker/capsule.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ func (c *Client) UpsertCapsule(ctx context.Context, capsuleName string, cc *clus
dcc.Env = append(dcc.Env, fmt.Sprint(k, "=", v))
}

limits := cc.ContainerSettings.Resources.Limits
limits := cc.ContainerSettings.GetResources().GetLimits()
dhc := &container.HostConfig{
NetworkMode: container.NetworkMode(netID),
PortBindings: nat.PortMap{},
RestartPolicy: container.RestartPolicy{
Name: "always",
},
Resources: container.Resources{
Memory: int64(limits.Memory),
NanoCPUs: int64(limits.Cpu * 1_000_000),
Memory: int64(limits.GetMemory()),
NanoCPUs: int64(limits.GetCpu() * 1_000_000),
},
}

Expand Down Expand Up @@ -155,6 +155,7 @@ func (c *Client) UpsertCapsule(ctx context.Context, capsuleName string, cc *clus
dcc,
dhc,
dnc,
cc.ConfigFiles,
)
if err != nil {
return err
Expand Down
73 changes: 72 additions & 1 deletion internal/client/docker/client.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package docker

import (
"archive/tar"
"bufio"
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"io/fs"
"path"
"strings"
"time"

Expand Down Expand Up @@ -112,7 +116,68 @@ func (w *logsWriter) Write(bs []byte) (int, error) {
return len(bs), nil
}

func (c *Client) createAndStartContainer(ctx context.Context, containerID string, cc *container.Config, hc *container.HostConfig, nc *network.NetworkingConfig) error {
type fileInfo struct {
name string
size int64
}

func (info *fileInfo) Name() string {
return info.name
}

func (info *fileInfo) Size() int64 {
return info.size
}

func (info *fileInfo) IsDir() bool {
return false
}

func (info *fileInfo) Mode() fs.FileMode {
return 0o644
}

func (info *fileInfo) ModTime() time.Time {
return time.Now()
}

func (info *fileInfo) Sys() any {
return nil
}

func (c *Client) copyFileToContainer(ctx context.Context, containerID string, file *capsule.ConfigFile) error {
var buffer bytes.Buffer

tw := tar.NewWriter(&buffer)
defer tw.Close()

dir := path.Dir(file.GetPath())
subPath := path.Base(file.GetPath())

header, err := tar.FileInfoHeader(&fileInfo{
name: subPath,
size: int64(len(file.GetContent())),
}, "")
if err != nil {
return err
}

if err := tw.WriteHeader(header); err != nil {
return err
}

if _, err := tw.Write(file.GetContent()); err != nil {
return err
}

if err := tw.Close(); err != nil {
return err
}

return c.dc.CopyToContainer(ctx, containerID, dir, bufio.NewReader(&buffer), types.CopyToContainerOptions{})
}

func (c *Client) createAndStartContainer(ctx context.Context, containerID string, cc *container.Config, hc *container.HostConfig, nc *network.NetworkingConfig, configFiles []*capsule.ConfigFile) error {
id, err := c.lookupContainer(ctx, containerID)
if errors.IsNotFound(err) {
// Already ready to create.
Expand All @@ -130,6 +195,12 @@ func (c *Client) createAndStartContainer(ctx context.Context, containerID string
return err
}

for _, f := range configFiles {
if err := c.copyFileToContainer(ctx, containerID, f); err != nil {
return err
}
}

if err := c.dc.ContainerStart(ctx, containerID, types.ContainerStartOptions{}); err != nil {
c.logger.Info("error starting container", zap.Error(err), zap.String("instance_id", containerID))
}
Expand Down
2 changes: 1 addition & 1 deletion internal/client/docker/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (c *Client) upsertService(ctx context.Context, capsuleName string, pc *prox
}}
}

if err := c.createAndStartContainer(ctx, containerID, cc, hc, nc); err != nil {
if err := c.createAndStartContainer(ctx, containerID, cc, hc, nc, nil); err != nil {
return err
}

Expand Down
13 changes: 13 additions & 0 deletions internal/client/k8s/delete_capsule.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,19 @@ func (c *Client) deleteEnvSecret(ctx context.Context, capsuleName, ns string) er
return nil
}

func (c *Client) deleteConfigMap(ctx context.Context, capsuleName, ns string) error {
err := c.cs.CoreV1().
ConfigMaps(ns).
Delete(ctx, capsuleName, metav1.DeleteOptions{})
if err != nil {
if kerrors.IsNotFound(err) {
return nil
}
return fmt.Errorf("could not delete ConfigMap: %w", err)
}
return nil
}

func (c *Client) deleteDeployment(ctx context.Context, capsuleName, ns string) error {
err := c.cs.AppsV1().
Deployments(ns).
Expand Down
Loading