mirror of
https://gitea.elkins.co/Networking/ccl.git
synced 2025-03-06 18:28:48 -06:00
WIP - broken compile
This commit is contained in:
parent
94892c3604
commit
50cb8543f7
@ -38,8 +38,7 @@ var createCmd = &cobra.Command{
|
||||
names or categories. Multiple arguments are supported.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.CreateCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.CreateCommands() }, 0)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -29,27 +29,81 @@ import (
|
||||
"gitea.elkins.co/Networking/ccl/internal/pkg/command"
|
||||
"gitea.elkins.co/Networking/ccl/internal/pkg/container"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
func execForEach(tgts []container.Container, getSet func(*container.Container) command.CommandSet) {
|
||||
var wg sync.WaitGroup
|
||||
type runner struct{
|
||||
GetSet func(*container.Container) command.CommandSet
|
||||
GroupScale int
|
||||
}
|
||||
|
||||
func execSetsForEachGroup(tgts [] container.Container, runners []runner) {
|
||||
var ser sync.Mutex // serialize non-async containers
|
||||
runLevel := make(map[int][]container.Container)
|
||||
|
||||
for i := range tgts {
|
||||
async := tgts[i].StartOrder.ValueOrZero() == 0
|
||||
wg.Add(1)
|
||||
if async {
|
||||
// TODO: need to log errors on this branch
|
||||
go runSet(&tgts[i], getSet, &wg)
|
||||
} else {
|
||||
ser.Lock()
|
||||
go func(cont *container.Container, ser *sync.Mutex) {
|
||||
defer ser.Unlock()
|
||||
runSet(cont, getSet, &wg)
|
||||
time.Sleep(5 * time.Second)
|
||||
}(&tgts[i], &ser)
|
||||
}
|
||||
rl := tgts[i].StartGroup
|
||||
runLevel[rl] = append(runLevel[rl], tgts[i])
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
rls := maps.Keys(runLevel)
|
||||
slices.Sort(rls)
|
||||
|
||||
for _, r := range rls {
|
||||
cs := runLevel[r]
|
||||
ser.Lock()
|
||||
fmt.Fprintln(output, "*** Running a command set for group", r, mapNames(cs))
|
||||
go func(async bool, conts []container.Container, ser *sync.Mutex) {
|
||||
var wg sync.WaitGroup
|
||||
defer func() {
|
||||
wg.Wait()
|
||||
ser.Unlock()
|
||||
}()
|
||||
for i := range conts {
|
||||
wg.Add(1)
|
||||
go runSet(&conts[i], getSet, &wg)
|
||||
}
|
||||
if !async {
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}(r == 0, cs, &ser)
|
||||
}
|
||||
ser.Lock()
|
||||
}
|
||||
|
||||
func execForEach(tgts []container.Container, getSet func(*container.Container) command.CommandSet, groupScale int) {
|
||||
var ser sync.Mutex // serialize non-async containers
|
||||
runLevel := make(map[int][]container.Container)
|
||||
|
||||
for i := range tgts {
|
||||
rl := int(tgts[i].StartGroup * groupScale)
|
||||
runLevel[rl] = append(runLevel[rl], tgts[i])
|
||||
}
|
||||
|
||||
rls := maps.Keys(runLevel)
|
||||
slices.Sort(rls)
|
||||
|
||||
for _, r := range rls {
|
||||
cs := runLevel[r]
|
||||
ser.Lock()
|
||||
fmt.Fprintln(output, "*** Running a command set for group", r, mapNames(cs))
|
||||
go func(async bool, conts []container.Container, ser *sync.Mutex) {
|
||||
var wg sync.WaitGroup
|
||||
defer func() {
|
||||
wg.Wait()
|
||||
ser.Unlock()
|
||||
}()
|
||||
for i := range conts {
|
||||
wg.Add(1)
|
||||
go runSet(&conts[i], getSet, &wg)
|
||||
}
|
||||
if !async {
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}(r == 0, cs, &ser)
|
||||
}
|
||||
ser.Lock()
|
||||
}
|
||||
|
||||
func runSet(cont *container.Container, getSet func(*container.Container) command.CommandSet, wg *sync.WaitGroup) {
|
||||
@ -67,11 +121,11 @@ func runSet(cont *container.Container, getSet func(*container.Container) command
|
||||
}
|
||||
|
||||
// For debugging
|
||||
func printConts(conts []container.Container) {
|
||||
func mapNames(conts []container.Container) string {
|
||||
names := []string{}
|
||||
for i := range conts {
|
||||
names = append(names, fmt.Sprintf("[%s %d]", conts[i].Name, conts[i].StartOrder.ValueOrZero()))
|
||||
names = append(names, conts[i].Name)
|
||||
}
|
||||
fmt.Printf("%v\n", names)
|
||||
return fmt.Sprintf("%v", names)
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,7 @@ affected: the old image will still remain, though untagged, and any defined cont
|
||||
will still use it.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.PullCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.PullCommands() }, 0)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,9 @@ var recreateCmd = &cobra.Command{
|
||||
one or more container names or categories. If empty, "all" is assumed.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Stop)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() })
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.RecreateCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.ConditionalStartCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() }, -1)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.RecreateCommands() }, 0)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.ConditionalStartCommands() }, 1)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,8 @@ var restartCmd = &cobra.Command{
|
||||
one or more container names or categories. If empty, "all" is assumed.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Stop)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() })
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StartCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() }, -1)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StartCommands() }, 1)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,8 @@ var rmCmd = &cobra.Command{
|
||||
If running, they will first be stopped.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Stop)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.RemoveCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() }, -1)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.RemoveCommands() }, 0)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@ var startCmd = &cobra.Command{
|
||||
one or more container names or categories. If empty, "all" is assumed.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StartCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StartCommands() }, 1)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@ var stopCmd = &cobra.Command{
|
||||
one or more container names or categories. If empty, "all" is assumed.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Stop)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.StopCommands() }, -1)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,8 @@ var updateCmd = &cobra.Command{
|
||||
one or more container names or categories. If empty, "all" is assumed.`,
|
||||
Run: func(_ *cobra.Command, args []string) {
|
||||
conts := config.Union(args, contMask)
|
||||
container.Reorder(conts, container.Stop)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.UpdateCommands() })
|
||||
container.Reorder(conts, container.Start)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.ConditionalStartCommands() })
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.UpdateCommands() }, -1)
|
||||
execForEach(conts, func(c *container.Container) command.CommandSet { return c.ConditionalStartCommands() }, 1)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -57,10 +57,10 @@ type Container struct {
|
||||
ExposeUdp []uint16 `toml:"expose_udp,omitempty"`
|
||||
PortsTcp map[uint16]uint16 `toml:"ports,omitempty"`
|
||||
NetNS string `toml:"netns,omitempty"`
|
||||
StartOrder null.Int `toml:"start_order,omitempty"`
|
||||
StartGroup int `toml:"group,omitempty"`
|
||||
|
||||
conn context.Context
|
||||
cdata *define.InspectContainerData
|
||||
conn context.Context
|
||||
cdata *define.InspectContainerData
|
||||
wasRunning null.Bool
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ func (c *Container) UpdateCommands() cmd.CommandSet {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Container) ConditionalStartCommands() cmd.CommandSet {
|
||||
func (c *Container) ConditionalStartCommands() cmd.CommandSet {
|
||||
return c.newCommandSet("CONDSTART", cmd.Commands{
|
||||
cmd.NewConditional("restart_if_was_running",
|
||||
c.wasRunning.ValueOrZero,
|
||||
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
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 container
|
||||
|
||||
import "golang.org/x/exp/slices"
|
||||
|
||||
type operation bool
|
||||
|
||||
const (
|
||||
Start operation = true
|
||||
Stop operation = false
|
||||
)
|
||||
|
||||
func Reorder(conts []Container, op operation) {
|
||||
// null orderings go first for either start or stop, as they are executed asynchronously
|
||||
norm := func(a, b Container) bool {
|
||||
return a.StartOrder.ValueOrZero() < b.StartOrder.ValueOrZero()
|
||||
}
|
||||
rev := func(a, b Container) bool {
|
||||
if a.StartOrder.ValueOrZero() == 0 {
|
||||
return true
|
||||
}
|
||||
if b.StartOrder.ValueOrZero() == 0 {
|
||||
return false
|
||||
}
|
||||
return norm(b, a)
|
||||
}
|
||||
var sorter func(a, b Container) bool
|
||||
if op == Start {
|
||||
sorter = norm
|
||||
} else {
|
||||
sorter = rev
|
||||
}
|
||||
slices.SortFunc(conts, sorter)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user