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

Commit

Permalink
Merge pull request #3 from everettraven/feature/upgrade_subcommand
Browse files Browse the repository at this point in the history
upgrade command and config file
  • Loading branch information
everettraven authored May 24, 2021
2 parents 0f35bbe + 773ae3b commit 82785d7
Show file tree
Hide file tree
Showing 5 changed files with 333 additions and 17 deletions.
3 changes: 3 additions & 0 deletions config.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
base_dir="./"
start_port=3000
port_increment=1
9 changes: 8 additions & 1 deletion subcommands/install_sc.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func (ic *InstallCommand) Name() string {

//Init - Parses and Populates values of the Install subcommand
func (ic *InstallCommand) 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 install.")
}

ic.name = args[0]
return nil
}
Expand All @@ -49,7 +54,9 @@ func (ic *InstallCommand) Run() error {
packageList := "./package_list.hcl"

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

packages := parseOut.(utils.PackageHCLUtil)

//Check for errors
if err != nil {
Expand Down
8 changes: 7 additions & 1 deletion subcommands/subcommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ func SubCommand(args []string) error {

cmds := []Runner{
NewInstallCommand(),
NewUpgradeCommand(),
}

subcommand := os.Args[1]

for _, cmd := range cmds {
if cmd.Name() == subcommand {
cmd.Init(os.Args[2:])
err := cmd.Init(os.Args[2:])

if err != nil {
return err
}

return cmd.Run()
}
}
Expand Down
264 changes: 264 additions & 0 deletions subcommands/upgrade_sc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package subcommands

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

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

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

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

//Instantiation method for a new InstallCommand
func NewUpgradeCommand() *UpgradeCommand {
//Create a new InstallCommand and set the FlagSet
ic := &UpgradeCommand{
fs: flag.NewFlagSet("upgrade", flag.ContinueOnError),
}

return ic
}

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

//Init - Parses and Populates values of the Install subcommand
func (ic *UpgradeCommand) Init(args []string) error {
if len(args) <= 0 {
fmt.Println("No package specified, upgrading all currently installed packages.")
} else {
ic.name = args[0]
fmt.Println("Upgrading", ic.name)
}
return nil
}

//Run - Runs the install subcommand
func (ic *UpgradeCommand) 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{})

packages := parseOut.(utils.PackageHCLUtil)

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

if ic.name != "" {
//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 == ic.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 " + ic.name + " in the package list")
}

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

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

//If the image exists the package is already installed
if !imgExist {
return errors.New("Package: " + pack.Name + " is not installed. It must be installed before it can be upgraded.")
}

fmt.Println("Upgrading", pack.Name)
//Pull the image down from Docker Hub
err = utils.PullImage(pack.Image)

if err != nil {
return err
}

fmt.Println("Updating package directories")

//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
}
} else {
//Remove the directory if it already exists
err = os.RemoveAll(vol.Path)

if err != nil {
return err
}

//Recreate the directory
err = os.MkdirAll(vol.Path, 0755)

if err != nil {
return err
}
}
}
}

//Check and see if any files need to be copied from the container to one of the volumes on the host.
if len(pack.Copies) > 0 {

fmt.Println("Copying necessary files 1/3")
//Create the container so that we can copy the files over to the right places
containerID, err := utils.CreateContainer(pack.Image)

if err != nil {
return err
}

fmt.Println("Copying necessary files 2/3")
//Copy the files from the container to the locations
for _, copy := range pack.Copies {
err = utils.CopyFromContainer(copy.Source, copy.Dest, containerID)

if err != nil {
return err
}
}

fmt.Println("Copying necessary files 3/3")
//Remove the Container
err = utils.RemoveContainer(containerID)

if err != nil {
return err
}

fmt.Println(pack.Name, "successfully upgraded")

}
} else {
//Loop through the packages in the package list
for _, pack := range packages.Packages {
//Check if the corresponding package image is already installed
imgExist, err := utils.ImageExists(pack.Image)

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

//If the image exists the package is already installed
if !imgExist {
continue
}

fmt.Println("Upgrading", pack.Name)
//Pull the image down from Docker Hub
err = utils.PullImage(pack.Image)

if err != nil {
return err
}

fmt.Println("Updating package directories")

//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
}
} else {
//Remove the directory if it already exists
err = os.RemoveAll(vol.Path)

if err != nil {
return err
}

//Recreate the directory
err = os.MkdirAll(vol.Path, 0755)

if err != nil {
return err
}
}
}
}

//Check and see if any files need to be copied from the container to one of the volumes on the host.
if len(pack.Copies) > 0 {

fmt.Println("Copying necessary files 1/3")
//Create the container so that we can copy the files over to the right places
containerID, err := utils.CreateContainer(pack.Image)

if err != nil {
return err
}

fmt.Println("Copying necessary files 2/3")
//Copy the files from the container to the locations
for _, copy := range pack.Copies {
err = utils.CopyFromContainer(copy.Source, copy.Dest, containerID)

if err != nil {
return err
}
}

fmt.Println("Copying necessary files 3/3")
//Remove the Container
err = utils.RemoveContainer(containerID)

if err != nil {
return err
}

fmt.Println(pack.Name, "successfully upgraded")
}

}

}

return nil
}
66 changes: 51 additions & 15 deletions utils/hcl_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,65 @@ type PackageHCLUtil struct {
Packages []Package `hcl:"package,block"`
}

//Config object to contain the configuration details
type Config struct {
BaseDir string `hcl:"base_dir,attr"`
StartPort int `hcl:"start_port,attr"`
PortInc int `hcl:"port_increment,attr"`
}

//Parse function to parse the HCL file given in the filepath
func Parse(filepath string) (PackageHCLUtil, error) {
func Parse(filepath string, out interface{}) (interface{}, error) {
//Create a parser
parser := hclparse.NewParser()

//Create the object to be decoded to
var packages PackageHCLUtil
switch out.(type) {
default:
return nil, errors.New("Unexpected type passed into the HCL parse function")

//Parse the data
parseData, parseDiags := parser.ParseHCLFile(filepath)
case PackageHCLUtil:
//Create the object to be decoded to
var packages PackageHCLUtil

//Check for errors
if parseDiags.HasErrors() {
return packages, errors.New("ParseDiags: " + parseDiags.Error())
}
//Parse the data
parseData, parseDiags := parser.ParseHCLFile(filepath)

//Check for errors
if parseDiags.HasErrors() {
return packages, errors.New("ParseDiags: " + parseDiags.Error())
}

//Decode the parsed HCL to the Object
decodeDiags := gohcl.DecodeBody(parseData.Body, nil, &packages)

//Check for errors
if decodeDiags.HasErrors() {
return packages, errors.New("DecodeDiags: " + decodeDiags.Error())
}

return packages, nil

case Config:
//Create the object to be decoded to
var config Config

//Parse the data
parseData, parseDiags := parser.ParseHCLFile(filepath)

//Check for errors
if parseDiags.HasErrors() {
return config, errors.New("ParseDiags: " + parseDiags.Error())
}

//Decode the parsed HCL to the Object
decodeDiags := gohcl.DecodeBody(parseData.Body, nil, &config)

//Decode the parsed HCL to the Object
decodeDiags := gohcl.DecodeBody(parseData.Body, nil, &packages)
//Check for errors
if decodeDiags.HasErrors() {
return config, errors.New("DecodeDiags: " + decodeDiags.Error())
}

//Check for errors
if decodeDiags.HasErrors() {
return packages, errors.New("DecodeDiags: " + decodeDiags.Error())
return config, nil
}

return packages, nil
}

0 comments on commit 82785d7

Please sign in to comment.