mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
feat: add --ulimit flag for 'uc run' command
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
dockeropts "github.com/docker/cli/opts"
|
dockeropts "github.com/docker/cli/opts"
|
||||||
"github.com/docker/compose/v2/pkg/progress"
|
"github.com/docker/compose/v2/pkg/progress"
|
||||||
"github.com/docker/docker/daemon/names"
|
"github.com/docker/docker/daemon/names"
|
||||||
|
"github.com/docker/go-units"
|
||||||
"github.com/psviderski/uncloud/internal/cli"
|
"github.com/psviderski/uncloud/internal/cli"
|
||||||
"github.com/psviderski/uncloud/internal/secret"
|
"github.com/psviderski/uncloud/internal/secret"
|
||||||
"github.com/psviderski/uncloud/pkg/api"
|
"github.com/psviderski/uncloud/pkg/api"
|
||||||
@@ -32,6 +33,7 @@ type runOptions struct {
|
|||||||
publish []string
|
publish []string
|
||||||
pull string
|
pull string
|
||||||
replicas uint
|
replicas uint
|
||||||
|
ulimits []string
|
||||||
user string
|
user string
|
||||||
volumes []string
|
volumes []string
|
||||||
}
|
}
|
||||||
@@ -102,6 +104,12 @@ func NewRunCommand(groupID string) *cobra.Command {
|
|||||||
cmd.Flags().StringVarP(&opts.user, "user", "u", "",
|
cmd.Flags().StringVarP(&opts.user, "user", "u", "",
|
||||||
"User name or UID and optionally group name or GID used for running the command inside service containers.\n"+
|
"User name or UID and optionally group name or GID used for running the command inside service containers.\n"+
|
||||||
"Format: USER[:GROUP] or UID[:GID]. If not specified, the user is set to the default user of the image.")
|
"Format: USER[:GROUP] or UID[:GID]. If not specified, the user is set to the default user of the image.")
|
||||||
|
cmd.Flags().StringSliceVar(&opts.ulimits, "ulimit", nil,
|
||||||
|
"Set resource limits for service containers. Can be specified multiple times.\n"+
|
||||||
|
"Format: type=soft_limit[:hard_limit]. If hard limit is not specified, soft limit is used for both.\n"+
|
||||||
|
"Examples:\n"+
|
||||||
|
" --ulimit nofile=1024:2048 Set soft limit to 1024 and hard limit to 2048 for number of open files\n"+
|
||||||
|
" --ulimit nproc=65535 Set both soft and hard limits to 65535 for number of processes")
|
||||||
cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil,
|
cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil,
|
||||||
"Mount a data volume or host path into service containers. Service containers will be scheduled on the machine(s) where\n"+
|
"Mount a data volume or host path into service containers. Service containers will be scheduled on the machine(s) where\n"+
|
||||||
"the volume is located. Can be specified multiple times.\n"+
|
"the volume is located. Can be specified multiple times.\n"+
|
||||||
@@ -194,13 +202,18 @@ func prepareServiceSpec(opts runOptions) (api.ServiceSpec, error) {
|
|||||||
ports[i] = port
|
ports[i] = port
|
||||||
}
|
}
|
||||||
|
|
||||||
volumes, mounts, err := parseVolumeFlags(opts.volumes)
|
placement := api.Placement{
|
||||||
|
Machines: cli.ExpandCommaSeparatedValues(opts.machines),
|
||||||
|
}
|
||||||
|
|
||||||
|
ulimits, err := parseUlimits(opts.ulimits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return spec, err
|
return spec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
placement := api.Placement{
|
volumes, mounts, err := parseVolumeFlags(opts.volumes)
|
||||||
Machines: cli.ExpandCommaSeparatedValues(opts.machines),
|
if err != nil {
|
||||||
|
return spec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
spec = api.ServiceSpec{
|
spec = api.ServiceSpec{
|
||||||
@@ -211,8 +224,9 @@ func prepareServiceSpec(opts runOptions) (api.ServiceSpec, error) {
|
|||||||
Privileged: opts.privileged,
|
Privileged: opts.privileged,
|
||||||
PullPolicy: opts.pull,
|
PullPolicy: opts.pull,
|
||||||
Resources: api.ContainerResources{
|
Resources: api.ContainerResources{
|
||||||
CPU: opts.cpu.Value(),
|
CPU: opts.cpu.Value(),
|
||||||
Memory: opts.memory.Value(),
|
Memory: opts.memory.Value(),
|
||||||
|
Ulimits: ulimits,
|
||||||
},
|
},
|
||||||
User: opts.user,
|
User: opts.user,
|
||||||
VolumeMounts: mounts,
|
VolumeMounts: mounts,
|
||||||
@@ -302,6 +316,24 @@ func parseVolumeFlags(volumes []string) ([]api.VolumeSpec, []api.VolumeMount, er
|
|||||||
return specs, mounts, nil
|
return specs, mounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseUlimits parses ulimit flag values in Docker CLI format (type=soft[:hard]).
|
||||||
|
func parseUlimits(ulimits []string) (map[string]api.Ulimit, error) {
|
||||||
|
if len(ulimits) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make(map[string]api.Ulimit, len(ulimits))
|
||||||
|
for _, u := range ulimits {
|
||||||
|
parsed, err := units.ParseUlimit(u)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid ulimit '%s': %w", u, err)
|
||||||
|
}
|
||||||
|
result[parsed.Name] = api.Ulimit{Soft: parsed.Soft, Hard: parsed.Hard}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseVolumeFlagValue(volume string) (api.VolumeSpec, api.VolumeMount, error) {
|
func parseVolumeFlagValue(volume string) (api.VolumeSpec, api.VolumeMount, error) {
|
||||||
var spec api.VolumeSpec
|
var spec api.VolumeSpec
|
||||||
var mount api.VolumeMount
|
var mount api.VolumeMount
|
||||||
|
|||||||
Reference in New Issue
Block a user