Skip to content

Commit

Permalink
Merge 4708271 into 0a8500d
Browse files Browse the repository at this point in the history
  • Loading branch information
feloy authored May 1, 2023
2 parents 0a8500d + 4708271 commit 491337b
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 151 deletions.
20 changes: 4 additions & 16 deletions pkg/dev/kubedev/kubedev.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/redhat-developer/odo/pkg/devfile/location"
"github.com/redhat-developer/odo/pkg/exec"
"github.com/redhat-developer/odo/pkg/kclient"
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
"github.com/redhat-developer/odo/pkg/portForward"
"github.com/redhat-developer/odo/pkg/preference"
"github.com/redhat-developer/odo/pkg/sync"
Expand Down Expand Up @@ -87,23 +86,12 @@ func (o *DevClient) Start(
klog.V(4).Infoln("Creating new adapter")

var (
devfileObj = odocontext.GetDevfileObj(ctx)
componentStatus = watch.ComponentStatus{
ImageComponentsAutoApplied: make(map[string]devfilev1.ImageComponent),
}
)

pushParameters := common.PushParameters{
StartOptions: options,
Devfile: *devfileObj,
}

klog.V(4).Infoln("Creating inner-loop resources for the component")
componentStatus := watch.ComponentStatus{
ImageComponentsAutoApplied: make(map[string]devfilev1.ImageComponent),
}
err := o.reconcile(ctx, pushParameters, &componentStatus)
if err != nil {
return err
}
klog.V(4).Infoln("Successfully created inner-loop resources")

watchParameters := watch.WatchParameters{
StartOptions: options,
Expand All @@ -120,7 +108,7 @@ func (o *DevClient) regenerateAdapterAndPush(ctx context.Context, pushParams com

devObj, err := devfile.ParseAndValidateFromFileWithVariables(location.DevfileLocation(""), pushParams.StartOptions.Variables)
if err != nil {
return fmt.Errorf("unable to generate component from watch parameters: %w", err)
return fmt.Errorf("unable to read devfile: %w", err)
}

pushParams.Devfile = devObj
Expand Down
16 changes: 5 additions & 11 deletions pkg/dev/podmandev/podmandev.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
"path/filepath"
"strings"

devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
Expand Down Expand Up @@ -77,21 +76,15 @@ func (o *DevClient) Start(
ctx context.Context,
options dev.StartOptions,
) error {
var (
devfilePath = odocontext.GetDevfilePath(ctx)
path = filepath.Dir(devfilePath)
klog.V(4).Infoln("Creating new adapter")

var (
componentStatus = watch.ComponentStatus{
ImageComponentsAutoApplied: make(map[string]devfilev1.ImageComponent),
}
)

err := o.reconcile(ctx, options, &componentStatus)
if err != nil {
return err
}

watch.PrintInfoMessage(options.Out, path, options.WatchFiles, promptMessage)
klog.V(4).Infoln("Creating inner-loop resources for the component")

watchParameters := watch.WatchParameters{
StartOptions: options,
Expand Down Expand Up @@ -171,8 +164,9 @@ func (o *DevClient) checkVolumesFree(pod *corev1.Pod) error {
}

func (o *DevClient) watchHandler(ctx context.Context, pushParams common.PushParameters, componentStatus *watch.ComponentStatus) error {
pushParams.Devfile = *odocontext.GetDevfileObj(ctx) // TOO reload devfile from disk
printWarningsOnDevfileChanges(ctx, pushParams.StartOptions)
return o.reconcile(ctx, pushParams.StartOptions, componentStatus)
return o.reconcile(ctx, pushParams, componentStatus)
}

func printWarningsOnDevfileChanges(ctx context.Context, options dev.StartOptions) {
Expand Down
20 changes: 11 additions & 9 deletions pkg/dev/podmandev/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,21 @@ import (

func (o *DevClient) reconcile(
ctx context.Context,
options dev.StartOptions,
parameters common.PushParameters,
componentStatus *watch.ComponentStatus,
) error {
var (
appName = odocontext.GetApplication(ctx)
componentName = odocontext.GetComponentName(ctx)
devfileObj = odocontext.GetDevfileObj(ctx)
devfilePath = odocontext.GetDevfilePath(ctx)
path = filepath.Dir(devfilePath)
options = parameters.StartOptions
devfileObj = parameters.Devfile
)

o.warnAboutK8sComponents(*devfileObj)
o.warnAboutK8sComponents(devfileObj)

err := o.buildPushAutoImageComponents(ctx, *devfileObj)
err := o.buildPushAutoImageComponents(ctx, devfileObj)
if err != nil {
return err
}
Expand All @@ -54,6 +55,7 @@ func (o *DevClient) reconcile(
return err
}
o.deployedPod = pod
componentStatus.State = watch.StateReady

execRequired, err := o.syncFiles(ctx, options, pod, path)
if err != nil {
Expand All @@ -62,7 +64,7 @@ func (o *DevClient) reconcile(

// PostStart events from the devfile will only be executed when the component
// didn't previously exist
if !componentStatus.PostStartEventsDone && libdevfile.HasPostStartEvents(*devfileObj) {
if !componentStatus.PostStartEventsDone && libdevfile.HasPostStartEvents(devfileObj) {
execHandler := component.NewExecHandler(
o.podmanClient,
o.execClient,
Expand All @@ -72,7 +74,7 @@ func (o *DevClient) reconcile(
"Executing post-start command in container",
false, /* TODO */
)
err = libdevfile.ExecPostStartEvents(ctx, *devfileObj, execHandler)
err = libdevfile.ExecPostStartEvents(ctx, devfileObj, execHandler)
if err != nil {
return err
}
Expand All @@ -90,7 +92,7 @@ func (o *DevClient) reconcile(
"Building your application in container",
false, /* TODO */
)
return libdevfile.Build(ctx, *devfileObj, options.BuildCommand, execHandler)
return libdevfile.Build(ctx, devfileObj, options.BuildCommand, execHandler)
}
err = doExecuteBuildCommand()
if err != nil {
Expand All @@ -113,7 +115,7 @@ func (o *DevClient) reconcile(
appName: appName,
componentName: componentName,
}
err = libdevfile.ExecuteCommandByNameAndKind(ctx, *devfileObj, cmdName, cmdKind, &cmdHandler, false)
err = libdevfile.ExecuteCommandByNameAndKind(ctx, devfileObj, cmdName, cmdKind, &cmdHandler, false)
if err != nil {
return err
}
Expand All @@ -140,7 +142,7 @@ func (o *DevClient) reconcile(

if options.ForwardLocalhost {
// Port-forwarding is enabled by executing dedicated socat commands
err = o.portForwardClient.StartPortForwarding(ctx, *devfileObj, componentName, options.Debug, options.RandomPorts, options.Out, options.ErrOut, fwPorts)
err = o.portForwardClient.StartPortForwarding(ctx, devfileObj, componentName, options.Debug, options.RandomPorts, options.Out, options.ErrOut, fwPorts)
if err != nil {
return common.NewErrPortForward(err)
}
Expand Down
83 changes: 27 additions & 56 deletions pkg/watch/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ type WatchClient struct {

// true to force sync, used when manual sync
forceSync bool

// deploymentGeneration indicates the generation of the latest observed Deployment
deploymentGeneration int64
readyReplicas int32
}

var _ Client = (*WatchClient)(nil)
Expand Down Expand Up @@ -83,7 +87,7 @@ type evaluateChangesFunc func(events []fsnotify.Event, path string, fileIgnores

// processEventsFunc processes the events received on the watcher. It uses the WatchParameters to trigger watch handler and writes to out
// It returns a Duration after which to recall in case of error
type processEventsFunc func(ctx context.Context, parameters WatchParameters, changedFiles, deletedPaths []string, componentStatus *ComponentStatus, backoff *ExpBackoff) (*time.Duration, error)
type processEventsFunc func(ctx context.Context, parameters WatchParameters, changedFiles, deletedPaths []string, componentStatus *ComponentStatus) error

func (o *WatchClient) WatchAndPush(ctx context.Context, parameters WatchParameters, componentStatus ComponentStatus) error {
var (
Expand Down Expand Up @@ -159,6 +163,12 @@ func (o *WatchClient) WatchAndPush(ctx context.Context, parameters WatchParamete
}

o.keyWatcher = getKeyWatcher(ctx, parameters.StartOptions.Out)

err = o.processEvents(ctx, parameters, nil, nil, &componentStatus)
if err != nil {
return err
}

return o.eventWatcher(ctx, parameters, evaluateFileChanges, o.processEvents, componentStatus)
}

Expand All @@ -181,8 +191,6 @@ func (o *WatchClient) eventWatcher(
out = parameters.StartOptions.Out
)

expBackoff := NewExpBackoff()

var events []fsnotify.Event

// sourcesTimer helps collect multiple events that happen in a quick succession. We start with 1ms as we don't care much
Expand All @@ -202,10 +210,6 @@ func (o *WatchClient) eventWatcher(
deployTimer := time.NewTimer(time.Millisecond)
<-deployTimer.C

// retryTimer is a timer used to retry later a sync that has failed
retryTimer := time.NewTimer(time.Millisecond)
<-retryTimer.C

podsPhases := NewPodPhases()

for {
Expand Down Expand Up @@ -234,7 +238,7 @@ func (o *WatchClient) eventWatcher(

componentStatus.State = StateSyncOutdated
fmt.Fprintf(out, "Pushing files...\n\n")
retry, err := processEventsHandler(ctx, parameters, changedFiles, deletedPaths, &componentStatus, expBackoff)
err := processEventsHandler(ctx, parameters, changedFiles, deletedPaths, &componentStatus)
o.forceSync = false
if err != nil {
return err
Expand All @@ -244,13 +248,6 @@ func (o *WatchClient) eventWatcher(
events = []fsnotify.Event{} // empty the events slice to capture new events
}

if retry != nil {
retryTimer.Reset(*retry)
} else {
retryTimer.Reset(time.Millisecond)
<-retryTimer.C
}

case watchErr := <-o.sourcesWatcher.Errors:
return watchErr

Expand All @@ -263,53 +260,33 @@ func (o *WatchClient) eventWatcher(
case ev := <-o.deploymentWatcher.ResultChan():
switch obj := ev.Object.(type) {
case *appsv1.Deployment:
klog.V(4).Infof("deployment watcher Event: Type: %s, name: %s, rv: %s, pods: %d\n",
ev.Type, obj.GetName(), obj.GetResourceVersion(), obj.Status.ReadyReplicas)
deployTimer.Reset(300 * time.Millisecond)
klog.V(4).Infof("deployment watcher Event: Type: %s, name: %s, rv: %s, generation: %d, pods: %d\n",
ev.Type, obj.GetName(), obj.GetResourceVersion(), obj.GetGeneration(), obj.Status.ReadyReplicas)
if obj.GetGeneration() > o.deploymentGeneration || obj.Status.ReadyReplicas != o.readyReplicas {
o.deploymentGeneration = obj.GetGeneration()
o.readyReplicas = obj.Status.ReadyReplicas
deployTimer.Reset(300 * time.Millisecond)
}

case *metav1.Status:
klog.V(4).Infof("Status: %+v\n", obj)
}

case <-deployTimer.C:
retry, err := processEventsHandler(ctx, parameters, nil, nil, &componentStatus, expBackoff)
err := processEventsHandler(ctx, parameters, nil, nil, &componentStatus)
if err != nil {
return err
}
if retry != nil {
retryTimer.Reset(*retry)
} else {
retryTimer.Reset(time.Millisecond)
<-retryTimer.C
}

case <-o.devfileWatcher.Events:
devfileTimer.Reset(100 * time.Millisecond)

case <-devfileTimer.C:
fmt.Fprintf(out, "Updating Component...\n\n")
retry, err := processEventsHandler(ctx, parameters, nil, nil, &componentStatus, expBackoff)
if err != nil {
return err
}
if retry != nil {
retryTimer.Reset(*retry)
} else {
retryTimer.Reset(time.Millisecond)
<-retryTimer.C
}

case <-retryTimer.C:
retry, err := processEventsHandler(ctx, parameters, nil, nil, &componentStatus, expBackoff)
err := processEventsHandler(ctx, parameters, nil, nil, &componentStatus)
if err != nil {
return err
}
if retry != nil {
retryTimer.Reset(*retry)
} else {
retryTimer.Reset(time.Millisecond)
<-retryTimer.C
}

case ev := <-o.podWatcher.ResultChan():
switch ev.Type {
Expand Down Expand Up @@ -421,8 +398,7 @@ func (o *WatchClient) processEvents(
parameters WatchParameters,
changedFiles, deletedPaths []string,
componentStatus *ComponentStatus,
backoff *ExpBackoff,
) (*time.Duration, error) {
) error {
var (
devfilePath = odocontext.GetDevfilePath(ctx)
path = filepath.Dir(devfilePath)
Expand All @@ -447,7 +423,7 @@ func (o *WatchClient) processEvents(
err := parameters.DevfileWatchHandler(ctx, pushParams, componentStatus)
if err != nil {
if isFatal(err) {
return nil, err
return err
}
klog.V(4).Infof("Error from Push: %v", err)
// Log and output, but intentionally not exiting on error here.
Expand All @@ -462,22 +438,17 @@ func (o *WatchClient) processEvents(
fmt.Fprintf(out, "Updated Kubernetes config\n")
}
} else {
if parameters.StartOptions.WatchFiles {
fmt.Fprintf(out, "%s - %s\n\n", PushErrorString, err.Error())
} else {
return nil, err
}
fmt.Fprintf(out, "%s - %s\n\n", PushErrorString, err.Error())
PrintInfoMessage(out, path, parameters.StartOptions.WatchFiles, parameters.PromptMessage)
}
wait := backoff.Delay()
return &wait, nil
return nil
}
backoff.Reset()
if oldStatus.State != StateReady && componentStatus.State == StateReady ||
!reflect.DeepEqual(oldStatus.EndpointsForwarded, componentStatus.EndpointsForwarded) {

PrintInfoMessage(out, path, parameters.StartOptions.WatchFiles, parameters.PromptMessage)
}
return nil, nil
return nil
}

func shouldIgnoreEvent(event fsnotify.Event) (ignoreEvent bool) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/watch/watch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ func evaluateChangesHandler(events []fsnotify.Event, path string, fileIgnores []
return changedFiles, deletedPaths
}

func processEventsHandler(ctx context.Context, params WatchParameters, changedFiles, deletedPaths []string, componentStatus *ComponentStatus, backo *ExpBackoff) (*time.Duration, error) {
func processEventsHandler(ctx context.Context, params WatchParameters, changedFiles, deletedPaths []string, componentStatus *ComponentStatus) error {
fmt.Fprintf(params.StartOptions.Out, "changedFiles %s deletedPaths %s\n", changedFiles, deletedPaths)
return nil, nil
return nil
}

type fakeWatcher struct{}
Expand Down
4 changes: 4 additions & 0 deletions tests/helper/helper_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ type DevSessionOpts struct {
RunOnPodman bool
TimeoutInSeconds int
NoRandomPorts bool
NoWatch bool
}

// StartDevMode starts a dev session with `odo dev`
Expand All @@ -139,6 +140,9 @@ func StartDevMode(options DevSessionOpts) (devSession DevSession, out []byte, er
if !options.NoRandomPorts {
args = append(args, "--random-ports")
}
if options.NoWatch {
args = append(args, "--no-watch")
}
args = append(args, options.CmdlineArgs...)
cmd := Cmd("odo", args...)
cmd.Cmd.Stdin = c.Tty()
Expand Down
Loading

0 comments on commit 491337b

Please sign in to comment.