Skip to content
This repository has been archived by the owner on Mar 17, 2023. It is now read-only.

add uninstall subcommand #5

Merged
merged 1 commit into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions package_list.hcl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package "python" {
image="packageless/python"
base_dir="./python/"

volume {
path="./python/packages/"
mount="/usr/local/lib/python3.9/site-packages/"
Expand Down
37 changes: 27 additions & 10 deletions subcommands/install_sc.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,21 @@ func (ic *InstallCommand) Run() error {

fmt.Println("Creating package directories")

//Create the base directory for the package
err = MakeDir(pack.BaseDir)

if err != nil {
return err
}

//Check the volumes and create the directories for them if they don't already exist
for _, vol := range pack.Volumes {
//Make sure that a path is given. If not we already assume that the working directory will be mounted
if vol.Path != "" {
if _, err := os.Stat(vol.Path); err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(vol.Path, 0755)

if err != nil {
return err
}
} else {
return err
}
err = MakeDir(vol.Path)

if err != nil {
return err
}
}
}
Expand Down Expand Up @@ -155,3 +156,19 @@ func (ic *InstallCommand) Run() error {

return nil
}

//MakeDir makes a directory if it doesnt exist given the path
func MakeDir(path string) error {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(path, 0755)

if err != nil {
return err
}
} else {
return err
}
}
return nil
}
1 change: 1 addition & 0 deletions subcommands/subcommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func SubCommand(args []string) error {
NewInstallCommand(),
NewUpgradeCommand(),
NewRunCommand(),
NewUninstallCommand(),
}

subcommand := os.Args[1]
Expand Down
148 changes: 148 additions & 0 deletions subcommands/uninstall_sc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package subcommands

import (
"errors"
"flag"
"fmt"
"os"

"github.com/everettraven/packageless/utils"
)

//Uninstall Sub-Command Object
type UninstallCommand struct {
//FlagSet so that we can create a custom flag
fs *flag.FlagSet

//String for the name of the package to Uninstall
name string
}

//Instantiation method for a new UninstallCommand
func NewUninstallCommand() *UninstallCommand {
//Create a new UninstallCommand and set the FlagSet
uc := &UninstallCommand{
fs: flag.NewFlagSet("uninstall", flag.ContinueOnError),
}

return uc
}

//Name - Gets the name of the Sub-Command
func (uc *UninstallCommand) Name() string {
return uc.fs.Name()
}

//Init - Parses and Populates values of the Uninstall subcommand
func (uc *UninstallCommand) Init(args []string) error {

if len(args) <= 0 {
return errors.New("No package name was found. You must include the name of the package you wish to uninstall.")
}

uc.name = args[0]

return nil
}

//Uninstall - Uninstalls the Uninstall subcommand
func (uc *UninstallCommand) Run() error {
//Create variables to use later
var found bool
var pack utils.Package

//Default location of the package list
packageList := "./package_list.hcl"

//Parse the package list
parseOut, err := utils.Parse(packageList, utils.PackageHCLUtil{})

//Check for errors
if err != nil {
return err
}

packages := parseOut.(utils.PackageHCLUtil)

//Check for errors
if err != nil {
return err
}

//Look for the package we want in the package list
for _, packs := range packages.Packages {
//If we find it, set some variables and break
if packs.Name == uc.name {
found = true
pack = packs
break
}
}

//Make sure we have found the package in the package list
if !found {
return errors.New("Could not find package " + uc.name + " in the package list")
}

//Check if the corresponding package image is already Uninstalled
imgExist, err := utils.ImageExists(pack.Image)

//Check for errors
if err != nil {
return err
}

//If the image doesn't exist it can't be uninstalled
if !imgExist {
return errors.New("Package " + pack.Name + " is not installed.")
}

fmt.Println("Removing package", pack.Name)

//Check for the directories that correspond to this packages volumes
fmt.Println("Removing package directories")

//Check the volumes and remove the directories if they exist
for _, vol := range pack.Volumes {
//Make sure that a path is given.
if vol.Path != "" {
err = RemoveDir(vol.Path)

if err != nil {
return err
}
}
}

//Remove the base directory for the package
err = RemoveDir(pack.BaseDir)

if err != nil {
return err
}

//Remove the image
err = utils.RemoveImage(pack.Image)

//Check for errors
if err != nil {
return err
}

return nil
}

//RemoveDir removes a given directory if it exists
func RemoveDir(path string) error {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return nil
} else {
return err
}
} else {
err = os.RemoveAll(path)
}

return nil
}
45 changes: 43 additions & 2 deletions utils/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func ImageExists(imageID string) (bool, error) {

//Check for errors
if err != nil {
return false, nil
return false, err
}

//Create a context and get a list of images on the system
Expand All @@ -62,7 +62,7 @@ func ImageExists(imageID string) (bool, error) {

//Check for errors
if err != nil {
return false, nil
return false, err
}

//Loop through all the images and check if a match is found
Expand Down Expand Up @@ -279,3 +279,44 @@ func RunContainer(image string, ports []string, volumes []string, containerName
return nil

}

//RemoveImage removes the image with the given name from local Docker
func RemoveImage(image string) error {
//Create the client
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())

//Check for errors
if err != nil {
return err
}

//Create the context and search for the image in the list of images
ctx := context.Background()

images, err := cli.ImageList(ctx, types.ImageListOptions{})

//Check for errors
if err != nil {
return err
}

//Create a variable to hold the ID of the image we want to remove
var imageID string

//Loop through all the images and check if a match is found
for _, img := range images {
if strings.Split(img.RepoTags[0], ":")[0] == image {
imageID = img.ID
}
}

//Remove the image
_, err = cli.ImageRemove(ctx, imageID, types.ImageRemoveOptions{Force: true})

//Check for errors
if err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions utils/hcl_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Volume struct {
type Package struct {
Name string `hcl:"name,label"`
Image string `hcl:"image,attr"`
BaseDir string `hcl:"base_dir,attr"`
Volumes []Volume `hcl:"volume,block"`
Copies []*Copy `hcl:"copy,block"`
Port string `hcl:"port,optional"`
Expand Down