diff --git a/Makefile b/Makefile index d613e40..ebeb410 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: build test build: - go build -o "build/foreman-builder" + go build -o ./build/ test: go test ./... \ No newline at end of file diff --git a/README.md b/README.md index 17d6ef0..aa23c33 100644 --- a/README.md +++ b/README.md @@ -28,5 +28,11 @@ Will display a list of containers that `foreman-builder` has created. foreman-builder list ``` +**Delete container** +Delete a container via name. Note you only be allowed to delete containers created with `foreman-builder`. +```bash +foreman-builder delete +``` + diff --git a/foreman-builder/cmd/delete.go b/foreman-builder/cmd/delete.go new file mode 100644 index 0000000..a57a4db --- /dev/null +++ b/foreman-builder/cmd/delete.go @@ -0,0 +1,67 @@ +package cmd + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "slices" + + foremanbuilder "github.com/aidenfine/foreman-builder/foreman-builder" + "github.com/spf13/cobra" +) + +var deleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete container via name.", + Run: func(cmd *cobra.Command, args []string) { + if len(args) < 1 || len(args) > 1 { + log.Fatalf("Arg Error: Got %d args, when 1 was expected \n", len(args)) + os.Exit(1) + } + containerName := args[0] + runDelete(containerName) + + }, +} + +func runDelete(containerName string) { + + // check if item actually exists first AND foreman-builder created it + home, err := os.UserHomeDir() + if err != nil { + log.Panicf("Failed to get home directory: %v\n", err) + } + dotFolderPath := filepath.Join(home, ".foreman-builder") + containersPath := filepath.Join(dotFolderPath, "containers") + containers, err := foremanbuilder.GetAllLines(containersPath) + + if !slices.Contains(containers, containerName) { + log.Fatalf("%s was not created with foreman-builder, foreman-builder will not delete it", containerName) + os.Exit(1) + + } + containerInfo, err := foremanbuilder.ContainerInfo(containerName) + if err != nil { + log.Fatalf("Failed to get container info %v \n", err) + os.Exit(1) + } + if containerInfo.State == "running" { + var input string + for input != "y" && input != "n" { + fmt.Println("Container is currently running! \n Do you want to stop the container and delete? \n [y/n]") + fmt.Scanln(&input) + } + if input == "n" { + os.Exit(1) + } + // stop container + exec.Command("orbctl", "stop", containerName) + + } + exec.Command("orbctl", "delete", containerName, "-f") + + // delete container in dotfile + foremanbuilder.DeleteLineInFile(containersPath, containerName) +} diff --git a/foreman-builder/cmd/root.go b/foreman-builder/cmd/root.go index 3273f98..f490e45 100644 --- a/foreman-builder/cmd/root.go +++ b/foreman-builder/cmd/root.go @@ -23,5 +23,6 @@ func Execute() { func init() { rootCmd.AddCommand(createCmd) rootCmd.AddCommand(listCmd) + rootCmd.AddCommand(deleteCmd) // rootCmd.AddCommand(syncCmd) } diff --git a/foreman-builder/cmd/sync.go b/foreman-builder/cmd/sync.go index 7958f96..643a996 100644 --- a/foreman-builder/cmd/sync.go +++ b/foreman-builder/cmd/sync.go @@ -24,7 +24,7 @@ import ( // } func SyncContainers() { - orbContainers, err := foremanbuilder.GetOrbstackContainers() + orbContainers, err := foremanbuilder.GetOrbStackContainers() if err != nil { fmt.Printf("Error: %v\n", err) } diff --git a/foreman-builder/orbstack.go b/foreman-builder/orbstack.go index a3b4ab4..d06a132 100644 --- a/foreman-builder/orbstack.go +++ b/foreman-builder/orbstack.go @@ -15,13 +15,21 @@ type OrbInstance struct { IP string `json:"ip"` } +type ContainerInfoStruct struct { + Id string `json:"id"` + Name string `json:"name"` + State string `json:"state"` +} + +var execCommand = exec.Command + func IsOrbStackRunning() bool { - cmd := exec.Command("orbctl", "status") + cmd := execCommand("orbctl", "status") return cmd.Run() == nil } -func GetOrbstackContainers() ([]string, error) { - cmd := exec.Command("orbctl", "list", "--format", "json") +func GetOrbStackContainers() ([]string, error) { + cmd := execCommand("orbctl", "list", "--format", "json") output, err := cmd.Output() if err != nil { @@ -40,3 +48,18 @@ func GetOrbstackContainers() ([]string, error) { return names, nil } + +func ContainerInfo(containerName string) (ContainerInfoStruct, error) { + cmd := execCommand("orbctl", "info", containerName, "--format", "json") + output, err := cmd.Output() + if err != nil { + return ContainerInfoStruct{}, err + } + + var containerInfo ContainerInfoStruct + + if err := json.Unmarshal(output, &containerInfo); err != nil { + return ContainerInfoStruct{}, err + } + return containerInfo, nil +}