engine, gapi, lang, lib: Plumb through new local API
This is a new API that is similar in spirit and plumbing to the World API, but it intended for all local machine operations and will likely only ever have one implementation.
This commit is contained in:
@@ -28,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/purpleidea/mgmt/converger"
|
"github.com/purpleidea/mgmt/converger"
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
"github.com/purpleidea/mgmt/util/errwrap"
|
"github.com/purpleidea/mgmt/util/errwrap"
|
||||||
@@ -47,6 +48,7 @@ type Engine struct {
|
|||||||
Hostname string
|
Hostname string
|
||||||
|
|
||||||
Converger *converger.Coordinator
|
Converger *converger.Coordinator
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
|
|
||||||
// Prefix is a unique directory prefix which can be used. It should be
|
// Prefix is a unique directory prefix which can be used. It should be
|
||||||
@@ -224,6 +226,7 @@ func (obj *Engine) Commit() error {
|
|||||||
Hostname: obj.Hostname,
|
Hostname: obj.Hostname,
|
||||||
|
|
||||||
//Converger: obj.Converger,
|
//Converger: obj.Converger,
|
||||||
|
Local: obj.Local,
|
||||||
World: obj.World,
|
World: obj.World,
|
||||||
Prefix: statePrefix,
|
Prefix: statePrefix,
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/purpleidea/mgmt/converger"
|
"github.com/purpleidea/mgmt/converger"
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
"github.com/purpleidea/mgmt/util/errwrap"
|
"github.com/purpleidea/mgmt/util/errwrap"
|
||||||
@@ -46,6 +47,7 @@ type State struct {
|
|||||||
|
|
||||||
//Converger *converger.Coordinator
|
//Converger *converger.Coordinator
|
||||||
|
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
|
|
||||||
// Prefix is a unique directory prefix which can be used. It should be
|
// Prefix is a unique directory prefix which can be used. It should be
|
||||||
@@ -239,6 +241,7 @@ func (obj *State) Init() error {
|
|||||||
return graph, nil // we return in a func so it's fresh!
|
return graph, nil // we return in a func so it's fresh!
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Local: obj.Local,
|
||||||
World: obj.World,
|
World: obj.World,
|
||||||
VarDir: obj.varDir,
|
VarDir: obj.varDir,
|
||||||
|
|
||||||
|
|||||||
36
engine/local/local.go
Normal file
36
engine/local/local.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// Mgmt
|
||||||
|
// Copyright (C) 2013-2023+ James Shubin and the project contributors
|
||||||
|
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Package local contains functions and interfaces that are shared between
|
||||||
|
// functions and resources. It's similar to the "world" functionality, except
|
||||||
|
// that it only involves local operations that stay within a single machine or
|
||||||
|
// local mgmt instance.
|
||||||
|
package local
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// API implements the base handle for all the methods in this package. If we
|
||||||
|
// were going to have more than one implementation for all of these, then this
|
||||||
|
// would be an interface instead, and different packages would implement it.
|
||||||
|
// Since this is not the expectation for the local API, it's all self-contained.
|
||||||
|
type API struct {
|
||||||
|
Prefix string
|
||||||
|
Debug bool
|
||||||
|
Logf func(format string, v ...interface{})
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
"github.com/purpleidea/mgmt/util/errwrap"
|
"github.com/purpleidea/mgmt/util/errwrap"
|
||||||
|
|
||||||
@@ -135,6 +136,11 @@ type Init struct {
|
|||||||
|
|
||||||
// TODO: GraphQuery offers an interface to query the resource graph.
|
// TODO: GraphQuery offers an interface to query the resource graph.
|
||||||
|
|
||||||
|
// Local has a bunch of methods and properties which are useful for
|
||||||
|
// operations on the local machine and for communication between
|
||||||
|
// functions and resources.
|
||||||
|
Local *local.API
|
||||||
|
|
||||||
// World provides a connection to the outside world. This is most often
|
// World provides a connection to the outside world. This is most often
|
||||||
// used for communicating with the distributed database.
|
// used for communicating with the distributed database.
|
||||||
World World
|
World World
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@@ -72,6 +73,7 @@ type Data struct {
|
|||||||
Program string // name of the originating program
|
Program string // name of the originating program
|
||||||
Version string // version of the originating program
|
Version string // version of the originating program
|
||||||
Hostname string // uuid for the host, required for GAPI
|
Hostname string // uuid for the host, required for GAPI
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
Noop bool
|
Noop bool
|
||||||
NoStreamWatch bool
|
NoStreamWatch bool
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
"github.com/purpleidea/mgmt/lang/funcs/structs"
|
"github.com/purpleidea/mgmt/lang/funcs/structs"
|
||||||
"github.com/purpleidea/mgmt/lang/interfaces"
|
"github.com/purpleidea/mgmt/lang/interfaces"
|
||||||
"github.com/purpleidea/mgmt/lang/types"
|
"github.com/purpleidea/mgmt/lang/types"
|
||||||
@@ -44,6 +45,7 @@ type Engine struct {
|
|||||||
Name string
|
Name string
|
||||||
|
|
||||||
Hostname string
|
Hostname string
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
|
|
||||||
Debug bool
|
Debug bool
|
||||||
@@ -289,6 +291,7 @@ func (obj *Engine) addVertex(f interfaces.Func) error {
|
|||||||
Input: node.input,
|
Input: node.input,
|
||||||
Output: node.output,
|
Output: node.output,
|
||||||
Txn: node.txn,
|
Txn: node.txn,
|
||||||
|
Local: obj.Local,
|
||||||
World: obj.World,
|
World: obj.World,
|
||||||
Debug: obj.Debug,
|
Debug: obj.Debug,
|
||||||
Logf: func(format string, v ...interface{}) {
|
Logf: func(format string, v ...interface{}) {
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ func (obj *GAPI) Cli(cliInfo *gapi.CliInfo) (*gapi.Deploy, error) {
|
|||||||
LexParser: parser.LexParse,
|
LexParser: parser.LexParse,
|
||||||
Downloader: downloader,
|
Downloader: downloader,
|
||||||
StrInterpolater: interpolate.StrInterpolate,
|
StrInterpolater: interpolate.StrInterpolate,
|
||||||
|
//Local: obj.Local, // TODO: do we need this?
|
||||||
//World: obj.World, // TODO: do we need this?
|
//World: obj.World, // TODO: do we need this?
|
||||||
|
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
@@ -467,6 +468,7 @@ func (obj *GAPI) LangInit() error {
|
|||||||
Input: input,
|
Input: input,
|
||||||
|
|
||||||
Hostname: obj.data.Hostname,
|
Hostname: obj.data.Hostname,
|
||||||
|
Local: obj.data.Local,
|
||||||
World: obj.data.World,
|
World: obj.data.World,
|
||||||
Debug: obj.data.Debug,
|
Debug: obj.data.Debug,
|
||||||
Logf: func(format string, v ...interface{}) {
|
Logf: func(format string, v ...interface{}) {
|
||||||
@@ -747,6 +749,7 @@ func (obj *GAPI) Get(getInfo *gapi.GetInfo) error {
|
|||||||
LexParser: parser.LexParse,
|
LexParser: parser.LexParse,
|
||||||
Downloader: downloader,
|
Downloader: downloader,
|
||||||
StrInterpolater: interpolate.StrInterpolate,
|
StrInterpolater: interpolate.StrInterpolate,
|
||||||
|
//Local: obj.Local, // TODO: do we need this?
|
||||||
//World: obj.World, // TODO: do we need this?
|
//World: obj.World, // TODO: do we need this?
|
||||||
|
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
"github.com/purpleidea/mgmt/lang/types"
|
"github.com/purpleidea/mgmt/lang/types"
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
)
|
)
|
||||||
@@ -61,6 +62,8 @@ type Init struct {
|
|||||||
Txn Txn
|
Txn Txn
|
||||||
|
|
||||||
// TODO: should we pass in a *Scope here for functions like template() ?
|
// TODO: should we pass in a *Scope here for functions like template() ?
|
||||||
|
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
|
|
||||||
Debug bool
|
Debug bool
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
"github.com/purpleidea/mgmt/engine/graph"
|
"github.com/purpleidea/mgmt/engine/graph"
|
||||||
"github.com/purpleidea/mgmt/engine/graph/autoedge"
|
"github.com/purpleidea/mgmt/engine/graph/autoedge"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
engineUtil "github.com/purpleidea/mgmt/engine/util"
|
||||||
"github.com/purpleidea/mgmt/etcd"
|
"github.com/purpleidea/mgmt/etcd"
|
||||||
"github.com/purpleidea/mgmt/lang/ast"
|
"github.com/purpleidea/mgmt/lang/ast"
|
||||||
@@ -717,6 +718,15 @@ func TestAstFunc2(t *testing.T) {
|
|||||||
afs := &afero.Afero{Fs: mmFs} // wrap so that we're implementing ioutil
|
afs := &afero.Afero{Fs: mmFs} // wrap so that we're implementing ioutil
|
||||||
fs := &util.Fs{Afero: afs}
|
fs := &util.Fs{Afero: afs}
|
||||||
|
|
||||||
|
// implementation of the Local API (we only expect just this single one)
|
||||||
|
localAPI := &local.API{
|
||||||
|
Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "local")),
|
||||||
|
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
||||||
|
Logf: func(format string, v ...interface{}) {
|
||||||
|
logf("local: api: "+format, v...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// implementation of the World API (alternatives can be substituted in)
|
// implementation of the World API (alternatives can be substituted in)
|
||||||
world := &etcd.World{
|
world := &etcd.World{
|
||||||
//Hostname: hostname,
|
//Hostname: hostname,
|
||||||
@@ -1011,6 +1021,7 @@ func TestAstFunc2(t *testing.T) {
|
|||||||
funcs := &dage.Engine{
|
funcs := &dage.Engine{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Hostname: "", // NOTE: empty b/c not used
|
Hostname: "", // NOTE: empty b/c not used
|
||||||
|
Local: localAPI, // used partially in some tests
|
||||||
World: world, // used partially in some tests
|
World: world, // used partially in some tests
|
||||||
//Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "funcs")),
|
//Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "funcs")),
|
||||||
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
||||||
@@ -1479,6 +1490,15 @@ func TestAstFunc3(t *testing.T) {
|
|||||||
afs := &afero.Afero{Fs: mmFs} // wrap so that we're implementing ioutil
|
afs := &afero.Afero{Fs: mmFs} // wrap so that we're implementing ioutil
|
||||||
fs := &util.Fs{Afero: afs}
|
fs := &util.Fs{Afero: afs}
|
||||||
|
|
||||||
|
// implementation of the Local API (we only expect just this single one)
|
||||||
|
localAPI := &local.API{
|
||||||
|
Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "local")),
|
||||||
|
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
||||||
|
Logf: func(format string, v ...interface{}) {
|
||||||
|
logf("local: api: "+format, v...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// implementation of the World API (alternatives can be substituted in)
|
// implementation of the World API (alternatives can be substituted in)
|
||||||
world := &etcd.World{
|
world := &etcd.World{
|
||||||
//Hostname: hostname,
|
//Hostname: hostname,
|
||||||
@@ -1773,6 +1793,7 @@ func TestAstFunc3(t *testing.T) {
|
|||||||
funcs := &dage.Engine{
|
funcs := &dage.Engine{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Hostname: "", // NOTE: empty b/c not used
|
Hostname: "", // NOTE: empty b/c not used
|
||||||
|
Local: localAPI, // used partially in some tests
|
||||||
World: world, // used partially in some tests
|
World: world, // used partially in some tests
|
||||||
//Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "funcs")),
|
//Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "funcs")),
|
||||||
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
Debug: testing.Verbose(), // set via the -test.v flag to `go test`
|
||||||
@@ -2004,6 +2025,7 @@ func TestAstFunc3(t *testing.T) {
|
|||||||
//Version: obj.Version,
|
//Version: obj.Version,
|
||||||
Hostname: "localhost",
|
Hostname: "localhost",
|
||||||
Converger: converger,
|
Converger: converger,
|
||||||
|
Local: localAPI,
|
||||||
World: world,
|
World: world,
|
||||||
Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "engine")),
|
Prefix: fmt.Sprintf("%s/", filepath.Join(tmpdir, "engine")),
|
||||||
Debug: testing.Verbose(),
|
Debug: testing.Verbose(),
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
"github.com/purpleidea/mgmt/lang/ast"
|
"github.com/purpleidea/mgmt/lang/ast"
|
||||||
_ "github.com/purpleidea/mgmt/lang/funcs/core" // import so the funcs register
|
_ "github.com/purpleidea/mgmt/lang/funcs/core" // import so the funcs register
|
||||||
"github.com/purpleidea/mgmt/lang/funcs/dage"
|
"github.com/purpleidea/mgmt/lang/funcs/dage"
|
||||||
@@ -57,6 +58,7 @@ type Lang struct {
|
|||||||
Input string
|
Input string
|
||||||
|
|
||||||
Hostname string
|
Hostname string
|
||||||
|
Local *local.API
|
||||||
World engine.World
|
World engine.World
|
||||||
Prefix string
|
Prefix string
|
||||||
Debug bool
|
Debug bool
|
||||||
@@ -139,6 +141,7 @@ func (obj *Lang) Init() error {
|
|||||||
LexParser: parser.LexParse,
|
LexParser: parser.LexParse,
|
||||||
Downloader: nil, // XXX: is this used here?
|
Downloader: nil, // XXX: is this used here?
|
||||||
StrInterpolater: interpolate.StrInterpolate,
|
StrInterpolater: interpolate.StrInterpolate,
|
||||||
|
//Local: obj.Local, // TODO: do we need this?
|
||||||
//World: obj.World, // TODO: do we need this?
|
//World: obj.World, // TODO: do we need this?
|
||||||
|
|
||||||
Prefix: obj.Prefix,
|
Prefix: obj.Prefix,
|
||||||
@@ -237,6 +240,7 @@ func (obj *Lang) Init() error {
|
|||||||
obj.funcs = &dage.Engine{
|
obj.funcs = &dage.Engine{
|
||||||
Name: "lang", // TODO: arbitrary name for now
|
Name: "lang", // TODO: arbitrary name for now
|
||||||
Hostname: obj.Hostname,
|
Hostname: obj.Hostname,
|
||||||
|
Local: obj.Local,
|
||||||
World: obj.World,
|
World: obj.World,
|
||||||
//Prefix: fmt.Sprintf("%s/", path.Join(obj.Prefix, "funcs")),
|
//Prefix: fmt.Sprintf("%s/", path.Join(obj.Prefix, "funcs")),
|
||||||
Debug: obj.Debug,
|
Debug: obj.Debug,
|
||||||
|
|||||||
12
lib/main.go
12
lib/main.go
@@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/purpleidea/mgmt/engine"
|
"github.com/purpleidea/mgmt/engine"
|
||||||
"github.com/purpleidea/mgmt/engine/graph"
|
"github.com/purpleidea/mgmt/engine/graph"
|
||||||
"github.com/purpleidea/mgmt/engine/graph/autogroup"
|
"github.com/purpleidea/mgmt/engine/graph/autogroup"
|
||||||
|
"github.com/purpleidea/mgmt/engine/local"
|
||||||
_ "github.com/purpleidea/mgmt/engine/resources" // let register's run
|
_ "github.com/purpleidea/mgmt/engine/resources" // let register's run
|
||||||
"github.com/purpleidea/mgmt/etcd"
|
"github.com/purpleidea/mgmt/etcd"
|
||||||
"github.com/purpleidea/mgmt/etcd/chooser"
|
"github.com/purpleidea/mgmt/etcd/chooser"
|
||||||
@@ -475,6 +476,15 @@ func (obj *Main) Run() error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// implementation of the Local API (we only expect just this single one)
|
||||||
|
localAPI := &local.API{
|
||||||
|
Prefix: fmt.Sprintf("%s/", path.Join(prefix, "local")),
|
||||||
|
Debug: obj.Flags.Debug,
|
||||||
|
Logf: func(format string, v ...interface{}) {
|
||||||
|
log.Printf("local: api: "+format, v...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// implementation of the World API (alternatives can be substituted in)
|
// implementation of the World API (alternatives can be substituted in)
|
||||||
world := &etcd.World{
|
world := &etcd.World{
|
||||||
Hostname: hostname,
|
Hostname: hostname,
|
||||||
@@ -493,6 +503,7 @@ func (obj *Main) Run() error {
|
|||||||
Version: obj.Version,
|
Version: obj.Version,
|
||||||
Hostname: hostname,
|
Hostname: hostname,
|
||||||
Converger: converger,
|
Converger: converger,
|
||||||
|
Local: localAPI,
|
||||||
World: world,
|
World: world,
|
||||||
Prefix: fmt.Sprintf("%s/", path.Join(prefix, "engine")),
|
Prefix: fmt.Sprintf("%s/", path.Join(prefix, "engine")),
|
||||||
//Prometheus: prom, // TODO: implement this via a general Status API
|
//Prometheus: prom, // TODO: implement this via a general Status API
|
||||||
@@ -582,6 +593,7 @@ func (obj *Main) Run() error {
|
|||||||
Program: obj.Program,
|
Program: obj.Program,
|
||||||
Version: obj.Version,
|
Version: obj.Version,
|
||||||
Hostname: hostname,
|
Hostname: hostname,
|
||||||
|
Local: localAPI,
|
||||||
World: world,
|
World: world,
|
||||||
Noop: mainDeploy.Noop,
|
Noop: mainDeploy.Noop,
|
||||||
// FIXME: should the below flags come from the deploy struct?
|
// FIXME: should the below flags come from the deploy struct?
|
||||||
|
|||||||
Reference in New Issue
Block a user