Skip to content

Commit ffa8ebf

Browse files
committed
Implement new pod waiting strategy
1 parent 75f2ccb commit ffa8ebf

7 files changed

Lines changed: 97 additions & 47 deletions

File tree

cmd/add.go

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,20 @@ type addSyncCmdFlags struct {
4444
LocalPath string
4545
ContainerPath string
4646
ExcludedPaths string
47+
Namespace string
4748
}
4849

4950
type addPortCmdFlags struct {
5051
ResourceType string
5152
Selector string
53+
Namespace string
5254
}
5355

5456
type addPackageFlags struct {
5557
AppVersion string
5658
ChartVersion string
5759
SkipQuestion bool
60+
Deployment string
5861
}
5962

6063
func init() {
@@ -106,6 +109,7 @@ func init() {
106109
addSyncCmd.Flags().StringVar(&cmd.syncFlags.ResourceType, "resource-type", "pod", "Selected resource type")
107110
addSyncCmd.Flags().StringVar(&cmd.syncFlags.Selector, "selector", "", "Comma separated key=value selector list (e.g. release=test)")
108111
addSyncCmd.Flags().StringVar(&cmd.syncFlags.LocalPath, "local", "", "Relative local path")
112+
addSyncCmd.Flags().StringVar(&cmd.syncFlags.Namespace, "namespace", "", "Namespace to use")
109113
addSyncCmd.Flags().StringVar(&cmd.syncFlags.ContainerPath, "container", "", "Absolute container path")
110114
addSyncCmd.Flags().StringVar(&cmd.syncFlags.ExcludedPaths, "exclude", "", "Comma separated list of paths to exclude (e.g. node_modules/,bin,*.exe)")
111115

@@ -129,6 +133,7 @@ func init() {
129133
}
130134

131135
addPortCmd.Flags().StringVar(&cmd.portFlags.ResourceType, "resource-type", "pod", "Selected resource type")
136+
addSyncCmd.Flags().StringVar(&cmd.portFlags.Namespace, "namespace", "", "Namespace to use")
132137
addPortCmd.Flags().StringVar(&cmd.portFlags.Selector, "selector", "", "Comma separated key=value selector list (e.g. release=test)")
133138

134139
addCmd.AddCommand(addPortCmd)
@@ -148,21 +153,39 @@ func init() {
148153
devspace add package
149154
devspace add package mysql
150155
devspace add package mysql --app-version=5.7.14
151-
devspace add package mysql --chart-version=0.10.3
156+
devspace add package mysql --chart-version=0.10.3 -d devspace-default
152157
#######################################################
153158
`,
154159
Run: cmd.RunAddPackage,
155160
}
156161

157162
addPackageCmd.Flags().StringVar(&cmd.packageFlags.AppVersion, "app-version", "", "App version")
158163
addPackageCmd.Flags().StringVar(&cmd.packageFlags.ChartVersion, "chart-version", "", "Chart version")
164+
addPackageCmd.Flags().StringVarP(&cmd.packageFlags.Deployment, "deployment", "d", "", "The deployment name to use")
159165
addPackageCmd.Flags().BoolVar(&cmd.packageFlags.SkipQuestion, "skip-question", false, "Skips the question to show the readme in a browser")
160166

161167
addCmd.AddCommand(addPackageCmd)
162168
}
163169

164170
// RunAddPackage executes the add package command logic
165171
func (cmd *AddCmd) RunAddPackage(cobraCmd *cobra.Command, args []string) {
172+
config := configutil.GetConfig()
173+
if config.DevSpace.Deployments == nil || (len(*config.DevSpace.Deployments) != 1 && cmd.packageFlags.Deployment == "") {
174+
log.Fatalf("Please specify the deployment via the -d flag")
175+
}
176+
177+
var deploymentConfig *v1.DeploymentConfig
178+
for _, deployConfig := range *config.DevSpace.Deployments {
179+
if cmd.packageFlags.Deployment == "" || cmd.packageFlags.Deployment == *deployConfig.Name {
180+
if deployConfig.Helm == nil || deployConfig.Helm.ChartPath == nil {
181+
log.Fatalf("Selected deployment %s is not a valid helm deployment", *deployConfig.Name)
182+
}
183+
184+
deploymentConfig = deployConfig
185+
break
186+
}
187+
}
188+
166189
kubectl, err := kubectl.NewClient()
167190
if err != nil {
168191
log.Fatalf("Unable to create new kubectl client: %v", err)
@@ -187,13 +210,12 @@ func (cmd *AddCmd) RunAddPackage(cobraCmd *cobra.Command, args []string) {
187210
}
188211

189212
log.Done("Chart found")
190-
191-
cwd, err := os.Getwd()
213+
chartPath, err := filepath.Abs(*deploymentConfig.Helm.ChartPath)
192214
if err != nil {
193215
log.Fatal(err)
194216
}
195217

196-
requirementsFile := filepath.Join(cwd, "chart", "requirements.yaml")
218+
requirementsFile := filepath.Join(chartPath, "requirements.yaml")
197219
_, err = os.Stat(requirementsFile)
198220
if os.IsNotExist(err) {
199221
entry := "dependencies:\n" +
@@ -234,15 +256,15 @@ func (cmd *AddCmd) RunAddPackage(cobraCmd *cobra.Command, args []string) {
234256
}
235257

236258
log.StartWait("Update chart dependencies")
237-
err = helm.UpdateDependencies(filepath.Join(cwd, "chart"))
259+
err = helm.UpdateDependencies(chartPath)
238260
log.StopWait()
239261

240262
if err != nil {
241263
log.Fatal(err)
242264
}
243265

244266
// Check if key already exists
245-
valuesYaml := filepath.Join(cwd, "chart", "values.yaml")
267+
valuesYaml := filepath.Join(chartPath, "values.yaml")
246268
valuesYamlContents := map[interface{}]interface{}{}
247269

248270
err = yamlutil.ReadYamlFromFile(valuesYaml, valuesYamlContents)
@@ -262,16 +284,11 @@ func (cmd *AddCmd) RunAddPackage(cobraCmd *cobra.Command, args []string) {
262284
}
263285
}
264286

265-
log.Donef("Successfully added %s as chart dependency, you can configure the package in 'chart/values.yaml'", version.GetName())
266-
cmd.showReadme(version)
287+
log.Donef("Successfully added %s as chart dependency, you can configure the package in '%s/values.yaml'", *deploymentConfig.Helm.ChartPath, version.GetName())
288+
cmd.showReadme(chartPath, version)
267289
}
268290

269-
func (cmd *AddCmd) showReadme(chartVersion *repo.ChartVersion) {
270-
cwd, err := os.Getwd()
271-
if err != nil {
272-
log.Fatal(err)
273-
}
274-
291+
func (cmd *AddCmd) showReadme(chartPath string, chartVersion *repo.ChartVersion) {
275292
if cmd.packageFlags.SkipQuestion {
276293
return
277294
}
@@ -286,7 +303,7 @@ func (cmd *AddCmd) showReadme(chartVersion *repo.ChartVersion) {
286303
return
287304
}
288305

289-
content, err := tar.ExtractSingleFileToStringTarGz(filepath.Join(cwd, "chart", "charts", chartVersion.GetName()+"-"+chartVersion.GetVersion()+".tgz"), chartVersion.GetName()+"/README.md")
306+
content, err := tar.ExtractSingleFileToStringTarGz(filepath.Join(chartPath, "charts", chartVersion.GetName()+"-"+chartVersion.GetVersion()+".tgz"), chartVersion.GetName()+"/README.md")
290307
if err != nil {
291308
log.Fatal(err)
292309
}
@@ -349,6 +366,7 @@ func (cmd *AddCmd) RunAddSync(cobraCmd *cobra.Command, args []string) {
349366
ContainerPath: configutil.String(cmd.syncFlags.ContainerPath),
350367
LocalSubPath: configutil.String(cmd.syncFlags.LocalPath),
351368
ExcludePaths: &excludedPaths,
369+
Namespace: &cmd.syncFlags.Namespace,
352370
})
353371

354372
config.DevSpace.Sync = &syncConfig
@@ -408,6 +426,7 @@ func (cmd *AddCmd) insertOrReplacePortMapping(labelSelectorMap map[string]*strin
408426
ResourceType: nil,
409427
LabelSelector: &labelSelectorMap,
410428
PortMappings: &portMappings,
429+
Namespace: &cmd.portFlags.Namespace,
411430
})
412431

413432
config.DevSpace.PortForwarding = &portMap

cmd/remove.go

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"os"
54
"path/filepath"
65
"strconv"
76
"strings"
@@ -36,7 +35,8 @@ type removePortCmdFlags struct {
3635
}
3736

3837
type removePackageCmdFlags struct {
39-
RemoveAll bool
38+
RemoveAll bool
39+
Deployment string
4040
}
4141

4242
func init() {
@@ -113,7 +113,6 @@ func init() {
113113
removePortCmd.Flags().BoolVar(&cmd.portFlags.RemoveAll, "all", false, "Remove all configured ports")
114114

115115
removeCmd.AddCommand(removePortCmd)
116-
117116
removePackageCmd := &cobra.Command{
118117
Use: "package",
119118
Short: "Removes forwarded ports from a devspace",
@@ -123,19 +122,38 @@ func init() {
123122
#######################################################
124123
Removes a package from the devspace:
125124
devspace remove package mysql
125+
devspace remove package mysql -d devspace-default
126126
#######################################################
127127
`,
128128
Args: cobra.MaximumNArgs(1),
129129
Run: cmd.RunRemovePackage,
130130
}
131131

132132
removePackageCmd.Flags().BoolVar(&cmd.packageFlags.RemoveAll, "all", false, "Remove all packages")
133+
removePackageCmd.Flags().StringVarP(&cmd.packageFlags.Deployment, "deployment", "d", "", "The deployment name to use")
133134
removeCmd.AddCommand(removePackageCmd)
134135
}
135136

136137
// RunRemovePackage executes the remove package command logic
137138
func (cmd *RemoveCmd) RunRemovePackage(cobraCmd *cobra.Command, args []string) {
138-
cwd, err := os.Getwd()
139+
config := configutil.GetConfig()
140+
if config.DevSpace.Deployments == nil || (len(*config.DevSpace.Deployments) != 1 && cmd.packageFlags.Deployment == "") {
141+
log.Fatalf("Please specify the deployment via the -d flag")
142+
}
143+
144+
var deploymentConfig *v1.DeploymentConfig
145+
for _, deployConfig := range *config.DevSpace.Deployments {
146+
if cmd.packageFlags.Deployment == "" || cmd.packageFlags.Deployment == *deployConfig.Name {
147+
if deployConfig.Helm == nil || deployConfig.Helm.ChartPath == nil {
148+
log.Fatalf("Selected deployment %s is not a valid helm deployment", *deployConfig.Name)
149+
}
150+
151+
deploymentConfig = deployConfig
152+
break
153+
}
154+
}
155+
156+
chartPath, err := filepath.Abs(*deploymentConfig.Helm.ChartPath)
139157
if err != nil {
140158
log.Fatal(err)
141159
}
@@ -144,7 +162,7 @@ func (cmd *RemoveCmd) RunRemovePackage(cobraCmd *cobra.Command, args []string) {
144162
log.Fatal("You need to specify a package name or the --all flag")
145163
}
146164

147-
requirementsPath := filepath.Join(cwd, "chart", "requirements.yaml")
165+
requirementsPath := filepath.Join(chartPath, "requirements.yaml")
148166
yamlContents := map[interface{}]interface{}{}
149167

150168
err = yamlutil.ReadYamlFromFile(requirementsPath, yamlContents)
@@ -170,7 +188,7 @@ func (cmd *RemoveCmd) RunRemovePackage(cobraCmd *cobra.Command, args []string) {
170188
dependenciesArr = append(dependenciesArr[:key], dependenciesArr[key+1:]...)
171189
yamlContents["dependencies"] = dependenciesArr
172190

173-
cmd.rebuildDependencies(yamlContents)
191+
cmd.rebuildDependencies(chartPath, yamlContents)
174192
break
175193
}
176194
}
@@ -182,21 +200,16 @@ func (cmd *RemoveCmd) RunRemovePackage(cobraCmd *cobra.Command, args []string) {
182200

183201
yamlContents["dependencies"] = []interface{}{}
184202

185-
cmd.rebuildDependencies(yamlContents)
203+
cmd.rebuildDependencies(chartPath, yamlContents)
186204
log.Done("Successfully removed all dependencies")
187205
return
188206
}
189207

190208
log.Done("No dependencies found")
191209
}
192210

193-
func (cmd *RemoveCmd) rebuildDependencies(newYamlContents map[interface{}]interface{}) {
194-
cwd, err := os.Getwd()
195-
if err != nil {
196-
log.Fatal(err)
197-
}
198-
199-
err = yamlutil.WriteYamlToFile(newYamlContents, filepath.Join(cwd, "chart", "requirements.yaml"))
211+
func (cmd *RemoveCmd) rebuildDependencies(chartPath string, newYamlContents map[interface{}]interface{}) {
212+
err := yamlutil.WriteYamlToFile(newYamlContents, filepath.Join(chartPath, "requirements.yaml"))
200213
if err != nil {
201214
log.Fatal(err)
202215
}
@@ -213,7 +226,7 @@ func (cmd *RemoveCmd) rebuildDependencies(newYamlContents map[interface{}]interf
213226
}
214227

215228
log.StartWait("Update chart dependencies")
216-
err = helm.UpdateDependencies(filepath.Join(cwd, "chart"))
229+
err = helm.UpdateDependencies(chartPath)
217230
log.StopWait()
218231

219232
if err != nil {

pkg/devspace/config/v1/deployments.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ type DeploymentConfig struct {
1010

1111
// HelmConfig defines the specific helm options used during deployment
1212
type HelmConfig struct {
13-
ChartPath *string `yaml:"chartPath,omitempty"`
14-
Values *map[interface{}]interface{} `yaml:"values,omitempty"`
13+
ChartPath *string `yaml:"chartPath,omitempty"`
1514
}
1615

1716
// KubectlConfig defines the specific kubectl options used during deployment

pkg/devspace/kubectl/client.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"os"
1010
"sync"
11+
"time"
1112

1213
"github.com/covexo/devspace/pkg/util/kubeconfig"
1314

@@ -158,23 +159,41 @@ func IsMinikube() bool {
158159
return *isMinikubeVar
159160
}
160161

161-
// GetFirstRunningPod retrieves the first pod that is found that has the status "Running" using the label selector string
162-
func GetFirstRunningPod(kubectl *kubernetes.Clientset, labelSelector, namespace string) (*k8sv1.Pod, error) {
163-
podList, err := kubectl.Core().Pods(namespace).List(metav1.ListOptions{
164-
LabelSelector: labelSelector,
165-
})
162+
// GetNewestRunningPod retrieves the first pod that is found that has the status "Running" using the label selector string
163+
func GetNewestRunningPod(kubectl *kubernetes.Clientset, labelSelector, namespace string) (*k8sv1.Pod, error) {
164+
maxWaiting := 120 * time.Second
165+
waitingInterval := 1 * time.Second
166166

167-
if err != nil {
168-
return nil, err
169-
}
167+
for maxWaiting > 0 {
168+
time.Sleep(waitingInterval)
170169

171-
for _, pod := range podList.Items {
172-
if GetPodStatus(&pod) == "Running" {
173-
return &pod, nil
170+
podList, err := kubectl.Core().Pods(namespace).List(metav1.ListOptions{
171+
LabelSelector: labelSelector,
172+
})
173+
if err != nil {
174+
return nil, err
174175
}
176+
177+
if podList.Size() > 0 && len(podList.Items) > 0 {
178+
// Get Pod with latest creation timestamp
179+
var selectedPod *k8sv1.Pod
180+
181+
for _, pod := range podList.Items {
182+
if selectedPod == nil || pod.CreationTimestamp.After(selectedPod.CreationTimestamp.Time) {
183+
selectedPod = &pod
184+
}
185+
}
186+
187+
if selectedPod != nil && GetPodStatus(selectedPod) == "Running" {
188+
return selectedPod, nil
189+
}
190+
}
191+
192+
time.Sleep(waitingInterval)
193+
maxWaiting -= waitingInterval * 2
175194
}
176195

177-
return nil, nil
196+
return nil, fmt.Errorf("Waiting for pod with selector %s in namespace %s timed out", labelSelector, namespace)
178197
}
179198

180199
// GetPodStatus returns the pod status as a string

pkg/devspace/services/port_forwarding.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func StartPortForwarding(client *kubernetes.Clientset, log log.Logger) error {
3030
namespace = *portForwarding.Namespace
3131
}
3232

33-
pod, err := kubectl.GetFirstRunningPod(client, strings.Join(labels, ", "), namespace)
33+
pod, err := kubectl.GetNewestRunningPod(client, strings.Join(labels, ", "), namespace)
3434
if err != nil {
3535
return fmt.Errorf("Unable to list devspace pods: %s", err.Error())
3636
} else if pod != nil {

pkg/devspace/services/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func StartSync(client *kubernetes.Clientset, verboseSync bool, log log.Logger) (
3636
namespace = *syncPath.Namespace
3737
}
3838

39-
pod, err := kubectl.GetFirstRunningPod(client, strings.Join(labels, ", "), namespace)
39+
pod, err := kubectl.GetNewestRunningPod(client, strings.Join(labels, ", "), namespace)
4040
if err != nil {
4141
return nil, fmt.Errorf("Unable to list devspace pods: %v", err)
4242
} else if pod != nil {

pkg/devspace/services/terminal.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func StartTerminal(client *kubernetes.Clientset, containerNameOverride string, a
4949
}
5050

5151
// Get first running pod
52-
pod, err := kubectl.GetFirstRunningPod(client, labelSelector, namespace)
52+
pod, err := kubectl.GetNewestRunningPod(client, labelSelector, namespace)
5353
if err != nil {
5454
log.Fatalf("Cannot find running pod: %v", err)
5555
}

0 commit comments

Comments
 (0)