Skip to content

Commit bd5098e

Browse files
feloyrm3l
andauthored
Use devstats.PID.json as devstate (#6713)
* Use devstate.PID.json * odo describe component gets forwarded ports from devstate.json * Pass pid in context * Add platform to state * Overwrite devstate.json if PId not exists * odo describe component displays forwarded ports from podman/cluster * Start only one session on platform * Fix integration test * Review * Fix * Update pkg/state/errors.go Co-authored-by: Armel Soro <[email protected]> * Integration tests * Fix integration test --------- Co-authored-by: Armel Soro <[email protected]>
1 parent 0dc2f4d commit bd5098e

File tree

21 files changed

+479
-58
lines changed

21 files changed

+479
-58
lines changed

cmd/odo/odo.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/redhat-developer/odo/pkg/log"
1515
"github.com/redhat-developer/odo/pkg/odo/cli"
1616
"github.com/redhat-developer/odo/pkg/odo/cli/version"
17+
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
1718
"github.com/redhat-developer/odo/pkg/odo/util"
1819
"github.com/redhat-developer/odo/pkg/odo/util/completion"
1920
"github.com/redhat-developer/odo/pkg/preference"
@@ -31,6 +32,7 @@ func main() {
3132
util.LogErrorAndExit(err, "")
3233
}
3334
ctx = envcontext.WithEnvConfig(ctx, *envConfig)
35+
ctx = odocontext.WithPID(ctx, os.Getpid())
3436

3537
// create the complete command
3638
klog.InitFlags(nil)

pkg/dev/podmandev/reconcile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func (o *DevClient) reconcile(
143143

144144
if options.ForwardLocalhost {
145145
// Port-forwarding is enabled by executing dedicated socat commands
146-
err = o.portForwardClient.StartPortForwarding(*devfileObj, componentName, options.Debug, options.RandomPorts, out, errOut, fwPorts)
146+
err = o.portForwardClient.StartPortForwarding(ctx, *devfileObj, componentName, options.Debug, options.RandomPorts, out, errOut, fwPorts)
147147
if err != nil {
148148
return adapters.NewErrPortForward(err)
149149
}
@@ -153,7 +153,7 @@ func (o *DevClient) reconcile(
153153
s := fmt.Sprintf("Forwarding from %s:%d -> %d", fwPort.LocalAddress, fwPort.LocalPort, fwPort.ContainerPort)
154154
fmt.Fprintf(out, " - %s", log.SboldColor(color.FgGreen, s))
155155
}
156-
err = o.stateClient.SetForwardedPorts(fwPorts)
156+
err = o.stateClient.SetForwardedPorts(ctx, fwPorts)
157157
if err != nil {
158158
return err
159159
}

pkg/devfile/adapters/kubernetes/component/adapter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ func (a Adapter) Push(ctx context.Context, parameters adapters.PushParameters, c
366366
fmt.Fprintln(log.GetStdout())
367367
}
368368

369-
err = a.portForwardClient.StartPortForwarding(a.Devfile, a.ComponentName, parameters.Debug, parameters.RandomPorts, log.GetStdout(), parameters.ErrOut, parameters.CustomForwardedPorts)
369+
err = a.portForwardClient.StartPortForwarding(ctx, a.Devfile, a.ComponentName, parameters.Debug, parameters.RandomPorts, log.GetStdout(), parameters.ErrOut, parameters.CustomForwardedPorts)
370370
if err != nil {
371371
return adapters.NewErrPortForward(err)
372372
}

pkg/odo/cli/describe/component.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ func (o *ComponentOptions) describeDevfileComponent(ctx context.Context) (result
241241
kubeClient = nil
242242
}
243243

244-
allFwdPorts, err := o.clientset.StateClient.GetForwardedPorts()
244+
// TODO(feloy) Pass PID with `--pid` flag
245+
allFwdPorts, err := o.clientset.StateClient.GetForwardedPorts(ctx)
245246
if err != nil {
246247
return api.Component{}, nil, err
247248
}

pkg/odo/cli/dev/dev.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ import (
1212
"strings"
1313

1414
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
15-
"k8s.io/klog"
16-
17-
"github.com/redhat-developer/odo/pkg/api"
18-
1915
"github.com/spf13/cobra"
16+
"k8s.io/klog/v2"
2017
ktemplates "k8s.io/kubectl/pkg/util/templates"
2118

19+
"github.com/redhat-developer/odo/pkg/api"
2220
"github.com/redhat-developer/odo/pkg/component"
2321
"github.com/redhat-developer/odo/pkg/dev"
2422
"github.com/redhat-developer/odo/pkg/kclient"
@@ -35,6 +33,7 @@ import (
3533
odoutil "github.com/redhat-developer/odo/pkg/odo/util"
3634
"github.com/redhat-developer/odo/pkg/podman"
3735
scontext "github.com/redhat-developer/odo/pkg/segment/context"
36+
"github.com/redhat-developer/odo/pkg/state"
3837
"github.com/redhat-developer/odo/pkg/util"
3938
"github.com/redhat-developer/odo/pkg/version"
4039
)
@@ -231,6 +230,12 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
231230

232231
log.Sectionf("Running on %s in Dev mode", deployingTo)
233232

233+
err = o.clientset.StateClient.Init(ctx)
234+
if err != nil {
235+
err = fmt.Errorf("unable to save state file: %w", err)
236+
return err
237+
}
238+
234239
return o.clientset.DevClient.Start(
235240
o.ctx,
236241
o.out,
@@ -258,10 +263,14 @@ func (o *DevOptions) HandleSignal() error {
258263
}
259264

260265
func (o *DevOptions) Cleanup(ctx context.Context, commandError error) {
266+
if errors.As(commandError, &state.ErrAlreadyRunningOnPlatform{}) {
267+
klog.V(4).Info("session already running, no need to cleanup")
268+
return
269+
}
261270
if commandError != nil {
262271
_ = o.clientset.DevClient.CleanupResources(ctx, log.GetStdout())
263272
}
264-
_ = o.clientset.StateClient.SaveExit()
273+
_ = o.clientset.StateClient.SaveExit(ctx)
265274
}
266275

267276
// NewCmdDev implements the odo dev command

pkg/odo/context/odo.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
type (
1010
applicationKeyType struct{}
1111
cwdKeyType struct{}
12+
pidKeyType struct{}
1213
devfilePathKeyType struct{}
1314
devfileObjKeyType struct{}
1415
componentNameKeyType struct{}
@@ -17,6 +18,7 @@ type (
1718
var (
1819
applicationKey applicationKeyType
1920
cwdKey cwdKeyType
21+
pidKey pidKeyType
2022
devfilePathKey devfilePathKeyType
2123
devfileObjKey devfileObjKeyType
2224
componentNameKey componentNameKeyType
@@ -57,6 +59,23 @@ func GetWorkingDirectory(ctx context.Context) string {
5759
panic("this should not happen, either the original context is not passed or WithWorkingDirectory is not called as it should. Check that FILESYSTEM dependency is added to the command")
5860
}
5961

62+
// WithPID sets the value of the PID in ctx
63+
// This function must be used before calling GetPID
64+
// Use this function only with a context obtained from Complete/Validate/Run/... methods of Runnable interface
65+
func WithPID(ctx context.Context, val int) context.Context {
66+
return context.WithValue(ctx, pidKey, val)
67+
}
68+
69+
// GetPID gets the PID value in ctx
70+
// This function will panic if the context does not contain the value
71+
func GetPID(ctx context.Context) int {
72+
value := ctx.Value(pidKey)
73+
if cast, ok := value.(int); ok {
74+
return cast
75+
}
76+
panic("this should not happen, either the original context is not passed or WithPID is not called as it should")
77+
}
78+
6079
// WithDevfilePath sets the value of the devfile path in ctx
6180
// This function must be called before using GetDevfilePath
6281
func WithDevfilePath(ctx context.Context, val string) context.Context {

pkg/portForward/interface.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package portForward
22

33
import (
4+
"context"
45
"io"
56

67
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
@@ -16,6 +17,7 @@ type Client interface {
1617
// output will be written to errOut writer
1718
// definedPorts allows callers to explicitly define the mapping they want to set.
1819
StartPortForwarding(
20+
ctx context.Context,
1921
devFileObj parser.DevfileObj,
2022
componentName string,
2123
debug bool,

pkg/portForward/kubeportforward/portForward.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kubeportforward
22

33
import (
4+
"context"
45
"errors"
56
"fmt"
67
"io"
@@ -49,7 +50,7 @@ func NewPFClient(kubernetesClient kclient.ClientInterface, stateClient state.Cli
4950
}
5051
}
5152

52-
func (o *PFClient) StartPortForwarding(devFileObj parser.DevfileObj, componentName string, debug bool, randomPorts bool, out io.Writer, errOut io.Writer, definedPorts []api.ForwardedPort) error {
53+
func (o *PFClient) StartPortForwarding(ctx context.Context, devFileObj parser.DevfileObj, componentName string, debug bool, randomPorts bool, out io.Writer, errOut io.Writer, definedPorts []api.ForwardedPort) error {
5354
if randomPorts && len(definedPorts) != 0 {
5455
return errors.New("cannot use randomPorts and custom definePorts together")
5556
}
@@ -114,7 +115,7 @@ func (o *PFClient) StartPortForwarding(devFileObj parser.DevfileObj, componentNa
114115

115116
go func() {
116117
portsBuf.Wait()
117-
err = o.stateClient.SetForwardedPorts(portsBuf.GetForwardedPorts())
118+
err = o.stateClient.SetForwardedPorts(ctx, portsBuf.GetForwardedPorts())
118119
if err != nil {
119120
err = fmt.Errorf("unable to save forwarded ports to state file: %v", err)
120121
}

pkg/portForward/podmanportforward/portForward.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package podmanportforward
22

33
import (
4+
"context"
45
"fmt"
56
"io"
67
"reflect"
@@ -36,6 +37,7 @@ func NewPFClient(execClient exec.Client) *PFClient {
3637
}
3738

3839
func (o *PFClient) StartPortForwarding(
40+
ctx context.Context,
3941
devFileObj parser.DevfileObj,
4042
componentName string,
4143
debug bool,

pkg/registry/mock.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/state/const.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
package state
22

3+
const _dirpath = "./.odo"
34
const _filepath = "./.odo/devstate.json"
5+
const _filepathPid = "./.odo/devstate.%d.json"

pkg/state/doc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
// Package state gives access to the state of the odo process stored in a local file
2+
// The state of an instance is stored in a file .odo/devstate.${PID}.json.
3+
// For compatibility with previous versions of odo, the `devstate.json` file contains
4+
// the state of the first instance of odo.
25
package state

pkg/state/errors.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package state
2+
3+
import "fmt"
4+
5+
type ErrAlreadyRunningOnPlatform struct {
6+
platform string
7+
pid int
8+
}
9+
10+
func NewErrAlreadyRunningOnPlatform(platform string, pid int) ErrAlreadyRunningOnPlatform {
11+
return ErrAlreadyRunningOnPlatform{
12+
platform: platform,
13+
pid: pid,
14+
}
15+
}
16+
17+
func (e ErrAlreadyRunningOnPlatform) Error() string {
18+
return fmt.Sprintf("a session with PID %d is already running on platform %q", e.pid, e.platform)
19+
}

pkg/state/interface.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package state
22

3-
import "github.com/redhat-developer/odo/pkg/api"
3+
import (
4+
"context"
5+
6+
"github.com/redhat-developer/odo/pkg/api"
7+
)
48

59
type Client interface {
10+
// Init creates a devstate file for the process
11+
Init(ctx context.Context) error
12+
613
// SetForwardedPorts sets the forwarded ports in the state file and saves it to the file, updating the metadata
7-
SetForwardedPorts(fwPorts []api.ForwardedPort) error
14+
SetForwardedPorts(ctx context.Context, fwPorts []api.ForwardedPort) error
815

916
// GetForwardedPorts returns the ports forwarded by the current odo dev session
10-
GetForwardedPorts() ([]api.ForwardedPort, error)
17+
GetForwardedPorts(ctx context.Context) ([]api.ForwardedPort, error)
1118

1219
// SaveExit resets the state file to indicate odo is not running
13-
SaveExit() error
20+
SaveExit(ctx context.Context) error
1421
}

pkg/state/process_unix.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
2+
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
3+
4+
package state
5+
6+
import (
7+
"fmt"
8+
"os"
9+
"syscall"
10+
)
11+
12+
func pidExists(pid int) (bool, error) {
13+
if pid <= 0 {
14+
return false, fmt.Errorf("invalid pid %v", pid)
15+
}
16+
proc, err := os.FindProcess(pid)
17+
if err != nil {
18+
return false, nil
19+
}
20+
err = proc.Signal(syscall.Signal(0))
21+
if err == nil {
22+
return true, nil
23+
}
24+
if err.Error() == "os: process already finished" {
25+
return false, nil
26+
}
27+
errno, ok := err.(syscall.Errno)
28+
if !ok {
29+
return false, err
30+
}
31+
switch errno {
32+
case syscall.ESRCH:
33+
return false, nil
34+
case syscall.EPERM:
35+
return true, nil
36+
}
37+
return false, err
38+
}

pkg/state/process_windows.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package state
2+
3+
import (
4+
"fmt"
5+
"os"
6+
)
7+
8+
func pidExists(pid int) (bool, error) {
9+
if pid <= 0 {
10+
return false, fmt.Errorf("invalid pid %v", pid)
11+
}
12+
_, err := os.FindProcess(pid)
13+
if err != nil {
14+
return false, nil
15+
}
16+
return true, nil
17+
}

0 commit comments

Comments
 (0)