mirror of
https://gitea.elkins.co/Networking/ccl.git
synced 2025-03-09 12:41:40 -05:00
Rest of commands; tooling including conditional command types
This commit is contained in:
parent
61b7fe55a0
commit
f74dc50392
@ -22,6 +22,8 @@ THE SOFTWARE.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -34,11 +36,17 @@ 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.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, c := range conts {
|
||||||
config.PrintCreate(&c)
|
fmt.Fprintln(output, "CREATE", c.Name)
|
||||||
|
for _, c := range c.CreateCommands() {
|
||||||
|
if err := c.Execute(output, fake); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
cmd/recreate.go
Normal file
55
cmd/recreate.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 Joel D. Elkins <joel@elkins.co>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// recreateCmd represents the recreate command
|
||||||
|
var recreateCmd = &cobra.Command{
|
||||||
|
Use: "recreate",
|
||||||
|
Short: "Recreate container images",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
ValidArgsFunction: validNouns,
|
||||||
|
Long: `Recreate container images, stopping and restarting if necessary. Arguments can be
|
||||||
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
conts := config.Union(args)
|
||||||
|
for _, c := range conts {
|
||||||
|
fmt.Fprintln(output, "RECREATE", c.Name)
|
||||||
|
for _, c := range c.RecreateCommands() {
|
||||||
|
if err := c.Execute(output, fake); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(recreateCmd)
|
||||||
|
}
|
65
cmd/restart.go
Normal file
65
cmd/restart.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 Joel D. Elkins <joel@elkins.co>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// restartCmd represents the restart command
|
||||||
|
var restartCmd = &cobra.Command{
|
||||||
|
Use: "restart",
|
||||||
|
Short: "Restart containers",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
ValidArgsFunction: validNouns,
|
||||||
|
Long: `Stop configured containers (if running), then restart them. Arguments can be
|
||||||
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
conts := config.Union(args)
|
||||||
|
for _, c := range conts {
|
||||||
|
fmt.Fprintln(output, "RESTART", c.Name)
|
||||||
|
for _, c := range c.RestartCommands() {
|
||||||
|
if err := c.Execute(output, fake); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(restartCmd)
|
||||||
|
|
||||||
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
|
// Cobra supports Persistent Flags which will work for this command
|
||||||
|
// and all subcommands, e.g.:
|
||||||
|
// restartCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||||
|
|
||||||
|
// Cobra supports local flags which will only run when this command
|
||||||
|
// is called directly, e.g.:
|
||||||
|
// restartCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
}
|
12
cmd/root.go
12
cmd/root.go
@ -22,6 +22,7 @@ THE SOFTWARE.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -39,9 +40,11 @@ from a toml configuration file, and the utility uses this information to
|
|||||||
execute the necessary podman commands.`,
|
execute the necessary podman commands.`,
|
||||||
ValidArgsFunction: cobra.NoFileCompletions,
|
ValidArgsFunction: cobra.NoFileCompletions,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
output io.Writer
|
output io.Writer
|
||||||
verbose bool
|
verbose bool
|
||||||
|
fake bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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.
|
||||||
@ -54,7 +57,13 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(config.Init)
|
cobra.OnInitialize(func() {
|
||||||
|
err := config.Init()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "Could not initialize configuration:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
cobra.OnInitialize(func() {
|
cobra.OnInitialize(func() {
|
||||||
if verbose {
|
if verbose {
|
||||||
output = os.Stderr
|
output = os.Stderr
|
||||||
@ -64,4 +73,5 @@ func init() {
|
|||||||
})
|
})
|
||||||
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")
|
||||||
}
|
}
|
||||||
|
18
cmd/start.go
18
cmd/start.go
@ -22,21 +22,31 @@ THE SOFTWARE.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// startCmd represents the start command
|
// startCmd represents the start command
|
||||||
var startCmd = &cobra.Command{
|
var startCmd = &cobra.Command{
|
||||||
Use: "start",
|
Use: "start",
|
||||||
Short: "Start containers",
|
Short: "Start containers",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
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.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
conts := config.Union(args)
|
conts := config.Union(args)
|
||||||
for _, c := range conts {
|
for _, c := range conts {
|
||||||
config.PrintStart(&c)
|
fmt.Fprintln(output, "START", c.Name)
|
||||||
|
for _, c := range c.StartCommands() {
|
||||||
|
if err := c.Execute(output, fake); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
cmd/update.go
Normal file
55
cmd/update.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 Joel D. Elkins <joel@elkins.co>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.elkins.co/Networking/ccl/internal/pkg/config"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// updateCmd represents the update command
|
||||||
|
var updateCmd = &cobra.Command{
|
||||||
|
Use: "update",
|
||||||
|
Short: "Update container images",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
ValidArgsFunction: validNouns,
|
||||||
|
Long: `Update container images, stopping and restarting if necessary. Arguments can be
|
||||||
|
one or more container names or categories. If empty, "all" is assumed.`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
conts := config.Union(args)
|
||||||
|
for _, c := range conts {
|
||||||
|
fmt.Fprintln(output, "UPDATE", c.Name)
|
||||||
|
for _, c := range c.UpdateCommands() {
|
||||||
|
if err := c.Execute(output, fake); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(updateCmd)
|
||||||
|
}
|
@ -29,8 +29,20 @@ import (
|
|||||||
|
|
||||||
type CommandType int
|
type CommandType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
CT_NOP CommandType = iota
|
||||||
|
CT_SH
|
||||||
|
CT_REF
|
||||||
|
CT_INDIRECT
|
||||||
|
CT_SET
|
||||||
|
CT_DEBUG
|
||||||
|
CT_CONDITIONAL
|
||||||
|
)
|
||||||
|
|
||||||
func (ct CommandType) String() string {
|
func (ct CommandType) String() string {
|
||||||
switch ct {
|
switch ct {
|
||||||
|
case CT_NOP:
|
||||||
|
return "NOP"
|
||||||
case CT_SH:
|
case CT_SH:
|
||||||
return "SHELL"
|
return "SHELL"
|
||||||
case CT_REF:
|
case CT_REF:
|
||||||
@ -41,30 +53,40 @@ func (ct CommandType) String() string {
|
|||||||
return "SET"
|
return "SET"
|
||||||
case CT_DEBUG:
|
case CT_DEBUG:
|
||||||
return "DEBUG"
|
return "DEBUG"
|
||||||
|
case CT_CONDITIONAL:
|
||||||
|
return "CONDITIONAL"
|
||||||
default:
|
default:
|
||||||
return "UNKOWN"
|
return "UNKOWN"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
CT_SH CommandType = iota
|
|
||||||
CT_REF
|
|
||||||
CT_INDIRECT
|
|
||||||
CT_SET
|
|
||||||
CT_DEBUG
|
|
||||||
)
|
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Type CommandType
|
Type CommandType
|
||||||
Command interface{}
|
Command interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type namedFunc struct {
|
||||||
|
Name string
|
||||||
|
Func func() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type conditional struct {
|
||||||
|
Name string
|
||||||
|
Condition func() bool
|
||||||
|
ThenCmd Command
|
||||||
|
ElseCmd Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f namedFunc) String() string {
|
||||||
|
return f.Name + "()"
|
||||||
|
}
|
||||||
|
|
||||||
func NewShell(cmd string) Command {
|
func NewShell(cmd string) Command {
|
||||||
return Command{CT_SH, cmd}
|
return Command{CT_SH, cmd}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFunc(f func() string) Command {
|
func NewFunc(name string, f func() string) Command {
|
||||||
return Command{CT_REF, f}
|
return Command{CT_REF, namedFunc{name, f}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIndirect(c Command) Command {
|
func NewIndirect(c Command) Command {
|
||||||
@ -79,6 +101,19 @@ func NewDebug(msg string) Command {
|
|||||||
return Command{CT_DEBUG, msg}
|
return Command{CT_DEBUG, msg}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewNop() Command {
|
||||||
|
return Command{CT_NOP, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConditional(name string, ifPart func() bool, thenPart Command, elsePart Command) Command {
|
||||||
|
return Command{CT_CONDITIONAL, conditional{
|
||||||
|
Name: name,
|
||||||
|
Condition: ifPart,
|
||||||
|
ThenCmd: thenPart,
|
||||||
|
ElseCmd: elsePart,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
func (c Command) GetShell() (string, error) {
|
func (c Command) GetShell() (string, error) {
|
||||||
s, ok := c.Command.(string)
|
s, ok := c.Command.(string)
|
||||||
if ok {
|
if ok {
|
||||||
@ -88,45 +123,79 @@ func (c Command) GetShell() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c Command) CallRef() (string, error) {
|
func (c Command) CallRef() (string, error) {
|
||||||
f, ok := c.Command.(func() string)
|
f, ok := c.Command.(namedFunc)
|
||||||
if ok {
|
if ok {
|
||||||
s := f()
|
s := f.Func()
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("Type error. Requested = %d, Type = %d", CT_REF, c.Type)
|
return "", fmt.Errorf("Type error. Requested = %d, Type = %d", CT_REF, c.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Command) Execute(output io.Writer) error {
|
func (c Command) Execute(output io.Writer, fake bool) error {
|
||||||
switch c.Type {
|
switch c.Type {
|
||||||
|
case CT_NOP:
|
||||||
|
fmt.Fprintln(output, c.Type)
|
||||||
case CT_SH:
|
case CT_SH:
|
||||||
cmd, err := c.GetShell()
|
cmd, err := c.GetShell()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
|
if fake {
|
||||||
fmt.Fprintln(output, out)
|
fmt.Fprintln(output, c.Type, "sh", "-c", cmd)
|
||||||
return err
|
return nil
|
||||||
|
} else {
|
||||||
|
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
|
||||||
|
fmt.Fprintln(output, out)
|
||||||
|
return err
|
||||||
|
}
|
||||||
case CT_REF:
|
case CT_REF:
|
||||||
s, err := c.CallRef()
|
if fake {
|
||||||
fmt.Println(s)
|
fmt.Fprintln(output, c.Type, c.Command)
|
||||||
return err
|
return nil
|
||||||
|
} else {
|
||||||
|
s, err := c.CallRef()
|
||||||
|
fmt.Println(s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
case CT_INDIRECT:
|
case CT_INDIRECT:
|
||||||
ct, ok := c.Command.(Command)
|
ct, ok := c.Command.(Command)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Type error: Requested = %d, Type = %d", CT_INDIRECT, c.Type)
|
return fmt.Errorf("Type error: Requested = %d, Type = %d", CT_INDIRECT, c.Type)
|
||||||
}
|
}
|
||||||
return ct.Execute(output)
|
return ct.Execute(output, fake)
|
||||||
case CT_SET:
|
case CT_SET:
|
||||||
cs, ok := c.Command.([]Command)
|
cs, ok := c.Command.([]Command)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Type error: Requested = %d, Type = %d", CT_SET, c.Type)
|
return fmt.Errorf("Type error: Requested = %d, Type = %d", CT_SET, c.Type)
|
||||||
}
|
}
|
||||||
for i := range cs {
|
for i := range cs {
|
||||||
err := cs[i].Execute(output)
|
err := cs[i].Execute(output, fake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case CT_CONDITIONAL:
|
||||||
|
cond, ok := c.Command.(conditional)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Type error: Requested = %d, Type = %d", CT_CONDITIONAL, c.Type)
|
||||||
|
}
|
||||||
|
if fake {
|
||||||
|
fmt.Fprintln(output, c.Type, cond.Name)
|
||||||
|
fmt.Fprintln(output, "-- True branch")
|
||||||
|
cond.ThenCmd.Execute(output, fake)
|
||||||
|
fmt.Fprintln(output, "-- False branch")
|
||||||
|
cond.ElseCmd.Execute(output, fake)
|
||||||
|
fmt.Fprintln(output, "-- End conditional")
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
branch := cond.Condition()
|
||||||
|
fmt.Fprintln(output, c.Type, cond.Name, ":", branch)
|
||||||
|
if branch {
|
||||||
|
return cond.ThenCmd.Execute(output, fake)
|
||||||
|
} else {
|
||||||
|
return cond.ElseCmd.Execute(output, fake)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -65,20 +65,21 @@ func Union(ids []string) (conts []container.Container) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init() {
|
func Init() error {
|
||||||
f, err := os.ReadFile(ConfigFile)
|
f, err := os.ReadFile(ConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
p := parse{}
|
p := parse{}
|
||||||
err = toml.Unmarshal(f, &p)
|
err = toml.Unmarshal(f, &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
containers, networks = &p.Containers, &p.Networks
|
containers, networks = &p.Containers, &p.Networks
|
||||||
for i := range p.Containers {
|
for i := range p.Containers {
|
||||||
p.Containers[i].Init(networks)
|
p.Containers[i].Init(networks)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NetworkDefaults(name string) (net *network.Network) {
|
func NetworkDefaults(name string) (net *network.Network) {
|
||||||
|
@ -45,13 +45,15 @@ type Container struct {
|
|||||||
pid int
|
pid int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) ClearRACommands() []command.Command {
|
func (c *Container) flushIPv6Commands() []command.Command {
|
||||||
cmds := []command.Command{}
|
cmds := []command.Command{}
|
||||||
for _, n := range c.Networks {
|
for _, n := range c.Networks {
|
||||||
if n.IPv6 != nil && !*n.IPv6 {
|
if n.IPv6 != nil && !*n.IPv6 {
|
||||||
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s sysctl -w net.ipv6.conf.default.accept_ra=0", c.Name)))
|
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s sysctl -w net.ipv6.conf.default.accept_ra=0", c.Name)))
|
||||||
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s sysctl -w net.ipv6.conf.all.accept_ra=0", c.Name)))
|
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s sysctl -w net.ipv6.conf.all.accept_ra=0", c.Name)))
|
||||||
// TODO: iterate through invoices and set the accpet_ra parameter to zero for each
|
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s ip -6 address flush scope global", c.Name)))
|
||||||
|
cmds = append(cmds, command.NewShell(fmt.Sprintf("ip netns exec %s ip -6 route flush proto ra", c.Name)))
|
||||||
|
// TODO: test, and, if necessary, iterate through interfaces and set the accpet_ra parameter to zero for each
|
||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,21 +68,24 @@ func (c *Container) CreateCommands() []command.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) RecreateCommands() []command.Command {
|
func (c *Container) RecreateCommands() []command.Command {
|
||||||
cmds := c.DestroyCommands()
|
wasRunning := false
|
||||||
create := c.CreateCommands()
|
return []command.Command{
|
||||||
for _, c := range create {
|
command.NewFunc("stash_run_state", func() string {
|
||||||
cmds = append(cmds, c)
|
wasRunning = c.isRunning()
|
||||||
|
runMsg := "not running"
|
||||||
|
if wasRunning {
|
||||||
|
runMsg = "running"
|
||||||
|
}
|
||||||
|
return "Container " + c.Name + " is " + runMsg
|
||||||
|
}),
|
||||||
|
command.NewSet(c.DestroyCommands()),
|
||||||
|
command.NewSet(c.CreateCommands()),
|
||||||
|
command.NewConditional("start_if_was_running",
|
||||||
|
func() bool { return wasRunning },
|
||||||
|
command.NewSet(c.StartCommands()),
|
||||||
|
command.NewNop(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
return cmds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Container) StopCommands() []command.Command {
|
|
||||||
cmds := []command.Command{}
|
|
||||||
if _, err := c.Pid(); err != nil {
|
|
||||||
cmds = append(cmds, command.NewShell("podman stop "+c.Name))
|
|
||||||
}
|
|
||||||
cmds = append(cmds, command.NewShell("podman rm "+c.Name))
|
|
||||||
return cmds
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) DestroyCommands() []command.Command {
|
func (c *Container) DestroyCommands() []command.Command {
|
||||||
@ -90,14 +95,62 @@ func (c *Container) DestroyCommands() []command.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) StartCommands() []command.Command {
|
func (c *Container) StartCommands() []command.Command {
|
||||||
_, err := c.Pid()
|
if len(c.upCommands) == 0 {
|
||||||
if err != nil {
|
c.initCommands()
|
||||||
if len(c.upCommands) == 0 {
|
}
|
||||||
c.initCommands()
|
return []command.Command{
|
||||||
}
|
command.NewConditional("start_unless_running",
|
||||||
return c.upCommands
|
c.isRunning,
|
||||||
|
command.NewNop(),
|
||||||
|
command.NewSet(c.upCommands),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) RestartCommands() []command.Command {
|
||||||
|
return []command.Command{
|
||||||
|
command.NewSet(c.StopCommands()),
|
||||||
|
command.NewShell("sleep 1"),
|
||||||
|
command.NewSet(c.StartCommands()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) isRunning() bool {
|
||||||
|
if _, err := c.Pid(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) UpdateCommands() []command.Command {
|
||||||
|
wasRunning := false
|
||||||
|
return []command.Command{
|
||||||
|
command.NewFunc("stash_run_state", func() string {
|
||||||
|
wasRunning = c.isRunning()
|
||||||
|
runMsg := "not running"
|
||||||
|
if wasRunning {
|
||||||
|
runMsg = "running"
|
||||||
|
}
|
||||||
|
return "Container " + c.Name + " is " + runMsg
|
||||||
|
}),
|
||||||
|
command.NewShell("podman pull " + c.Image),
|
||||||
|
command.NewSet(c.RecreateCommands()),
|
||||||
|
command.NewConditional("restart_if_was_running",
|
||||||
|
func() bool { return wasRunning },
|
||||||
|
command.NewSet(c.StartCommands()),
|
||||||
|
command.NewNop(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) StopCommands() []command.Command {
|
||||||
|
return []command.Command{
|
||||||
|
command.NewConditional("stop_if_running",
|
||||||
|
c.isRunning,
|
||||||
|
command.NewShell("podman stop "+c.Name),
|
||||||
|
command.NewNop(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
return []command.Command{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) Init(nets *[]network.Network) {
|
func (c *Container) Init(nets *[]network.Network) {
|
||||||
@ -136,7 +189,7 @@ func (c *Container) Pid() (pid int, err error) {
|
|||||||
|
|
||||||
func (c *Container) initCommands() {
|
func (c *Container) initCommands() {
|
||||||
c.createCommands = []command.Command{
|
c.createCommands = []command.Command{
|
||||||
command.NewShell("podman create --name %s%s%s%s%s%s"),
|
command.NewShell("podman create --name %s%s%s%s%s %s%s"),
|
||||||
}
|
}
|
||||||
hostname := ""
|
hostname := ""
|
||||||
if c.Hostname != "" {
|
if c.Hostname != "" {
|
||||||
@ -159,7 +212,7 @@ func (c *Container) initCommands() {
|
|||||||
entry = " " + c.Command
|
entry = " " + c.Command
|
||||||
}
|
}
|
||||||
t, _ := c.createCommands[0].GetShell()
|
t, _ := c.createCommands[0].GetShell()
|
||||||
c.createCommands[0] = command.NewShell(fmt.Sprintf(t, c.Name, hostname, net, dns, args, entry))
|
c.createCommands[0] = command.NewShell(fmt.Sprintf(t, c.Name, hostname, net, dns, args, c.Image, entry))
|
||||||
|
|
||||||
if len(c.Networks) > 1 {
|
if len(c.Networks) > 1 {
|
||||||
for i := 1; i < len(c.Networks); i++ {
|
for i := 1; i < len(c.Networks); i++ {
|
||||||
@ -171,7 +224,7 @@ func (c *Container) initCommands() {
|
|||||||
|
|
||||||
c.upCommands = []command.Command{
|
c.upCommands = []command.Command{
|
||||||
command.NewShell("podman start " + c.Name),
|
command.NewShell("podman start " + c.Name),
|
||||||
command.NewFunc(func() string {
|
command.NewFunc("assure_netns", func() string {
|
||||||
var err error
|
var err error
|
||||||
pid, err := c.Pid()
|
pid, err := c.Pid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -181,7 +234,7 @@ func (c *Container) initCommands() {
|
|||||||
command.NewShell(fmt.Sprintf("rm -f /var/run/netns/%s", c.Name)),
|
command.NewShell(fmt.Sprintf("rm -f /var/run/netns/%s", c.Name)),
|
||||||
command.NewShell(fmt.Sprintf("ln -s /proc/%d/ns/net /var/run/netns/%s", pid, c.Name)),
|
command.NewShell(fmt.Sprintf("ln -s /proc/%d/ns/net /var/run/netns/%s", pid, c.Name)),
|
||||||
})
|
})
|
||||||
err = commands.Execute(os.Stderr)
|
err = commands.Execute(os.Stderr, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprintln("Error:", err)
|
return fmt.Sprintln("Error:", err)
|
||||||
}
|
}
|
||||||
@ -190,7 +243,7 @@ func (c *Container) initCommands() {
|
|||||||
}
|
}
|
||||||
if len(c.Networks) > 0 && !*c.Networks[0].IPv6 {
|
if len(c.Networks) > 0 && !*c.Networks[0].IPv6 {
|
||||||
c.upCommands = append(c.upCommands, command.NewShell("sleep 1"))
|
c.upCommands = append(c.upCommands, command.NewShell("sleep 1"))
|
||||||
for _, k := range c.ClearRACommands() {
|
for _, k := range c.flushIPv6Commands() {
|
||||||
c.upCommands = append(c.upCommands, k)
|
c.upCommands = append(c.upCommands, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user