Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Fixed docker start command bug #1586

Merged
merged 58 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
287bec0
fixed docker start command bug
Yaxhveer Feb 16, 2024
9349a79
changes
Yaxhveer Feb 16, 2024
c2379e8
changes
Yaxhveer Feb 17, 2024
5f50192
[fix]: update permission to keploy directory if it exists (#1585)
AhmedLotfy02 Feb 17, 2024
e2af67e
chore: replace deprecated io/ioutil package (#1350)
nnnkkk7 Feb 17, 2024
7294389
[refactor]: hide complete test summary in case of app not running (#1…
AhmedLotfy02 Feb 19, 2024
a834839
Dummy commit
Yaxhveer Feb 19, 2024
215d3cf
code refactored
Yaxhveer Feb 20, 2024
4466e0a
code refactored
Yaxhveer Feb 20, 2024
ac0e8a3
Merge branch 'main' into docker-start-cmd
Yaxhveer Feb 21, 2024
40516aa
updated the changes
Yaxhveer Feb 22, 2024
2538a33
Merge branch 'main' into docker-start-cmd
Yaxhveer Feb 22, 2024
f3ddde9
dummy commit
Yaxhveer Feb 22, 2024
24bf9b6
dummy commit
Yaxhveer Feb 22, 2024
5df1351
changes
Yaxhveer Feb 22, 2024
cc4e01f
dummy commit
Yaxhveer Feb 22, 2024
cc61b00
linter issue fixed
Yaxhveer Feb 22, 2024
cf471f4
Merge branch 'main' into docker-start-cmd
Yaxhveer Feb 23, 2024
6db5e69
updated changes
Yaxhveer Feb 24, 2024
618b9b0
Merge branch 'main' into docker-start-cmd
Yaxhveer Feb 28, 2024
bdc268a
refactored
Yaxhveer Mar 4, 2024
8f53727
refactored
Yaxhveer Mar 4, 2024
c985555
Merge branch 'main' into docker-start-cmd
Yaxhveer Mar 4, 2024
7242ebe
Merge branch 'keploy:main' into docker-start-cmd
Yaxhveer Mar 5, 2024
c52fabf
Merge branch 'main' into docker-start-cmd
Yaxhveer Mar 9, 2024
2192672
Merge branch 'main' of https://github.com/Yaxhveer/keploy into docker…
Yaxhveer Apr 3, 2024
632245f
Merge branch 'main' of https://github.com/Yaxhveer/keploy into docker…
Yaxhveer Apr 3, 2024
b2e5e03
updated branch
Yaxhveer Apr 3, 2024
1213a7d
fixed linter issue
Yaxhveer Apr 3, 2024
dd36893
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 5, 2024
cae36df
fixing linter issue
Yaxhveer Apr 5, 2024
eebc436
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 8, 2024
2ef121b
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 10, 2024
9a8902f
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 10, 2024
57b261a
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 13, 2024
f17e436
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 15, 2024
02c575c
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 15, 2024
40e4936
Merge branch 'docker-start-cmd' of https://github.com/Yaxhveer/keploy…
Yaxhveer Apr 15, 2024
9c3f37a
updated changes
Yaxhveer Apr 15, 2024
9971bd1
Merge branch 'main' into docker-start-cmd
Yaxhveer Apr 19, 2024
a7cefef
Merge branch 'main' into docker-start-cmd
gouravkrosx Apr 20, 2024
cd2dc5d
refactored changes
Yaxhveer Apr 20, 2024
0bc1384
fixed linter issue
Yaxhveer Apr 20, 2024
4be8be6
fixed linter issue
Yaxhveer Apr 20, 2024
5c33062
Merge branch 'main' into docker-start-cmd
gouravkrosx Apr 20, 2024
bc07952
added parse command for docker start
Yaxhveer Apr 21, 2024
8c74e63
Merge branch 'docker-start-cmd' of https://github.com/Yaxhveer/keploy…
Yaxhveer Apr 21, 2024
7856a93
fixed linter issue
Yaxhveer Apr 21, 2024
f5fc4cb
Merge branch 'main' into docker-start-cmd
Yaxhveer May 13, 2024
57e1847
Merge branch 'main' into docker-start-cmd
gouravkrosx May 21, 2024
c6899ee
updated the changes
Yaxhveer May 21, 2024
1d334e2
Merge branch 'main' into docker-start-cmd
gouravkrosx May 21, 2024
fb2d240
added IsDockerKind function
Yaxhveer May 21, 2024
7c37c68
updated commandtype
Yaxhveer May 21, 2024
98d4c43
updated commandtype
Yaxhveer May 21, 2024
dcb8ee7
Merge branch 'main' into docker-start-cmd
gouravkrosx May 21, 2024
358cefa
corrected parse container
Yaxhveer May 21, 2024
0989f0a
Merge branch 'docker-start-cmd' of https://github.com/Yaxhveer/keploy…
Yaxhveer May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions pkg/core/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ func (a *App) Setup(_ context.Context) error {
}
a.docker = d

if (a.kind == utils.Docker || a.kind == utils.DockerCompose) && IsDetachMode(a.cmd) {
return fmt.Errorf("detach mode is not allowed in Keploy command")
if utils.IsDockerKind(a.kind) && isDetachMode(a.logger, a.cmd, a.kind) {
return fmt.Errorf("application could not be started in detached mode")
}

switch a.kind {
case utils.Docker:
case utils.DockerRun, utils.DockerStart:
err := a.SetupDocker()
if err != nil {
return err
Expand All @@ -100,7 +100,9 @@ func (a *App) ContainerIPv4Addr() string {

func (a *App) SetupDocker() error {
var err error
cont, net, err := ParseDockerCmd(a.cmd)

cont, net, err := ParseDockerCmd(a.cmd, a.kind, a.docker)

if err != nil {
utils.LogError(a.logger, err, "failed to parse container name from given docker command", zap.String("cmd", a.cmd))
return err
Expand All @@ -117,6 +119,16 @@ func (a *App) SetupDocker() error {
a.logger.Warn(fmt.Sprintf("given docker network:(%v) is different from parsed docker network:(%v)", a.containerNetwork, net))
}

if a.kind == utils.DockerStart {
running, err := a.docker.IsContainerRunning(a.container)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are you getting a.container value, you are not even parsing the docker start command to get the container name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not working for me in both cases. Whether the container is present locally or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User can't give container name in docker start command, they have to use containerName flag for that. So we don't have to parse the command here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keploy cmd would something be like keployV2 record -c "docker start -a MongoApp" --containerName MongoApp --networkName keploy-network

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why can't we just parse because you have to specify the container name when starting a stopped container? We should parse it by default and also let the user set the value just like how we are doing in the case of docker run command.

Copy link
Contributor Author

@Yaxhveer Yaxhveer Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be working on that then.

Copy link
Member

@gouravkrosx gouravkrosx May 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if the given container is different from the parsed container, we should provide the parsed container. i.e cont here. We are already logging a warning msg.

running, err := a.docker.IsContainerRunning(a.container)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected

if err != nil {
return err
}
if running {
return fmt.Errorf("docker container is already in running state")
}
}

//injecting appNetwork to keploy.
err = a.injectNetwork(a.containerNetwork)
if err != nil {
Expand Down Expand Up @@ -420,7 +432,7 @@ func (a *App) runDocker(ctx context.Context) models.AppError {
func (a *App) Run(ctx context.Context, inodeChan chan uint64) models.AppError {
a.inodeChan = inodeChan

if a.kind == utils.DockerCompose || a.kind == utils.Docker {
if utils.IsDockerKind(a.kind) {
return a.runDocker(ctx)
}
return a.run(ctx)
Expand All @@ -431,7 +443,7 @@ func (a *App) run(ctx context.Context) models.AppError {
userCmd := a.cmd
username := os.Getenv("SUDO_USER")

if utils.FindDockerCmd(a.cmd) == utils.Docker {
if utils.FindDockerCmd(a.cmd) == utils.DockerRun {
userCmd = utils.EnsureRmBeforeName(userCmd)
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/core/app/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,20 @@ func (idc *Impl) SetKeployNetwork(c *Compose) (*NetworkInfo, error) {
}
return networkInfo, nil
}

// IsContainerRunning check if the container is already running or not, required for docker start command.
func (idc *Impl) IsContainerRunning(containerName string) (bool, error) {

ctx, cancel := context.WithTimeout(context.Background(), idc.timeoutForDockerQuery)
defer cancel()

containerJSON, err := idc.ContainerInspect(ctx, containerName)
if err != nil {
return false, err
}

if containerJSON.State.Running {
return true, nil
}
return false, nil
}
2 changes: 2 additions & 0 deletions pkg/core/app/docker/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type Client interface {
SetKeployNetwork(c *Compose) (*NetworkInfo, error)
ReadComposeFile(filePath string) (*Compose, error)
WriteComposeFile(compose *Compose, path string) error

IsContainerRunning(containerName string) (bool, error)
}

type NetworkInfo struct {
Expand Down
44 changes: 41 additions & 3 deletions pkg/core/app/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import (
"os"
"path/filepath"
"regexp"
"slices"
"strconv"
"strings"
"syscall"

"go.keploy.io/server/v2/pkg/core/app/docker"
"go.keploy.io/server/v2/utils"
"go.uber.org/zap"
)

func findComposeFile() string {
Expand Down Expand Up @@ -47,9 +52,17 @@ func modifyDockerComposeCommand(appCmd, newComposeFile string) string {
return fmt.Sprintf("%s -f %s", appCmd, newComposeFile)
}

func ParseDockerCmd(cmd string) (string, string, error) {
func ParseDockerCmd(cmd string, kind utils.CmdType, idc docker.Client) (string, string, error) {

// Regular expression patterns
containerNamePattern := `--name\s+([^\s]+)`
var containerNamePattern string
switch kind {
case utils.DockerStart:
containerNamePattern = `start\s+(?:-[^\s]+\s+)*([^\s]*)`
default:
containerNamePattern = `--name\s+([^\s]+)`
}

networkNamePattern := `(--network|--net)\s+([^\s]+)`

// Extract container name
Expand All @@ -60,6 +73,17 @@ func ParseDockerCmd(cmd string) (string, string, error) {
}
containerName := containerNameMatches[1]

if kind == utils.DockerStart {
networks, err := idc.ExtractNetworksForContainer(containerName)
if err != nil {
return containerName, "", err
}
for i := range networks {
return containerName, i, nil
}
return containerName, "", fmt.Errorf("failed to parse network name")
}

// Extract network name
networkNameRegex := regexp.MustCompile(networkNamePattern)
networkNameMatches := networkNameRegex.FindStringSubmatch(cmd)
Expand All @@ -86,10 +110,24 @@ func getInode(pid int) (uint64, error) {
return i, nil
}

func IsDetachMode(command string) bool {
func isDetachMode(logger *zap.Logger, command string, kind utils.CmdType) bool {
args := strings.Fields(command)

if kind == utils.DockerStart {
flags := []string{"-a", "--attach", "-i", "--interactive"}

for _, arg := range args {
if slices.Contains(flags, arg) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be !slices.Contains(flags,arg), and you should log fmt.Errorf("docker start require --attach/-a or --interactive/-i flag") here and return true that it is in detachMode.

Copy link
Contributor Author

@Yaxhveer Yaxhveer Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I made this error while refactoring changes. Refactored

return false
}
}
utils.LogError(logger, fmt.Errorf("docker start require --attach/-a or --interactive/-i flag"), "failed to start command")
return true
}

for _, arg := range args {
if arg == "-d" || arg == "--detach" {
utils.LogError(logger, fmt.Errorf("detach mode is not allowed in Keploy command"), "failed to start command")
return true
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (c *Core) Hook(ctx context.Context, id uint64, opts models.HookOptions) err
isDocker := false
appKind := a.Kind(ctx)
//check if the app is docker/docker-compose or native
if appKind == utils.Docker || appKind == utils.DockerCompose {
if utils.IsDockerKind(appKind) {
isDocker = true
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/service/record/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ func (r *Recorder) ReRecord(ctx context.Context, appID uint64) error {

}
cmdType := utils.FindDockerCmd(r.config.Command)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also

if cmdType == utils.Docker || cmdType == utils.DockerCompose {
if utils.IsDockerKind(cmdType) {
host = r.config.ContainerName
}

Expand All @@ -360,7 +360,7 @@ func (r *Recorder) ReRecord(ctx context.Context, appID uint64) error {

allTestCasesRecorded := true
for _, tc := range tcs {
if cmdType == utils.Docker || cmdType == utils.DockerCompose {
if utils.IsDockerKind(cmdType) {

userIP, err := r.instrumentation.GetContainerIP(ctx, appID)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/service/replay/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s
return models.TestSetStatusUserAbort, context.Canceled
}

cmdType := utils.FindDockerCmd(r.config.Command)
cmdType := utils.CmdType(r.config.CommandType)
var userIP string
if cmdType == utils.Docker || cmdType == utils.DockerCompose {
if utils.IsDockerKind(cmdType) {
userIP, err = r.instrumentation.GetContainerIP(ctx, appID)
if err != nil {
return models.TestSetStatusFailed, err
Expand Down Expand Up @@ -413,7 +413,7 @@ func (r *Replayer) RunTestSet(ctx context.Context, testSetID string, testRunID s

started := time.Now().UTC()

if cmdType == utils.Docker || cmdType == utils.DockerCompose {
if utils.IsDockerKind(cmdType) {

testCase.HTTPReq.URL, err = utils.ReplaceHostToIP(testCase.HTTPReq.URL, userIP)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion utils/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func StartInDocker(ctx context.Context, logger *zap.Logger, conf *config.Config)
// If it does, then we would run the docker version of keploy and
// pass the command and control to it.
cmdType := FindDockerCmd(conf.Command)
if conf.InDocker || !(cmdType == Docker || cmdType == DockerCompose) {
if conf.InDocker || !(IsDockerKind(cmdType)) {
return nil
}
// pass the all the commands and args to the docker version of Keploy
Expand Down
22 changes: 17 additions & 5 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ func FindDockerCmd(cmd string) CmdType {
cmdLower := strings.TrimSpace(strings.ToLower(cmd))

// Define patterns for Docker and Docker Compose
dockerPatterns := []string{"docker", "sudo docker"}
dockerRunPatterns := []string{"docker run", "sudo docker run"}
dockerStartPatterns := []string{"docker start", "sudo docker start"}
dockerComposePatterns := []string{"docker-compose", "sudo docker-compose", "docker compose", "sudo docker compose"}

// Check for Docker Compose command patterns and file extensions
Expand All @@ -342,10 +343,16 @@ func FindDockerCmd(cmd string) CmdType {
return DockerCompose
}
}
// Check for Docker command patterns
for _, pattern := range dockerPatterns {
// Check for Docker start command patterns
for _, pattern := range dockerStartPatterns {
if strings.HasPrefix(cmdLower, pattern) {
return Docker
return DockerStart
}
}
// Check for Docker run command patterns
for _, pattern := range dockerRunPatterns {
if strings.HasPrefix(cmdLower, pattern) {
return DockerRun
}
}
return Native
Expand All @@ -355,7 +362,8 @@ type CmdType string

// CmdType constants
const (
Docker CmdType = "docker"
DockerRun CmdType = "docker-run"
DockerStart CmdType = "docker-start"
DockerCompose CmdType = "docker-compose"
Native CmdType = "native"
)
Expand Down Expand Up @@ -712,3 +720,7 @@ func EnsureRmBeforeName(cmd string) string {

return strings.Join(parts, " ")
}

func IsDockerKind(kind CmdType) bool {
return (kind == DockerRun || kind == DockerStart || kind == DockerCompose)
}
Loading