Skip to content

Commit

Permalink
feat: Add a sub-command for docker - container (#27)
Browse files Browse the repository at this point in the history
* Add command to stop with all flag
* Add command to rename
* Add command to delete with all flag
  • Loading branch information
Pradumnasaraf authored Jul 13, 2023
1 parent 872a4b8 commit d7d1e5b
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 14 deletions.
23 changes: 23 additions & 0 deletions cmd/docker/container/container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package container

import (
"log"

"github.com/spf13/cobra"
)

var (
runnnigContainer = []string{}
)

// containerCmd represents the container command
var ContainerCmd = &cobra.Command{
Use: "container [command] [flags]",
Short: "Container related commands",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
if err != nil {
log.Fatal(err)
}
},
}
108 changes: 108 additions & 0 deletions cmd/docker/container/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package container

import (
"fmt"
"log"
"strings"

"github.com/docker/docker/api/types"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

var (
deleteAll bool
)

// deleteContainerCmd represents the delete command
var deleteContainerCmd = &cobra.Command{
Use: "delete",
Short: "Delete a running container",
Run: func(cmd *cobra.Command, args []string) {
deleteContainer()
},
}

func deleteContainer() {
ctx, cli := dockerClient()
containerList := runnnigContainerList(cli, ctx)

if len(containerList) == 0 {
fmt.Println("No container running")
return
}

// If the flag --all is set, delete all containers
if deleteAll {

prompt := promptui.Select{
Label: "Are you sure you want to delete all containers?",
Items: []string{"Yes", "No"},
}

_, option, err := prompt.Run()
checkErr(err)

if option == "Yes" {

for _, container := range containerList {
fmt.Printf("Deleting container %s (%s)...\n", container.Names[0][1:], container.ID[:6])
err = cli.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{Force: true})
checkErr(err)
}

fmt.Println("Deleted all containers")
return
} else {
fmt.Println("Containers not removed")
return
}

}

// If the flag --all is not set, delete a specific container
for _, container := range containerList {
runnnigContainer = append(runnnigContainer, container.Names[0][1:]+" - "+container.ID[:6])

}

prompt := promptui.Select{
Label: "Select a containe to delete",
Items: runnnigContainer,
}

_, conSelection, err := prompt.Run()
checkErr(err)

prompt = promptui.Select{
Label: "Are you sure you want to delete " + conSelection + " ?",
Items: []string{"Yes", "No"},
}

_, option, err := prompt.Run()
checkErr(err)

if option == "Yes" {
slpit := strings.Split(conSelection, " - ")

err = cli.ContainerRemove(ctx, slpit[1], types.ContainerRemoveOptions{Force: true})
checkErr(err)

fmt.Printf("Container %s deleted successfully\n", slpit[0])
} else {
fmt.Println("Container not removed")
return
}

}

func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
}

func init() {
ContainerCmd.AddCommand(deleteContainerCmd)
deleteContainerCmd.Flags().BoolVarP(&deleteAll, "all", "a", false, "Delete all containers")
}
27 changes: 27 additions & 0 deletions cmd/docker/container/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package container

import (
"context"

"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)

// dockerClient returns a docker client
func dockerClient() (context.Context, *client.Client) {
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
checkErr(err)
defer cli.Close()

return ctx, cli
}

// runnnigContainerList returns a list of running containers
func runnnigContainerList(cli *client.Client, ctx context.Context) []types.Container {

containerList, err := cli.ContainerList(ctx, types.ContainerListOptions{})
checkErr(err)
return containerList

}
72 changes: 72 additions & 0 deletions cmd/docker/container/rename.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package container

import (
"bufio"
"fmt"
"os"
"strings"

"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

// renameCmd represents the rename command
var renameCmd = &cobra.Command{
Use: "rename",
Short: "Rename a container",
Run: func(cmd *cobra.Command, args []string) {
renameContainer()
},
}

func renameContainer() {
ctx, cli := dockerClient()
containerList := runnnigContainerList(cli, ctx)

if len(containerList) == 0 {
fmt.Println("No container running")
return
}

for _, container := range containerList {
runnnigContainer = append(runnnigContainer, container.Names[0][1:]+" - "+container.ID[:6])

}

// Prompt the user to select a container
fmt.Println("CONTAINER NAME - CONTAINER ID")
prompt := promptui.Select{
Label: "Select a container to rename",
Items: runnnigContainer,
}

_, result, err := prompt.Run()
checkErr(err)

// Get new name from the command line
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Enter new name: ")
scanner.Scan()
newName := scanner.Text()

newName = strings.TrimSpace(newName)

if newName == "" {
fmt.Println("New name cannot be empty")
return
}

slpit := strings.Split(result, " - ")

// Rename the container
err = cli.ContainerRename(ctx, slpit[0], newName)
checkErr(err)

fmt.Printf("Container %s renamed to %s\n", slpit[0], newName)

}

func init() {
ContainerCmd.AddCommand(renameCmd)

}
119 changes: 119 additions & 0 deletions cmd/docker/container/stop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package container

import (
"fmt"
"log"
"strings"

containertypes "github.com/docker/docker/api/types/container"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
)

var (
stopall bool
)

// deleteallcontainerCmd represents the deleteallcontainer command
var stopAllContainersCmd = &cobra.Command{
Use: "stop",
Short: "Stop a running container",
Run: func(cmd *cobra.Command, args []string) {
stopContainers()
},
}

func stopContainers() {
ctx, cli := dockerClient()
containerList := runnnigContainerList(cli, ctx)

if len(containerList) == 0 {
fmt.Println("No container running")
return
}

// If the flag --all is set, delete all containers
if stopall {

prompt := promptui.Select{
Label: "Are you sure you want to stop all containers?",
Items: []string{"Yes", "No"},
}

_, option, err := prompt.Run()

if err != nil {
log.Fatal(err)
}

if option == "Yes" {

for _, container := range containerList {
fmt.Printf("Stopping container %s (%s)...\n", container.Names[0][1:], container.ID[:6])
noWaitTimeout := 5 // to not wait for the container to exit gracefully
err := cli.ContainerStop(ctx, container.ID, containertypes.StopOptions{Timeout: &noWaitTimeout})
if err != nil {
log.Fatal(err)
}

}
fmt.Println("Stopped all containers")
return

} else {
fmt.Println("Aborted")
return
}

}

// If the flag --all is not set, delete a specific container
for _, container := range containerList {
runnnigContainer = append(runnnigContainer, container.Names[0][1:]+" - "+container.ID[:6])
}

// Prompt the user to select a container
fmt.Println("CONTAINER NAME - CONTAINER ID")
prompt := promptui.Select{
Label: "Select a container to stop",
Items: runnnigContainer,
}

_, result, err := prompt.Run()
if err != nil {
log.Fatal(err)
}

prompt = promptui.Select{
Label: "Are you sure you want to stop " + result + "?",
Items: []string{"Yes", "No"},
}

_, option, err := prompt.Run()
if err != nil {
log.Fatal(err)
}

if option == "Yes" {

split := strings.Split(result, " - ")

noWaitTimeout := 5 // to not wait for the container to exit gracefully
err := cli.ContainerStop(ctx, split[1], containertypes.StopOptions{Timeout: &noWaitTimeout})
if err != nil {
log.Fatal(err)
}

fmt.Println("Container + " + split[0] + " stopped successfully")

}

}

func init() {

ContainerCmd.AddCommand(stopAllContainersCmd)

stopAllContainersCmd.Flags().BoolVarP(&stopall, "all", "a", false, "Delete all containers")

}
2 changes: 0 additions & 2 deletions cmd/docker/docker-file.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ func createDockerfile(lang string) {
}

func init() {
DockerCmd.AddCommand(dockerfileCmd)

dockerfileCmd.Flags().StringVarP(&language, "lang", "l", "", "Programming language to generate Dockerfile for.")
err := dockerfileCmd.MarkFlagRequired("lang")
checkNilErr(err)
Expand Down
6 changes: 6 additions & 0 deletions cmd/docker/docker.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package docker

import (
"github.com/Pradumnasaraf/candy/cmd/docker/container"
"github.com/spf13/cobra"
)

Expand All @@ -13,3 +14,8 @@ var DockerCmd = &cobra.Command{
checkNilErr(err)
},
}

func init() {
DockerCmd.AddCommand(container.ContainerCmd)
DockerCmd.AddCommand(dockerfileCmd)
}
2 changes: 0 additions & 2 deletions cmd/kubernetes/kubernetes-manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ func createManifestFile(filename string, obj string) {
}

func init() {
KubernetesCmd.AddCommand(kubernetesManifestCmd)

kubernetesManifestCmd.Flags().StringVarP(&k8Obj, "obj", "o", "", "Kubernetes object to generate manifest for.")
err := kubernetesManifestCmd.MarkFlagRequired("obj")
checkNilErr(err)
Expand Down
4 changes: 4 additions & 0 deletions cmd/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ var KubernetesCmd = &cobra.Command{
checkNilErr(err)
},
}

func init() {
KubernetesCmd.AddCommand(kubernetesManifestCmd)
}
Loading

0 comments on commit d7d1e5b

Please sign in to comment.