From c9ef4dc8c571499a33ffb09d3c9870c94a676cbb Mon Sep 17 00:00:00 2001 From: Lukas Gentele Date: Mon, 5 Nov 2018 00:05:41 +0100 Subject: [PATCH] add services (closes #345) --- cmd/enter.go | 13 ++- cmd/init.go | 25 +++-- cmd/list.go | 119 +++++++++++++++++++---- cmd/up.go | 8 +- pkg/devspace/config/configutil/get.go | 39 ++++++++ pkg/devspace/config/v1/devspace.go | 15 ++- pkg/devspace/config/v1/terminal.go | 1 + pkg/devspace/configure/package.go | 18 +++- pkg/devspace/configure/sync.go | 1 - pkg/devspace/services/port_forwarding.go | 69 +++++++------ pkg/devspace/services/sync.go | 44 ++++++--- pkg/devspace/services/terminal.go | 60 ++++++++++-- 12 files changed, 325 insertions(+), 87 deletions(-) diff --git a/cmd/enter.go b/cmd/enter.go index 25f36fa06d..14d26f158f 100644 --- a/cmd/enter.go +++ b/cmd/enter.go @@ -16,9 +16,10 @@ type EnterCmd struct { // EnterCmdFlags are the flags available for the enter-command type EnterCmdFlags struct { - container string + service string namespace string labelSelector string + container string } func init() { @@ -28,7 +29,7 @@ func init() { cobraCmd := &cobra.Command{ Use: "enter", - Short: "Enter your DevSpace", + Short: "Start a new terminal session", Long: ` ####################################################### ################## devspace enter ##################### @@ -38,7 +39,8 @@ devspace: devspace enter devspace enter bash -devspace enter -c myContainer +devspace enter -s my-service +devspace enter -c my-container devspace enter bash -n my-namespace devspace enter bash -l release=test #######################################################`, @@ -46,9 +48,10 @@ devspace enter bash -l release=test } rootCmd.AddCommand(cobraCmd) + cobraCmd.Flags().StringVarP(&cmd.flags.service, "service", "s", "", "Service name to select pod/container for terminal") cobraCmd.Flags().StringVarP(&cmd.flags.container, "container", "c", "", "Container name within pod where to execute command") - cobraCmd.Flags().StringVarP(&cmd.flags.namespace, "namespace", "n", "", "Namespace where to select pods") cobraCmd.Flags().StringVarP(&cmd.flags.labelSelector, "label-selector", "l", "", "Comma separated key=value selector list (e.g. release=test)") + cobraCmd.Flags().StringVarP(&cmd.flags.namespace, "namespace", "n", "", "Namespace where to select pods") } // Run executes the command logic @@ -61,5 +64,5 @@ func (cmd *EnterCmd) Run(cobraCmd *cobra.Command, args []string) { log.Fatalf("Unable to create new kubectl client: %v", err) } - services.StartTerminal(cmd.kubectl, cmd.flags.container, cmd.flags.labelSelector, cmd.flags.namespace, args, log.GetInstance()) + services.StartTerminal(cmd.kubectl, cmd.flags.service, cmd.flags.container, cmd.flags.labelSelector, cmd.flags.namespace, args, log.GetInstance()) } diff --git a/cmd/init.go b/cmd/init.go index 140854d772..b72136efba 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -188,6 +188,7 @@ func (cmd *InitCmd) Run(cobraCmd *cobra.Command, args []string) { cmd.configureDevSpace() } + cmd.addDefaultService() cmd.addDefaultPorts() cmd.addDefaultSyncConfig() @@ -302,6 +303,18 @@ func (cmd *InitCmd) configureDevSpace() { config.Cluster.Namespace = namespace } +func (cmd *InitCmd) addDefaultService() { + config := configutil.GetConfig() + config.DevSpace.Services = &[]*v1.ServiceConfig{ + { + Name: configutil.String(configutil.DefaultDevspaceServiceName), + LabelSelector: &map[string]*string{ + "devspace": configutil.String("default"), + }, + }, + } +} + func (cmd *InitCmd) addDefaultPorts() { dockerfilePath := filepath.Join(cmd.workdir, "Dockerfile") ports, err := dockerfile.GetPorts(dockerfilePath) @@ -324,9 +337,7 @@ func (cmd *InitCmd) addDefaultPorts() { config := configutil.GetConfig() config.DevSpace.Ports = &[]*v1.PortForwardingConfig{ { - LabelSelector: &map[string]*string{ - "release": configutil.String(configutil.DefaultDevspaceDeploymentName), - }, + Service: configutil.String(configutil.DefaultDevspaceServiceName), PortMappings: &portMappings, }, } @@ -355,11 +366,9 @@ func (cmd *InitCmd) addDefaultSyncConfig() { } syncConfig := append(*config.DevSpace.Sync, &v1.SyncConfig{ - ContainerPath: configutil.String("/app"), - LocalSubPath: configutil.String("./"), - LabelSelector: &map[string]*string{ - "release": configutil.String(configutil.DefaultDevspaceDeploymentName), - }, + Service: configutil.String(configutil.DefaultDevspaceServiceName), + ContainerPath: configutil.String("/app"), + LocalSubPath: configutil.String("./"), UploadExcludePaths: &uploadExcludePaths, }) diff --git a/cmd/list.go b/cmd/list.go index 8338385e69..281c37b5ae 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -82,7 +82,7 @@ func init() { ####################################################### ############### devspace list package ################# ####################################################### - Lists the packages that were added to the devspace + Lists the packages that were added to the DevSpace ####################################################### `, Args: cobra.NoArgs, @@ -90,6 +90,22 @@ func init() { } listCmd.AddCommand(listPackageCmd) + + listServiceCmd := &cobra.Command{ + Use: "service", + Short: "Lists all services", + Long: ` + ####################################################### + ############### devspace list service ################# + ####################################################### + Lists the service that are defined in the DevSpace + ####################################################### + `, + Args: cobra.NoArgs, + Run: cmd.RunListService, + } + + listCmd.AddCommand(listServiceCmd) } // RunListPackage runs the list sync command logic @@ -133,6 +149,64 @@ func (cmd *ListCmd) RunListPackage(cobraCmd *cobra.Command, args []string) { log.PrintTable(headerColumnNames, values) } +// RunListService runs the list service command logic +func (cmd *ListCmd) RunListService(cobraCmd *cobra.Command, args []string) { + config := configutil.GetConfig() + + if len(*config.DevSpace.Services) == 0 { + log.Write("No services are configured. Run `devspace add service` to add new service\n") + return + } + + headerColumnNames := []string{ + "Name", + "Namespace", + "Type", + "Selector", + "Container", + } + + services := make([][]string, 0, len(*config.DevSpace.Services)) + + // Transform values into string arrays + for _, value := range *config.DevSpace.Services { + selector := "" + for k, v := range *value.LabelSelector { + if len(selector) > 0 { + selector += ", " + } + + selector += k + "=" + *v + } + + resourceType := "pod" + if value.ResourceType != nil { + resourceType = *value.ResourceType + } + + // TODO: should we skip this error? + namespace, _ := configutil.GetDefaultNamespace(config) + if value.Namespace != nil { + namespace = *value.Namespace + } + + containerName := "" + if value.ContainerName != nil { + containerName = *value.ContainerName + } + + services = append(services, []string{ + *value.Name, + namespace, + resourceType, + selector, + containerName, + }) + } + + log.PrintTable(headerColumnNames, services) +} + // RunListSync runs the list sync command logic func (cmd *ListCmd) RunListSync(cobraCmd *cobra.Command, args []string) { config := configutil.GetConfig() @@ -143,7 +217,7 @@ func (cmd *ListCmd) RunListSync(cobraCmd *cobra.Command, args []string) { } headerColumnNames := []string{ - "Type", + "Service", "Selector", "Local Path", "Container Path", @@ -154,16 +228,20 @@ func (cmd *ListCmd) RunListSync(cobraCmd *cobra.Command, args []string) { // Transform values into string arrays for _, value := range *config.DevSpace.Sync { + service := "" selector := "" - for k, v := range *value.LabelSelector { - if len(selector) > 0 { - selector += ", " - } + if value.Service != nil { + service = *value.Service + } else { + for k, v := range *value.LabelSelector { + if len(selector) > 0 { + selector += ", " + } - selector += k + "=" + *v + selector += k + "=" + *v + } } - excludedPaths := "" if value.ExcludePaths != nil { @@ -176,13 +254,8 @@ func (cmd *ListCmd) RunListSync(cobraCmd *cobra.Command, args []string) { } } - resourceType := "pod" - if value.ResourceType != nil { - resourceType = *value.ResourceType - } - syncPaths = append(syncPaths, []string{ - resourceType, + service, selector, *value.LocalSubPath, *value.ContainerPath, @@ -203,6 +276,7 @@ func (cmd *ListCmd) RunListPort(cobraCmd *cobra.Command, args []string) { } headerColumnNames := []string{ + "Service", "Type", "Selector", "Ports (Local:Remote)", @@ -212,13 +286,19 @@ func (cmd *ListCmd) RunListPort(cobraCmd *cobra.Command, args []string) { // Transform values into string arrays for _, value := range *config.DevSpace.Ports { + service := "" selector := "" - for k, v := range *value.LabelSelector { - if len(selector) > 0 { - selector += ", " - } - selector += k + "=" + *v + if value.Service != nil { + service = *value.Service + } else { + for k, v := range *value.LabelSelector { + if len(selector) > 0 { + selector += ", " + } + + selector += k + "=" + *v + } } portMappings := "" @@ -236,6 +316,7 @@ func (cmd *ListCmd) RunListPort(cobraCmd *cobra.Command, args []string) { } portForwards = append(portForwards, []string{ + service, resourceType, selector, portMappings, diff --git a/cmd/up.go b/cmd/up.go index 9696805e65..34f09108ea 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -36,6 +36,7 @@ type UpCmdFlags struct { switchContext bool portforwarding bool verboseSync bool + service string container string labelSelector string namespace string @@ -85,15 +86,16 @@ Starts and connects your DevSpace: cobraCmd.Flags().BoolVar(&cmd.flags.tiller, "tiller", cmd.flags.tiller, "Install/upgrade tiller") cobraCmd.Flags().BoolVar(&cmd.flags.initRegistries, "init-registries", cmd.flags.initRegistries, "Initialize registries (and install internal one)") cobraCmd.Flags().BoolVarP(&cmd.flags.build, "build", "b", cmd.flags.build, "Force image build") - cobraCmd.Flags().StringVarP(&cmd.flags.container, "container", "c", cmd.flags.container, "Container name where to open the shell") cobraCmd.Flags().BoolVar(&cmd.flags.sync, "sync", cmd.flags.sync, "Enable code synchronization") cobraCmd.Flags().BoolVar(&cmd.flags.verboseSync, "verbose-sync", cmd.flags.verboseSync, "When enabled the sync will log every file change") cobraCmd.Flags().BoolVar(&cmd.flags.portforwarding, "portforwarding", cmd.flags.portforwarding, "Enable port forwarding") cobraCmd.Flags().BoolVarP(&cmd.flags.deploy, "deploy", "d", cmd.flags.deploy, "Force chart deployment") cobraCmd.Flags().BoolVar(&cmd.flags.switchContext, "switch-context", cmd.flags.switchContext, "Switch kubectl context to the devspace context") cobraCmd.Flags().BoolVar(&cmd.flags.exitAfterDeploy, "exit-after-deploy", cmd.flags.exitAfterDeploy, "Exits the command after building the images and deploying the devspace") - cobraCmd.Flags().StringVarP(&cmd.flags.namespace, "namespace", "n", "", "Namespace where to select pods") + cobraCmd.Flags().StringVarP(&cmd.flags.service, "service", "s", "", "Service name to select pods/container for terminal") + cobraCmd.Flags().StringVarP(&cmd.flags.container, "container", "c", cmd.flags.container, "Container name where to open the shell") cobraCmd.Flags().StringVarP(&cmd.flags.labelSelector, "label-selector", "l", "", "Comma separated key=value selector list (e.g. release=test)") + cobraCmd.Flags().StringVarP(&cmd.flags.namespace, "namespace", "n", "", "Namespace where to select pods") cobraCmd.Flags().StringVar(&cmd.flags.config, "config", configutil.ConfigPath, "The devspace config file to load (default: '.devspace/config.yaml'") } @@ -223,5 +225,5 @@ func (cmd *UpCmd) startServices(args []string) { log.Info("See https://devspace-cloud.com/domain-guide for more information") } - services.StartTerminal(cmd.kubectl, cmd.flags.container, cmd.flags.labelSelector, cmd.flags.namespace, args, log.GetInstance()) + services.StartTerminal(cmd.kubectl, cmd.flags.service, cmd.flags.container, cmd.flags.labelSelector, cmd.flags.namespace, args, log.GetInstance()) } diff --git a/pkg/devspace/config/configutil/get.go b/pkg/devspace/config/configutil/get.go index 3bd2f0bd69..130a0a1a04 100644 --- a/pkg/devspace/config/configutil/get.go +++ b/pkg/devspace/config/configutil/get.go @@ -4,6 +4,8 @@ import ( "os" "sync" + "github.com/juju/errors" + "github.com/covexo/devspace/pkg/util/kubeconfig" "github.com/covexo/devspace/pkg/util/log" "k8s.io/client-go/tools/clientcmd" @@ -28,6 +30,9 @@ var ConfigPath = DefaultConfigPath // OverwriteConfigPath specifies where the override.yaml lies var OverwriteConfigPath = "/.devspace/overwrite.yaml" +// DefaultDevspaceServiceName is the name of the initial default service +const DefaultDevspaceServiceName = "default" + // DefaultDevspaceDeploymentName is the name of the initial default deployment const DefaultDevspaceDeploymentName = "devspace-default" @@ -143,6 +148,18 @@ func SetDefaultsOnce() { } } + if config.DevSpace.Services != nil { + for index, serviceConfig := range *config.DevSpace.Services { + if serviceConfig.Name == nil { + log.Fatalf("Error in config: Unnamed service at index %d", index) + } + + if serviceConfig.Namespace == nil { + serviceConfig.Namespace = String("") + } + } + } + if config.DevSpace.Sync != nil { for _, syncPath := range *config.DevSpace.Sync { if syncPath.Namespace == nil { @@ -212,3 +229,25 @@ func GetDefaultNamespace(config *v1.Config) (string, error) { return "default", nil } + +// GetService returns the service referenced by serviceName +func GetService(serviceName string) (*v1.ServiceConfig, error) { + if config.DevSpace.Services != nil { + for _, service := range *config.DevSpace.Services { + if *service.Name == serviceName { + return service, nil + } + } + } + return nil, errors.New("Unable to find service: " + serviceName) +} + +// AddService adds a service to the config +func AddService(service *v1.ServiceConfig) error { + if config.DevSpace.Services == nil { + config.DevSpace.Services = &[]*v1.ServiceConfig{} + } + *config.DevSpace.Services = append(*config.DevSpace.Services, service) + + return nil +} diff --git a/pkg/devspace/config/v1/devspace.go b/pkg/devspace/config/v1/devspace.go index becc2e8080..96f230a040 100644 --- a/pkg/devspace/config/v1/devspace.go +++ b/pkg/devspace/config/v1/devspace.go @@ -3,13 +3,24 @@ package v1 //DevSpaceConfig defines the devspace deployment type DevSpaceConfig struct { Terminal *Terminal `yaml:"terminal"` + Services *[]*ServiceConfig `yaml:"services,omitempty"` Deployments *[]*DeploymentConfig `yaml:"deployments,omitempty"` Ports *[]*PortForwardingConfig `yaml:"ports"` Sync *[]*SyncConfig `yaml:"sync"` } +// ServiceConfig defines the ports for a port forwarding to a DevSpace +type ServiceConfig struct { + Name *string `yaml:"name,omitempty"` + Namespace *string `yaml:"namespace,omitempty"` + ResourceType *string `yaml:"resourceType,omitempty"` + LabelSelector *map[string]*string `yaml:"labelSelector"` + ContainerName *string `yaml:"containerName"` +} + // PortForwardingConfig defines the ports for a port forwarding to a DevSpace type PortForwardingConfig struct { + Service *string `yaml:"service,omitempty"` Namespace *string `yaml:"namespace,omitempty"` ResourceType *string `yaml:"resourceType,omitempty"` LabelSelector *map[string]*string `yaml:"labelSelector"` @@ -24,12 +35,12 @@ type PortMapping struct { // SyncConfig defines the paths for a SyncFolder type SyncConfig struct { + Service *string `yaml:"service,omitempty"` Namespace *string `yaml:"namespace,omitempty"` - ResourceType *string `yaml:"resourceType,omitempty"` LabelSelector *map[string]*string `yaml:"labelSelector"` + ContainerName *string `yaml:"containerName,omitempty"` LocalSubPath *string `yaml:"localSubPath"` ContainerPath *string `yaml:"containerPath"` - ContainerName *string `yaml:"containerName,omitempty"` ExcludePaths *[]string `yaml:"excludePaths"` DownloadExcludePaths *[]string `yaml:"downloadExcludePaths"` UploadExcludePaths *[]string `yaml:"uploadExcludePaths"` diff --git a/pkg/devspace/config/v1/terminal.go b/pkg/devspace/config/v1/terminal.go index 112033c7a6..936bd8babf 100644 --- a/pkg/devspace/config/v1/terminal.go +++ b/pkg/devspace/config/v1/terminal.go @@ -2,6 +2,7 @@ package v1 // Terminal describes the terminal options type Terminal struct { + Service *string `yaml:"service,omitempty"` ResourceType *string `yaml:"resourceType"` LabelSelector *map[string]*string `yaml:"labelSelector"` Namespace *string `yaml:"namespace"` diff --git a/pkg/devspace/configure/package.go b/pkg/devspace/configure/package.go index c05e7e213e..db76829690 100644 --- a/pkg/devspace/configure/package.go +++ b/pkg/devspace/configure/package.go @@ -22,6 +22,7 @@ import ( // AddPackage adds a helm dependency to specified deployment func AddPackage(skipQuestion bool, appVersion, chartVersion, deployment string, args []string, log log.Logger) (string, string, error) { + packageName := args[0] config := configutil.GetConfig() if config.DevSpace.Deployments == nil || (len(*config.DevSpace.Deployments) != 1 && deployment == "") { return "", "", fmt.Errorf("Please specify the deployment via the -d flag") @@ -59,7 +60,7 @@ func AddPackage(skipQuestion bool, appVersion, chartVersion, deployment string, } log.StartWait("Search Chart") - repo, version, err := helm.SearchChart(args[0], chartVersion, appVersion) + repo, version, err := helm.SearchChart(packageName, chartVersion, appVersion) log.StopWait() if err != nil { @@ -141,6 +142,21 @@ func AddPackage(skipQuestion bool, appVersion, chartVersion, deployment string, } } + err = configutil.AddService(&v1.ServiceConfig{ + Name: configutil.String(packageName), + LabelSelector: &map[string]*string{ + "chart": configutil.String(packageName), + }, + }) + if err != nil { + log.Fatalf("Unable to add service to config: %v", err) + } + + err = configutil.SaveConfig() + if err != nil { + log.Fatalf("Unable to save config: %v", err) + } + if skipQuestion == false { showReadme(chartPath, version) } diff --git a/pkg/devspace/configure/sync.go b/pkg/devspace/configure/sync.go index e584d103a5..9579fdae4e 100644 --- a/pkg/devspace/configure/sync.go +++ b/pkg/devspace/configure/sync.go @@ -46,7 +46,6 @@ func AddSyncPath(localPath, containerPath, namespace, selector, excludedPathsStr } syncConfig := append(*config.DevSpace.Sync, &v1.SyncConfig{ - ResourceType: nil, LabelSelector: &labelSelectorMap, ContainerPath: configutil.String(containerPath), LocalSubPath: configutil.String(localPath), diff --git a/pkg/devspace/services/port_forwarding.go b/pkg/devspace/services/port_forwarding.go index 2cef9d54fb..ca4776aa27 100644 --- a/pkg/devspace/services/port_forwarding.go +++ b/pkg/devspace/services/port_forwarding.go @@ -19,46 +19,59 @@ func StartPortForwarding(client *kubernetes.Clientset, log log.Logger) error { for _, portForwarding := range *config.DevSpace.Ports { if portForwarding.ResourceType == nil || *portForwarding.ResourceType == "pod" { - if len(*portForwarding.LabelSelector) > 0 { - labels := make([]string, 0, len(*portForwarding.LabelSelector)) - for key, value := range *portForwarding.LabelSelector { - labels = append(labels, key+"="+*value) + var labelSelector map[string]*string + namespace := "" + + if portForwarding.Service != nil { + service, err := configutil.GetService(*portForwarding.Service) + if err != nil { + log.Fatalf("Error resolving service name: %v", err) } - namespace := "" + labelSelector = *service.LabelSelector + if service.Namespace != nil && *service.Namespace != "" { + namespace = *service.Namespace + } + } else { + labelSelector = *portForwarding.LabelSelector if portForwarding.Namespace != nil && *portForwarding.Namespace != "" { namespace = *portForwarding.Namespace } + } - log.StartWait("Waiting for pods to become running") - pod, err := kubectl.GetNewestRunningPod(client, strings.Join(labels, ", "), namespace) - log.StopWait() + labels := make([]string, len(labelSelector)-1) + for key, value := range labelSelector { + labels = append(labels, key+"="+*value) + } - if err != nil { - return fmt.Errorf("Unable to list devspace pods: %s", err.Error()) - } else if pod != nil { - ports := make([]string, len(*portForwarding.PortMappings)) + log.StartWait("Waiting for pods to become running") + pod, err := kubectl.GetNewestRunningPod(client, strings.Join(labels, ", "), namespace) + log.StopWait() - for index, value := range *portForwarding.PortMappings { - ports[index] = strconv.Itoa(*value.LocalPort) + ":" + strconv.Itoa(*value.RemotePort) - } + if err != nil { + return fmt.Errorf("Unable to list devspace pods: %s", err.Error()) + } else if pod != nil { + ports := make([]string, len(*portForwarding.PortMappings)) - readyChan := make(chan struct{}) + for index, value := range *portForwarding.PortMappings { + ports[index] = strconv.Itoa(*value.LocalPort) + ":" + strconv.Itoa(*value.RemotePort) + } - go func() { - err := kubectl.ForwardPorts(client, pod, ports, make(chan struct{}), readyChan) - if err != nil { - log.Errorf("Error starting port forwarding: %v", err) - } - }() + readyChan := make(chan struct{}) - // Wait till forwarding is ready - select { - case <-readyChan: - log.Donef("Port forwarding started on %s", strings.Join(ports, ", ")) - case <-time.After(20 * time.Second): - return fmt.Errorf("Timeout waiting for port forwarding to start") + go func() { + err := kubectl.ForwardPorts(client, pod, ports, make(chan struct{}), readyChan) + if err != nil { + log.Errorf("Error starting port forwarding: %v", err) } + }() + + // Wait till forwarding is ready + select { + case <-readyChan: + log.Donef("Port forwarding started on %s", strings.Join(ports, ", ")) + case <-time.After(20 * time.Second): + return fmt.Errorf("Timeout waiting for port forwarding to start") } } } else { diff --git a/pkg/devspace/services/sync.go b/pkg/devspace/services/sync.go index 21e1fcb7c9..5957285946 100644 --- a/pkg/devspace/services/sync.go +++ b/pkg/devspace/services/sync.go @@ -24,16 +24,38 @@ func StartSync(client *kubernetes.Clientset, verboseSync bool, log log.Logger) ( return nil, fmt.Errorf("Unable to resolve localSubPath %s: %v", *syncPath.LocalSubPath, err) } - // Retrieve pod from label selector - labels := make([]string, 0, len(*syncPath.LabelSelector)) - for key, value := range *syncPath.LabelSelector { - labels = append(labels, key+"="+*value) + var labelSelector map[string]*string + namespace := "" + containerName := "" + + if syncPath.Service != nil { + service, err := configutil.GetService(*syncPath.Service) + if err != nil { + log.Fatalf("Error resolving service name: %v", err) + } + + labelSelector = *service.LabelSelector + if service.Namespace != nil && *service.Namespace != "" { + namespace = *service.Namespace + } + + if service.ContainerName != nil && *service.ContainerName != "" { + containerName = *service.ContainerName + } + } else { + labelSelector = *syncPath.LabelSelector + if syncPath.Namespace != nil && *syncPath.Namespace != "" { + namespace = *syncPath.Namespace + } + + if syncPath.ContainerName != nil && *syncPath.ContainerName != "" { + containerName = *syncPath.ContainerName + } } - // Init namespace - namespace := "" - if syncPath.Namespace != nil { - namespace = *syncPath.Namespace + labels := make([]string, len(labelSelector)-1) + for key, value := range labelSelector { + labels = append(labels, key+"="+*value) } log.StartWait("Waiting for pods to become running") @@ -48,11 +70,11 @@ func StartSync(client *kubernetes.Clientset, verboseSync bool, log log.Logger) ( } container := &pod.Spec.Containers[0] - if syncPath.ContainerName != nil && *syncPath.ContainerName != "" { + if containerName != "" { found := false for _, c := range pod.Spec.Containers { - if c.Name == *syncPath.ContainerName { + if c.Name == containerName { container = &c found = true break @@ -60,7 +82,7 @@ func StartSync(client *kubernetes.Clientset, verboseSync bool, log log.Logger) ( } if found == false { - log.Warnf("Couldn't start sync, because container %s wasn't found in pod %s/%s", *syncPath.ContainerName, pod.Namespace, pod.Name) + log.Warnf("Couldn't start sync, because container %s wasn't found in pod %s/%s", containerName, pod.Namespace, pod.Name) continue } } diff --git a/pkg/devspace/services/terminal.go b/pkg/devspace/services/terminal.go index 6fd3c45093..ccbfc1486a 100644 --- a/pkg/devspace/services/terminal.go +++ b/pkg/devspace/services/terminal.go @@ -3,6 +3,8 @@ package services import ( "strings" + "github.com/covexo/devspace/pkg/devspace/config/v1" + "github.com/covexo/devspace/pkg/devspace/config/configutil" "github.com/covexo/devspace/pkg/devspace/kubectl" "github.com/covexo/devspace/pkg/util/log" @@ -11,7 +13,7 @@ import ( ) // StartTerminal opens a new terminal -func StartTerminal(client *kubernetes.Clientset, containerNameOverride string, labelSelectorOverride string, namespaceOverride string, args []string, log log.Logger) { +func StartTerminal(client *kubernetes.Clientset, serviceNameOverride, containerNameOverride, labelSelectorOverride, namespaceOverride string, args []string, log log.Logger) { var command []string config := configutil.GetConfig() @@ -31,11 +33,35 @@ func StartTerminal(client *kubernetes.Clientset, containerNameOverride string, l } } + var service *v1.ServiceConfig + serviceName := "" + + if serviceNameOverride == "" { + if config.DevSpace.Terminal.Service != nil { + serviceName = *config.DevSpace.Terminal.Service + } + } else { + serviceName = serviceNameOverride + } + + if serviceName != "" { + var err error + + service, err = configutil.GetService(serviceName) + if err != nil { + log.Fatalf("Error resolving service name: %v", err) + } + } + // Select pods namespace := "" if namespaceOverride == "" { - if config.DevSpace.Terminal != nil && config.DevSpace.Terminal.Namespace != nil { - namespace = *config.DevSpace.Terminal.Namespace + if service != nil { + namespace = *service.Namespace + } else { + if config.DevSpace.Terminal != nil && config.DevSpace.Terminal.Namespace != nil { + namespace = *config.DevSpace.Terminal.Namespace + } } } else { namespace = namespaceOverride @@ -45,13 +71,23 @@ func StartTerminal(client *kubernetes.Clientset, containerNameOverride string, l // Retrieve pod from label selector if labelSelectorOverride == "" { labelSelector = "release=" + GetNameOfFirstHelmDeployment() - if config.DevSpace.Terminal != nil && config.DevSpace.Terminal.LabelSelector != nil { - labels := make([]string, 0, len(*config.DevSpace.Terminal.LabelSelector)) - for key, value := range *config.DevSpace.Terminal.LabelSelector { + + if service != nil { + labels := make([]string, 0, len(*service.LabelSelector)-1) + for key, value := range *service.LabelSelector { labels = append(labels, key+"="+*value) } labelSelector = strings.Join(labels, ", ") + } else { + if config.DevSpace.Terminal != nil && config.DevSpace.Terminal.LabelSelector != nil { + labels := make([]string, 0, len(*config.DevSpace.Terminal.LabelSelector)) + for key, value := range *config.DevSpace.Terminal.LabelSelector { + labels = append(labels, key+"="+*value) + } + + labelSelector = strings.Join(labels, ", ") + } } } else { labelSelector = labelSelectorOverride @@ -67,10 +103,16 @@ func StartTerminal(client *kubernetes.Clientset, containerNameOverride string, l // Get container name containerName := pod.Spec.Containers[0].Name - if containerNameOverride != "" { + if containerNameOverride == "" { + if service != nil { + containerName = *service.ContainerName + } else { + if config.DevSpace.Terminal.ContainerName != nil { + containerName = *config.DevSpace.Terminal.ContainerName + } + } + } else { containerName = containerNameOverride - } else if config.DevSpace.Terminal.ContainerName != nil { - containerName = *config.DevSpace.Terminal.ContainerName } _, _, _, terminalErr := kubectl.Exec(client, pod, containerName, command, true, nil)