Skip to content

Commit 2a694ab

Browse files
committed
fixes #108 feat: Add support for start and stop command
Signed-off-by: Harsh4902 <harshparmar4902@gmail.com>
1 parent b75ad1f commit 2a694ab

5 files changed

Lines changed: 189 additions & 16 deletions

File tree

cmd/start.go

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,23 @@ package cmd
22

33
import (
44
"context"
5+
"fmt"
56
"io"
7+
"log"
68
"os"
79

810
"github.com/docker/docker/api/types/container"
911
"github.com/docker/docker/api/types/image"
1012
"github.com/docker/docker/client"
1113
"github.com/docker/go-connections/nat"
14+
"github.com/microcks/microcks-cli/pkg/config"
1215
"github.com/spf13/cobra"
1316
)
1417

1518
func NewStartCommand() *cobra.Command {
1619
var (
17-
hostIP string
20+
hostIP string = "0.0.0.0"
21+
name string
1822
hostPort string
1923
imageName string
2024
autoRemove bool
@@ -28,22 +32,62 @@ microcks start
2832
# Define your port (by default 8585)
2933
microcks start --port [Port you want]`,
3034
Run: func(cmd *cobra.Command, args []string) {
31-
startContainer(imageName, hostIP, hostPort, autoRemove)
35+
cfg, err := config.EnsureConfig(config.ConfigPath)
36+
37+
if err != nil {
38+
log.Fatalf("Error loading config: %v", err)
39+
}
40+
41+
if cfg.Instance.Status == "Running" {
42+
fmt.Println("Microcks is already running.")
43+
return
44+
}
45+
46+
if cfg.Instance.Status == "Stopped" {
47+
if err := startContainer(cfg.Instance.ContainerID); err != nil {
48+
fmt.Errorf("failed to start container: %v", err)
49+
}
50+
fmt.Println("Microcks started successfully...")
51+
return
52+
}
53+
54+
cfg.Instance.Name = name
55+
cfg.Instance.Image = imageName
56+
cfg.Instance.Port = hostPort
57+
cfg.Instance.AutoRemove = autoRemove
58+
59+
containerID, err := createContainer(cfg, hostIP)
60+
61+
if err != nil {
62+
log.Fatalf("Failed to create a container: %v", err)
63+
}
64+
cfg.Instance.ContainerID = containerID
65+
66+
if err := startContainer(cfg.Instance.ContainerID); err != nil {
67+
fmt.Errorf("failed to start container: %v", err)
68+
}
69+
70+
err = config.SaveConfig(config.ConfigPath, cfg)
71+
72+
if err != nil {
73+
log.Fatalf("Failed to save config: %v", err)
74+
}
75+
76+
fmt.Printf("Microcks started successfully...")
3277
},
3378
}
34-
35-
startCmd.Flags().StringVar(&hostIP, "IP", "localhost", "")
79+
startCmd.Flags().StringVar(&name, "name", "microcks", "name for you microcks instance")
3680
startCmd.Flags().StringVar(&hostPort, "port", "8585", "")
3781
startCmd.Flags().StringVar(&imageName, "image", "quay.io/microcks/microcks-uber:latest-native", "image which will be used to create a container")
3882
startCmd.Flags().BoolVar(&autoRemove, "rm", false, "mimic of '--rm' flag of dokcer to automatically remove the container when it exits")
3983
return startCmd
4084
}
4185

42-
func startContainer(imageName string, hostIP string, hostPort string, autoRemove bool) {
86+
func createContainer(cfg *config.Config, hostIP string) (string, error) {
4387
ctx := context.Background()
4488
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
4589
if err != nil {
46-
panic(err)
90+
return "", err
4791
}
4892
defer cli.Close()
4993

@@ -53,34 +97,47 @@ func startContainer(imageName string, hostIP string, hostPort string, autoRemove
5397
exposedPort: []nat.PortBinding{
5498
{
5599
HostIP: hostIP,
56-
HostPort: hostPort,
100+
HostPort: cfg.Instance.Port,
57101
},
58102
},
59103
}
60104

61-
out, err := cli.ImagePull(ctx, imageName, image.PullOptions{})
105+
out, err := cli.ImagePull(ctx, cfg.Instance.Image, image.PullOptions{})
62106
if err != nil {
63-
panic(err)
107+
return "", err
64108
}
65109
defer out.Close()
66110
io.Copy(os.Stdout, out)
67111

68112
resp, err := cli.ContainerCreate(
69113
ctx,
70114
&container.Config{
71-
Image: imageName,
115+
Image: cfg.Instance.Image,
72116
ExposedPorts: nat.PortSet{exposedPort: struct{}{}},
73117
},
74118
&container.HostConfig{
75119
PortBindings: portBindings,
76-
AutoRemove: autoRemove,
77-
}, nil, nil, "")
120+
AutoRemove: cfg.Instance.AutoRemove,
121+
}, nil, nil, cfg.Instance.Name)
78122

79123
if err != nil {
80-
panic(err)
124+
return "", err
81125
}
82126

83-
if err := cli.ContainerStart(ctx, resp.ID, container.StartOptions{}); err != nil {
127+
return resp.ID, nil
128+
}
129+
130+
func startContainer(cotainerID string) error {
131+
ctx := context.Background()
132+
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
133+
if err != nil {
134+
return err
135+
}
136+
defer cli.Close()
137+
138+
if err := cli.ContainerStart(ctx, cotainerID, container.StartOptions{}); err != nil {
84139
panic(err)
85140
}
141+
142+
return nil
86143
}

cmd/stop.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"log"
67

78
containertypes "github.com/docker/docker/api/types/container"
89
"github.com/docker/docker/client"
10+
"github.com/microcks/microcks-cli/pkg/config"
911
"github.com/spf13/cobra"
1012
)
1113

@@ -16,7 +18,34 @@ func NewStopCommand() *cobra.Command {
1618
Short: "stop microcks instance",
1719
Long: "stop microcks instance",
1820
Run: func(cmd *cobra.Command, args []string) {
19-
stopContainer(args[0])
21+
22+
cfg, err := config.LoadConfig(config.ConfigPath)
23+
if err != nil {
24+
log.Fatalf("Failed to load config: %v", err)
25+
}
26+
27+
stopContainer(cfg.Instance.ContainerID)
28+
29+
cfg.Instance.Status = "Stopped"
30+
31+
if cfg.Instance.AutoRemove {
32+
cfg.Instance = struct {
33+
Name string "yaml:\"name\""
34+
Image string "yaml:\"image\""
35+
Status string "yaml:\"status\""
36+
Port string "yaml:\"port\""
37+
ContainerID string "yaml:\"containerID\""
38+
AutoRemove bool "yaml:\"autoRemove\""
39+
}{}
40+
}
41+
42+
err = config.SaveConfig(config.ConfigPath, cfg)
43+
44+
if err != nil {
45+
log.Fatalf("Failed to save config: %v", err)
46+
}
47+
48+
fmt.Println("Microcks stopped successfully...")
2049
},
2150
}
2251

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ toolchain go1.24.1
66

77
require (
88
github.com/docker/docker v28.0.4+incompatible
9+
github.com/docker/go-connections v0.5.0
910
github.com/spf13/cobra v1.9.1
11+
gopkg.in/yaml.v2 v2.4.0
1012
)
1113

1214
require (
1315
github.com/Microsoft/go-winio v0.4.14 // indirect
1416
github.com/containerd/log v0.1.0 // indirect
1517
github.com/distribution/reference v0.6.0 // indirect
16-
github.com/docker/go-connections v0.5.0 // indirect
1718
github.com/docker/go-units v0.5.0 // indirect
1819
github.com/felixge/httpsnoop v1.0.4 // indirect
1920
github.com/go-logr/logr v1.4.2 // indirect

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
3737
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
3838
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
3939
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
40+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
41+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
42+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
43+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
4044
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
4145
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
4246
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
@@ -52,6 +56,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
5256
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
5357
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5458
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
59+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
60+
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
5561
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
5662
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
5763
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -130,6 +136,10 @@ google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd
130136
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
131137
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
132138
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
139+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
140+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
141+
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
142+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
133143
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
134144
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
135145
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=

pkg/config/config.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import (
2222
"io/ioutil"
2323
"net/http"
2424
"net/http/httputil"
25+
"os"
26+
"path/filepath"
2527
strings "strings"
28+
29+
"gopkg.in/yaml.v2"
2630
)
2731

2832
var (
@@ -32,8 +36,21 @@ var (
3236
CaCertPaths string
3337
// Verbose represents a debug flag for HTTP Exchanges
3438
Verbose bool = false
39+
40+
ConfigPath = filepath.Join(os.Getenv("HOME"), ".microcks-cli", "config.yaml")
3541
)
3642

43+
type Config struct {
44+
Instance struct {
45+
Name string `yaml:"name"`
46+
Image string `yaml:"image"`
47+
Status string `yaml:"status"`
48+
Port string `yaml:"port"`
49+
ContainerID string `yaml:"containerID"`
50+
AutoRemove bool `yaml:"autoRemove"`
51+
} `yaml:"instance"`
52+
}
53+
3754
// CreateTLSConfig wraps the creation of tls.Config object for use with HTTP Client for example.
3855
func CreateTLSConfig() *tls.Config {
3956
tlsConfig := &tls.Config{}
@@ -91,3 +108,62 @@ func DumpResponseIfRequired(name string, resp *http.Response, body bool) {
91108
}
92109
}
93110
}
111+
112+
//Functions related to configs
113+
114+
func defaultConfig() *Config {
115+
return &Config{
116+
Instance: struct {
117+
Name string `yaml:"name"`
118+
Image string `yaml:"image"`
119+
Status string `yaml:"status"`
120+
Port string `yaml:"port"`
121+
ContainerID string `yaml:"containerID"`
122+
AutoRemove bool `yaml:"autoRemove"`
123+
}{
124+
Name: "microcks",
125+
Image: "",
126+
Status: "",
127+
Port: "",
128+
AutoRemove: false,
129+
},
130+
}
131+
}
132+
133+
func EnsureConfig(path string) (*Config, error) {
134+
if _, err := os.Stat(path); os.IsNotExist(err) {
135+
fmt.Println("Config not found. Initializing default config.")
136+
cfg := defaultConfig()
137+
err := SaveConfig(path, cfg)
138+
if err != nil {
139+
return nil, fmt.Errorf("failed to create default config: %w", err)
140+
}
141+
return cfg, nil
142+
}
143+
return LoadConfig(path)
144+
}
145+
146+
func LoadConfig(path string) (*Config, error) {
147+
data, err := os.ReadFile(path)
148+
if err != nil {
149+
return nil, err
150+
}
151+
var cfg Config
152+
err = yaml.Unmarshal(data, &cfg)
153+
if err != nil {
154+
return nil, err
155+
}
156+
return &cfg, nil
157+
}
158+
159+
func SaveConfig(path string, cfg *Config) error {
160+
err := os.MkdirAll(filepath.Dir(path), 0755)
161+
if err != nil {
162+
return err
163+
}
164+
data, err := yaml.Marshal(cfg)
165+
if err != nil {
166+
return err
167+
}
168+
return os.WriteFile(path, data, 0644)
169+
}

0 commit comments

Comments
 (0)