main: Libify mgmt with a golang API

This is an initial implementation of a possible golang API. In this
particular version, the *gconfig.GraphConfig data structures are
emitted, instead of possibly building a pgraph. As long as we can
represent any local graph as the data structure, then this is fine!

Is there a way to merge the gconfig Vertex and the pgraph Vertex?
This commit is contained in:
James Shubin
2016-10-24 04:10:54 -04:00
parent 80476d19f9
commit 71de8014d5
4 changed files with 171 additions and 35 deletions

110
examples/lib/libmgmt1.go Normal file
View File

@@ -0,0 +1,110 @@
// libmgmt example
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/purpleidea/mgmt/gconfig"
mgmt "github.com/purpleidea/mgmt/mgmtmain"
"github.com/purpleidea/mgmt/resources"
)
func generateGraphConfig() *gconfig.GraphConfig {
n1, err := resources.NewNoopRes("noop1")
if err != nil {
return nil // error
}
gc := &gconfig.GraphConfig{
Graph: "libmgmt",
Resources: gconfig.Resources{ // must redefine anonymous struct :(
// in alphabetical order
Exec: []*resources.ExecRes{},
File: []*resources.FileRes{},
Msg: []*resources.MsgRes{},
Noop: []*resources.NoopRes{n1},
Pkg: []*resources.PkgRes{},
Svc: []*resources.SvcRes{},
Timer: []*resources.TimerRes{},
Virt: []*resources.VirtRes{},
},
//Collector: []collectorResConfig{},
//Edges: []Edge{},
Comment: "comment!",
//Hostname: "???",
//Remote: "???",
}
return gc
}
// Run runs an embedded mgmt server.
func Run() error {
obj := &mgmt.Main{}
obj.Program = "mgmtlib" // TODO: set on compilation
obj.Version = "0.0.1" // TODO: set on compilation
obj.TmpPrefix = true
obj.IdealClusterSize = -1
obj.ConvergedTimeout = -1
obj.Noop = true
obj.GAPI = generateGraphConfig // graph API function
if err := obj.Init(); err != nil {
return err
}
go func() {
for {
log.Printf("Generating new graph...")
obj.Switch(generateGraphConfig) // pass in function to run...
time.Sleep(15 * time.Second) // XXX: arbitrarily change graph every 30 seconds
}
}()
// install the exit signal handler
exit := make(chan struct{})
defer close(exit)
go func() {
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt) // catch ^C
//signal.Notify(signals, os.Kill) // catch signals
signal.Notify(signals, syscall.SIGTERM)
select {
case sig := <-signals: // any signal will do
if sig == os.Interrupt {
log.Println("Interrupted by ^C")
obj.Exit(nil)
return
}
log.Println("Interrupted by signal")
obj.Exit(fmt.Errorf("Killed by %v", sig))
return
case <-exit:
return
}
}()
if err := obj.Run(); err != nil {
return err
}
return nil
}
func main() {
log.Printf("Hello!")
if err := Run(); err != nil {
fmt.Println(err)
os.Exit(1)
return
}
log.Printf("Goodbye!")
}