mirror of
https://gitea.elkins.co/Networking/ccl.git
synced 2025-02-04 12:02:47 -06:00
Clean up error handling, logging, and completion
This commit is contained in:
parent
16cf7fdf41
commit
c5dc8ba3ed
@ -36,17 +36,16 @@ var createCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Create containers specified by the arguments. Arguments can be either container
|
Long: `Create containers specified by the arguments. Arguments can be either container
|
||||||
names or categories. Multiple arguments are supported.`,
|
names or categories. Multiple arguments are supported.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "CREATE", c.Name)
|
fmt.Fprintln(output, "CREATE", cont.Name)
|
||||||
for _, c := range c.CreateCommands() {
|
for _, c := range cont.CreateCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Create failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,17 +36,16 @@ var recreateCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Recreate container images, stopping and restarting if necessary. Arguments can be
|
Long: `Recreate container images, stopping and restarting if necessary. Arguments can be
|
||||||
one or more container names or categories. If empty, "all" is assumed.`,
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "RECREATE", c.Name)
|
fmt.Fprintln(output, "RECREATE", cont.Name)
|
||||||
for _, c := range c.RecreateCommands() {
|
for _, c := range cont.RecreateCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Recreation failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,17 +36,16 @@ var restartCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Stop configured containers (if running), then restart them. Arguments can be
|
Long: `Stop configured containers (if running), then restart them. Arguments can be
|
||||||
one or more container names or categories. If empty, "all" is assumed.`,
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "RESTART", c.Name)
|
fmt.Fprintln(output, "RESTART", cont.Name)
|
||||||
for _, c := range c.RestartCommands() {
|
for _, c := range cont.RestartCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Restart failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
cmd/rm.go
12
cmd/rm.go
@ -25,7 +25,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,14 +39,11 @@ var rmCmd = &cobra.Command{
|
|||||||
If running, they will first be stopped.`,
|
If running, they will first be stopped.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "REMOVE", c.Name)
|
fmt.Fprintln(output, "REMOVE", cont.Name)
|
||||||
for _, cmd := range c.DestroyCommands() {
|
for _, cmd := range cont.DestroyCommands() {
|
||||||
if err := cmd.Execute(output, fake); err != nil {
|
if err := cmd.Execute(output, fake); err != nil {
|
||||||
log.WithFields(log.Fields{
|
cont.LogEntry().WithField("error", err).Errorln("Remove failed")
|
||||||
"container": c.Name,
|
|
||||||
"cmd": cmd,
|
|
||||||
}).Errorln("Remove failed")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
cmd/root.go
28
cmd/root.go
@ -34,8 +34,9 @@ import (
|
|||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "ccl",
|
Use: "ccl",
|
||||||
Short: "Manage a set of pre-configured of podman containers",
|
Short: "Manage a set of pre-configured of podman containers",
|
||||||
|
Version: Version,
|
||||||
Long: `ccl is a utility to manage a set of podman containers. Use with various subcommands
|
Long: `ccl is a utility to manage a set of podman containers. Use with various subcommands
|
||||||
to define, start, stop, or update the container images. Configuration is read
|
to define, start, stop, or update the container images. Configuration is read
|
||||||
from a toml configuration file, and the utility uses this information to
|
from a toml configuration file, and the utility uses this information to
|
||||||
@ -44,10 +45,10 @@ execute the necessary podman commands.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
output io.Writer
|
output io.Writer
|
||||||
verbose bool
|
verbose bool
|
||||||
fake bool
|
fake bool
|
||||||
socket string
|
socket string
|
||||||
)
|
)
|
||||||
|
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
@ -61,6 +62,12 @@ func Execute() {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(func() {
|
cobra.OnInitialize(func() {
|
||||||
|
if verbose {
|
||||||
|
output = os.Stdout
|
||||||
|
} else {
|
||||||
|
output = io.Discard
|
||||||
|
}
|
||||||
|
|
||||||
// connect to podman
|
// connect to podman
|
||||||
conn, err := bindings.NewConnection(context.Background(), socket)
|
conn, err := bindings.NewConnection(context.Background(), socket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -72,15 +79,8 @@ func init() {
|
|||||||
fmt.Fprintln(os.Stderr, "Warning: Could not initialize configuration:", err)
|
fmt.Fprintln(os.Stderr, "Warning: Could not initialize configuration:", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
cobra.OnInitialize(func() {
|
|
||||||
if verbose {
|
|
||||||
output = os.Stdout
|
|
||||||
} else {
|
|
||||||
output = io.Discard
|
|
||||||
}
|
|
||||||
})
|
|
||||||
rootCmd.PersistentFlags().StringVarP(&config.ConfigFile, "config", "c", config.CONFIG_FILE_DEFAULT, "pathname of config file")
|
rootCmd.PersistentFlags().StringVarP(&config.ConfigFile, "config", "c", config.CONFIG_FILE_DEFAULT, "pathname of config file")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "show additional info from command execution")
|
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "show additional info from command execution")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&fake, "no-action", "n", false, "do not actually execute commands")
|
rootCmd.PersistentFlags().BoolVarP(&fake, "no-action", "n", false, "do not actually execute commands")
|
||||||
rootCmd.PersistentFlags().StringVarP(&socket, "socket", "k", "unix:/run/podman/podman.sock", "socket address to which to connect")
|
rootCmd.PersistentFlags().StringVarP(&socket, "socket", "k", "unix:///run/podman/podman.sock", "socket address to which to connect")
|
||||||
}
|
}
|
||||||
|
11
cmd/start.go
11
cmd/start.go
@ -36,17 +36,16 @@ var startCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Start configured containers. They must be created first. Arguments can be
|
Long: `Start configured containers. They must be created first. Arguments can be
|
||||||
one or more container names or categories. If empty, "all" is assumed.`,
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "START", c.Name)
|
fmt.Fprintln(output, "START", cont.Name)
|
||||||
for _, c := range c.StartCommands() {
|
for _, c := range cont.StartCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Start failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
cmd/stop.go
11
cmd/stop.go
@ -36,17 +36,16 @@ var stopCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Stop configured containers if running. Arguments can be
|
Long: `Stop configured containers if running. Arguments can be
|
||||||
one or more container names or categories. If empty, "all" is assumed.`,
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "STOP", c.Name)
|
fmt.Fprintln(output, "STOP", cont.Name)
|
||||||
for _, c := range c.StopCommands() {
|
for _, c := range cont.StopCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Stop failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,17 +36,16 @@ var updateCmd = &cobra.Command{
|
|||||||
ValidArgsFunction: validNouns,
|
ValidArgsFunction: validNouns,
|
||||||
Long: `Update container images, stopping and restarting if necessary. Arguments can be
|
Long: `Update container images, stopping and restarting if necessary. Arguments can be
|
||||||
one or more container names or categories. If empty, "all" is assumed.`,
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
Run: func(_ *cobra.Command, args []string) {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, cont := range conts {
|
||||||
fmt.Fprintln(output, "UPDATE", c.Name)
|
fmt.Fprintln(output, "UPDATE", cont.Name)
|
||||||
for _, c := range c.UpdateCommands() {
|
for _, c := range cont.UpdateCommands() {
|
||||||
if err := c.Execute(output, fake); err != nil {
|
if err := c.Execute(output, fake); err != nil {
|
||||||
return err
|
cont.LogEntry().WithField("error", err).Errorln("Update failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"gitea.elkins.co/Networking/ccl/internal/pkg/network"
|
"gitea.elkins.co/Networking/ccl/internal/pkg/network"
|
||||||
"github.com/emirpasic/gods/sets/hashset"
|
"github.com/emirpasic/gods/sets/hashset"
|
||||||
toml "github.com/pelletier/go-toml"
|
toml "github.com/pelletier/go-toml"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,22 +22,18 @@ var (
|
|||||||
ConfigFile string = CONFIG_FILE_DEFAULT
|
ConfigFile string = CONFIG_FILE_DEFAULT
|
||||||
networks = &[]network.Network{}
|
networks = &[]network.Network{}
|
||||||
containers = &[]container.Container{}
|
containers = &[]container.Container{}
|
||||||
categories = &[]string{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Categories() []string {
|
func Categories() []string {
|
||||||
if categories != nil {
|
categories := []string{"all"}
|
||||||
return *categories
|
|
||||||
}
|
|
||||||
categories = &[]string{"all"}
|
|
||||||
gs := hashset.New()
|
gs := hashset.New()
|
||||||
for _, c := range *containers {
|
for _, c := range *containers {
|
||||||
gs.Add(c.Category)
|
gs.Add(c.Category)
|
||||||
}
|
}
|
||||||
for _, c := range gs.Values() {
|
for _, c := range gs.Values() {
|
||||||
*categories = append(*categories, c.(string))
|
categories = append(categories, c.(string))
|
||||||
}
|
}
|
||||||
return *categories
|
return categories
|
||||||
}
|
}
|
||||||
|
|
||||||
func Union(ids []string) (conts []container.Container) {
|
func Union(ids []string) (conts []container.Container) {
|
||||||
@ -56,6 +53,11 @@ func Union(ids []string) (conts []container.Container) {
|
|||||||
match := slices.IndexFunc(*containers, func(c container.Container) bool { return c.Name == name })
|
match := slices.IndexFunc(*containers, func(c container.Container) bool { return c.Name == name })
|
||||||
conts = append(conts, (*containers)[match])
|
conts = append(conts, (*containers)[match])
|
||||||
}
|
}
|
||||||
|
if len(conts) == 0 {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"ids": ids,
|
||||||
|
}).Warnln("No matching containers")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,19 @@ func (c *Container) Init(conn context.Context, nets *[]network.Network) error {
|
|||||||
return c.populateCData()
|
return c.populateCData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Container) LogEntry() *log.Entry {
|
||||||
|
f := log.Fields{
|
||||||
|
"container": c.Name,
|
||||||
|
}
|
||||||
|
if c.cdata != nil {
|
||||||
|
f["id"] = c.cdata.ID
|
||||||
|
}
|
||||||
|
if c.cdata.State != nil {
|
||||||
|
f["state"] = c.cdata.State.Status
|
||||||
|
}
|
||||||
|
return log.WithFields(f)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Container) CreateCommands() []command.Command {
|
func (c *Container) CreateCommands() []command.Command {
|
||||||
if c.Image == "" {
|
if c.Image == "" {
|
||||||
log.WithField("container", c.Name).Error("Image not defined")
|
log.WithField("container", c.Name).Error("Image not defined")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user