diff --git a/cmd/uncloud/service/run.go b/cmd/uncloud/service/run.go index 8310267d..eb74f393 100644 --- a/cmd/uncloud/service/run.go +++ b/cmd/uncloud/service/run.go @@ -74,20 +74,34 @@ func run(ctx context.Context, uncli *cli.CLI, opts runOptions) error { return fmt.Errorf("invalid replication mode: %q", opts.mode) } - client, err := uncli.ConnectCluster(ctx, opts.cluster) - if err != nil { - return fmt.Errorf("connect to cluster: %w", err) + ports := make([]api.PortSpec, len(opts.publish)) + for i, publishPort := range opts.publish { + port, err := api.ParsePortSpec(publishPort) + if err != nil { + return fmt.Errorf("invalid service port '%s': %w", publishPort, err) + } + ports[i] = port } - defer client.Close() spec := api.ServiceSpec{ Container: api.ContainerSpec{ Command: opts.command, Image: opts.image, }, - Mode: opts.mode, - Name: opts.name, + Mode: opts.mode, + Name: opts.name, + Ports: ports, } + if err := spec.Validate(); err != nil { + return fmt.Errorf("invalid service configuration: %w", err) + } + + client, err := uncli.ConnectCluster(ctx, opts.cluster) + if err != nil { + return fmt.Errorf("connect to cluster: %w", err) + } + defer client.Close() + if _, err = client.RunService(ctx, spec); err != nil { return fmt.Errorf("run service: %w", err) } diff --git a/internal/api/port.go b/internal/api/port.go index a6e3fc68..5d23892f 100644 --- a/internal/api/port.go +++ b/internal/api/port.go @@ -41,7 +41,8 @@ func (p *PortSpec) Validate() error { switch p.Protocol { case ProtocolHTTP, ProtocolHTTPS, ProtocolTCP, ProtocolUDP: default: - return fmt.Errorf("invalid protocol: '%s'", p.Protocol) + return fmt.Errorf("invalid protocol '%s', supported protocols: '%s', '%s', '%s', '%s'", + p.Protocol, ProtocolHTTP, ProtocolHTTPS, ProtocolTCP, ProtocolUDP) } switch p.Mode { diff --git a/internal/api/service.go b/internal/api/service.go index 77e415e5..6e1a81c1 100644 --- a/internal/api/service.go +++ b/internal/api/service.go @@ -32,6 +32,8 @@ func (s *ServiceSpec) Validate() error { return fmt.Errorf("invalid mode: %q", s.Mode) } + // TODO: validate there is no conflict between ports. + return nil } diff --git a/internal/api/service_test.go b/internal/api/service_test.go index 5381ae38..d4816313 100644 --- a/internal/api/service_test.go +++ b/internal/api/service_test.go @@ -430,7 +430,7 @@ func TestPortSpec_Validate(t *testing.T) { ContainerPort: 8080, Protocol: "invalid", }, - wantErr: "invalid protocol: 'invalid'", + wantErr: "invalid protocol 'invalid'", }, { name: "invalid mode",