Add some of the pkg and svc autoedge logic
This adds another chunk of it, and makes some other small fixes.
This commit is contained in:
29
examples/autoedges3.yaml
Normal file
29
examples/autoedges3.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
graph: mygraph
|
||||
resources:
|
||||
pkg:
|
||||
- name: drbd-utils
|
||||
meta:
|
||||
autoedge: true
|
||||
state: installed
|
||||
file:
|
||||
- name: file1
|
||||
meta:
|
||||
autoedge: true
|
||||
path: "/etc/drbd.conf"
|
||||
content: |
|
||||
# this is an mgmt test
|
||||
state: exists
|
||||
- name: file2
|
||||
meta:
|
||||
autoedge: true
|
||||
path: "/etc/drbd.d/"
|
||||
content: |
|
||||
i am a directory
|
||||
state: exists
|
||||
svc:
|
||||
- name: drbd
|
||||
meta:
|
||||
autoedge: true
|
||||
state: stopped
|
||||
edges: []
|
||||
134
misc_test.go
134
misc_test.go
@@ -656,4 +656,138 @@ func TestMiscT11(t *testing.T) {
|
||||
if !reflect.DeepEqual(ex9, out9) {
|
||||
t.Errorf("RemoveCommonFilePrefixes expected: %v; got: %v.", ex9, out9)
|
||||
}
|
||||
|
||||
in10 := []string{
|
||||
"/etc/drbd.conf",
|
||||
"/etc/drbd.d/", // watch me, i'm a dir
|
||||
"/etc/drbd.d/global_common.conf", // and watch me i'm a file!
|
||||
"/lib/drbd/drbd",
|
||||
"/lib/drbd/drbdadm-83",
|
||||
"/lib/drbd/drbdadm-84",
|
||||
"/lib/drbd/drbdsetup-83",
|
||||
"/lib/drbd/drbdsetup-84",
|
||||
"/usr/lib/drbd/crm-fence-peer.sh",
|
||||
"/usr/lib/drbd/crm-unfence-peer.sh",
|
||||
"/usr/lib/drbd/notify-emergency-reboot.sh",
|
||||
"/usr/lib/drbd/notify-emergency-shutdown.sh",
|
||||
"/usr/lib/drbd/notify-io-error.sh",
|
||||
"/usr/lib/drbd/notify-out-of-sync.sh",
|
||||
"/usr/lib/drbd/notify-pri-lost-after-sb.sh",
|
||||
"/usr/lib/drbd/notify-pri-lost.sh",
|
||||
"/usr/lib/drbd/notify-pri-on-incon-degr.sh",
|
||||
"/usr/lib/drbd/notify-split-brain.sh",
|
||||
"/usr/lib/drbd/notify.sh",
|
||||
"/usr/lib/drbd/outdate-peer.sh",
|
||||
"/usr/lib/drbd/rhcs_fence",
|
||||
"/usr/lib/drbd/snapshot-resync-target-lvm.sh",
|
||||
"/usr/lib/drbd/stonith_admin-fence-peer.sh",
|
||||
"/usr/lib/drbd/unsnapshot-resync-target-lvm.sh",
|
||||
"/usr/lib/systemd/system/drbd.service",
|
||||
"/usr/lib/tmpfiles.d/drbd.conf",
|
||||
"/usr/sbin/drbd-overview",
|
||||
"/usr/sbin/drbdadm",
|
||||
"/usr/sbin/drbdmeta",
|
||||
"/usr/sbin/drbdsetup",
|
||||
"/usr/share/doc/drbd-utils/", // watch me, i'm a dir too
|
||||
"/usr/share/doc/drbd-utils/COPYING",
|
||||
"/usr/share/doc/drbd-utils/ChangeLog",
|
||||
"/usr/share/doc/drbd-utils/README",
|
||||
"/usr/share/doc/drbd-utils/drbd.conf.example",
|
||||
"/usr/share/man/man5/drbd.conf-8.3.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf-8.4.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf-9.0.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf.5.gz",
|
||||
"/usr/share/man/man8/drbd-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbd-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbd-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbd-overview-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbd-overview.8.gz",
|
||||
"/usr/share/man/man8/drbd.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdadm.8.gz",
|
||||
"/usr/share/man/man8/drbddisk-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbddisk-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup.8.gz",
|
||||
"/var/lib/drbd",
|
||||
}
|
||||
ex10 := []string{
|
||||
"/etc/drbd.conf",
|
||||
"/etc/drbd.d/global_common.conf",
|
||||
"/lib/drbd/drbd",
|
||||
"/lib/drbd/drbdadm-83",
|
||||
"/lib/drbd/drbdadm-84",
|
||||
"/lib/drbd/drbdsetup-83",
|
||||
"/lib/drbd/drbdsetup-84",
|
||||
"/usr/lib/drbd/crm-fence-peer.sh",
|
||||
"/usr/lib/drbd/crm-unfence-peer.sh",
|
||||
"/usr/lib/drbd/notify-emergency-reboot.sh",
|
||||
"/usr/lib/drbd/notify-emergency-shutdown.sh",
|
||||
"/usr/lib/drbd/notify-io-error.sh",
|
||||
"/usr/lib/drbd/notify-out-of-sync.sh",
|
||||
"/usr/lib/drbd/notify-pri-lost-after-sb.sh",
|
||||
"/usr/lib/drbd/notify-pri-lost.sh",
|
||||
"/usr/lib/drbd/notify-pri-on-incon-degr.sh",
|
||||
"/usr/lib/drbd/notify-split-brain.sh",
|
||||
"/usr/lib/drbd/notify.sh",
|
||||
"/usr/lib/drbd/outdate-peer.sh",
|
||||
"/usr/lib/drbd/rhcs_fence",
|
||||
"/usr/lib/drbd/snapshot-resync-target-lvm.sh",
|
||||
"/usr/lib/drbd/stonith_admin-fence-peer.sh",
|
||||
"/usr/lib/drbd/unsnapshot-resync-target-lvm.sh",
|
||||
"/usr/lib/systemd/system/drbd.service",
|
||||
"/usr/lib/tmpfiles.d/drbd.conf",
|
||||
"/usr/sbin/drbd-overview",
|
||||
"/usr/sbin/drbdadm",
|
||||
"/usr/sbin/drbdmeta",
|
||||
"/usr/sbin/drbdsetup",
|
||||
"/usr/share/doc/drbd-utils/COPYING",
|
||||
"/usr/share/doc/drbd-utils/ChangeLog",
|
||||
"/usr/share/doc/drbd-utils/README",
|
||||
"/usr/share/doc/drbd-utils/drbd.conf.example",
|
||||
"/usr/share/man/man5/drbd.conf-8.3.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf-8.4.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf-9.0.5.gz",
|
||||
"/usr/share/man/man5/drbd.conf.5.gz",
|
||||
"/usr/share/man/man8/drbd-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbd-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbd-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbd-overview-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbd-overview.8.gz",
|
||||
"/usr/share/man/man8/drbd.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdadm-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdadm.8.gz",
|
||||
"/usr/share/man/man8/drbddisk-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbddisk-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdmeta.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-8.3.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-8.4.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup-9.0.8.gz",
|
||||
"/usr/share/man/man8/drbdsetup.8.gz",
|
||||
"/var/lib/drbd",
|
||||
}
|
||||
sort.Strings(ex10)
|
||||
out10 := RemoveCommonFilePrefixes(in10)
|
||||
sort.Strings(out10)
|
||||
if !reflect.DeepEqual(ex10, out10) {
|
||||
t.Errorf("RemoveCommonFilePrefixes expected: %v; got: %v.", ex10, out10)
|
||||
for i := 0; i < len(ex10); i++ {
|
||||
if ex10[i] != out10[i] {
|
||||
t.Errorf("# %d: %v <> %v", i, ex10[i], out10[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,16 +196,10 @@ func (bus *Conn) matchSignal(ch chan *dbus.Signal, path dbus.ObjectPath, iface s
|
||||
if call.Err != nil {
|
||||
return call.Err
|
||||
}
|
||||
if PK_DEBUG {
|
||||
log.Println("PackageKit: matchSignal(): Added!")
|
||||
}
|
||||
// The caller has to make sure that ch is sufficiently buffered; if a
|
||||
// message arrives when a write to c is not possible, it is discarded!
|
||||
// This can be disastrous if we're waiting for a "Finished" signal!
|
||||
bus.GetBus().Signal(ch)
|
||||
if PK_DEBUG {
|
||||
log.Println("PackageKit: matchSignal(): Success!")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -411,11 +405,9 @@ loop:
|
||||
// a package was installed...
|
||||
// only start the timer once we're here...
|
||||
timeout = PkSignalPackageTimeout
|
||||
continue loop
|
||||
} else if signal.Name == FmtTransactionMethod("Finished") {
|
||||
finished = true
|
||||
timeout = PkSignalDestroyTimeout // wait a bit
|
||||
continue loop
|
||||
} else if signal.Name == FmtTransactionMethod("Destroy") {
|
||||
return nil // success
|
||||
} else {
|
||||
@@ -508,8 +500,6 @@ loop:
|
||||
if signal.Name == FmtTransactionMethod("ErrorCode") {
|
||||
return errors.New(fmt.Sprintf("PackageKit: Error: %v", signal.Body))
|
||||
} else if signal.Name == FmtTransactionMethod("Package") {
|
||||
// a package was installed...
|
||||
continue loop
|
||||
} else if signal.Name == FmtTransactionMethod("Finished") {
|
||||
// TODO: should we wait for the Destroy signal?
|
||||
break loop
|
||||
@@ -574,8 +564,6 @@ loop:
|
||||
continue loop // failed conversion
|
||||
}
|
||||
files[key] = fileList // build up map
|
||||
|
||||
continue loop
|
||||
} else if signal.Name == FmtTransactionMethod("Finished") {
|
||||
// TODO: should we wait for the Destroy signal?
|
||||
break loop
|
||||
@@ -593,6 +581,9 @@ loop:
|
||||
|
||||
// get list of packages that are installed and which can be updated, mod filter
|
||||
func (bus *Conn) GetUpdates(filter uint64) ([]string, error) {
|
||||
if PK_DEBUG {
|
||||
log.Println("PackageKit: GetUpdates()")
|
||||
}
|
||||
packageIds := []string{}
|
||||
ch := make(chan *dbus.Signal, PkBufferSize) // we need to buffer :(
|
||||
interfacePath, err := bus.CreateTransaction()
|
||||
@@ -635,7 +626,6 @@ loop:
|
||||
}
|
||||
}
|
||||
packageIds = append(packageIds, packageId)
|
||||
|
||||
} else if signal.Name == FmtTransactionMethod("Finished") {
|
||||
// TODO: should we wait for the Destroy signal?
|
||||
break loop
|
||||
@@ -708,8 +698,9 @@ func (bus *Conn) PackagesToPackageIds(packageMap map[string]string, filter uint6
|
||||
return nil, errors.New(fmt.Sprintf("Empty package state for %v", pkg))
|
||||
}
|
||||
found[index] = true
|
||||
stateIsVersion := (state != "installed" && state != "uninstalled" && state != "newest") // must be a ver. string
|
||||
|
||||
if state != "installed" && state != "uninstalled" && state != "newest" { // must be a ver. string
|
||||
if stateIsVersion {
|
||||
if state == ver && ver != "" { // we match what we want...
|
||||
usePackageId[index] = packageId
|
||||
}
|
||||
@@ -718,11 +709,13 @@ func (bus *Conn) PackagesToPackageIds(packageMap map[string]string, filter uint6
|
||||
if FlagInData("installed", data) {
|
||||
installed[index] = true
|
||||
version[index] = ver
|
||||
if state == "uninstalled" {
|
||||
// state of "uninstalled" matched during CheckApply, and
|
||||
// states of "installed" and "newest" for fileList
|
||||
if !stateIsVersion {
|
||||
usePackageId[index] = packageId // save for later
|
||||
}
|
||||
} else { // not installed...
|
||||
if state == "installed" || state == "newest" {
|
||||
if !stateIsVersion {
|
||||
// if there is more than one result, eg: there
|
||||
// is the old and newest version of a package,
|
||||
// then this section can run more than once...
|
||||
|
||||
186
pkg.go
186
pkg.go
@@ -22,15 +22,18 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PkgRes struct {
|
||||
BaseRes `yaml:",inline"`
|
||||
State string `yaml:"state"` // state: installed, uninstalled, newest, <version>
|
||||
AllowUntrusted bool `yaml:"allowuntrusted"` // allow untrusted packages to be installed?
|
||||
AllowNonFree bool `yaml:"allownonfree"` // allow nonfree packages to be found?
|
||||
AllowUnsupported bool `yaml:"allowunsupported"` // allow unsupported packages to be found?
|
||||
fileList []string // FIXME: update if pkg changes
|
||||
State string `yaml:"state"` // state: installed, uninstalled, newest, <version>
|
||||
AllowUntrusted bool `yaml:"allowuntrusted"` // allow untrusted packages to be installed?
|
||||
AllowNonFree bool `yaml:"allownonfree"` // allow nonfree packages to be found?
|
||||
AllowUnsupported bool `yaml:"allowunsupported"` // allow unsupported packages to be found?
|
||||
//bus *Conn // pk bus connection
|
||||
fileList []string // FIXME: update if pkg changes
|
||||
}
|
||||
|
||||
// helper function for creating new pkg resources that calls Init()
|
||||
@@ -53,10 +56,35 @@ func NewPkgRes(name, state string, allowuntrusted, allownonfree, allowunsupporte
|
||||
func (obj *PkgRes) Init() {
|
||||
obj.BaseRes.kind = "Pkg"
|
||||
obj.BaseRes.Init() // call base init, b/c we're overriding
|
||||
|
||||
bus := NewBus()
|
||||
if bus == nil {
|
||||
log.Fatal("Can't connect to PackageKit bus.")
|
||||
}
|
||||
defer bus.Close()
|
||||
|
||||
data, err := obj.PkgMappingHelper(bus)
|
||||
if err != nil {
|
||||
// FIXME: return error?
|
||||
log.Fatalf("The PkgMappingHelper failed with: %v.", err)
|
||||
return
|
||||
}
|
||||
|
||||
packageIds := []string{data.PackageId} // just one for now
|
||||
filesMap, err := bus.GetFilesByPackageId(packageIds)
|
||||
if err != nil {
|
||||
// FIXME: return error?
|
||||
log.Fatalf("Can't run GetFilesByPackageId: %v", err)
|
||||
return
|
||||
}
|
||||
if files, ok := filesMap[data.PackageId]; ok {
|
||||
obj.fileList = DirifyFileList(files, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (obj *PkgRes) Kind() string {
|
||||
return "Pkg"
|
||||
// XXX: run this when resource exits
|
||||
func (obj *PkgRes) Close() {
|
||||
//obj.bus.Close()
|
||||
}
|
||||
|
||||
func (obj *PkgRes) Validate() bool {
|
||||
@@ -143,22 +171,7 @@ func (obj *PkgRes) Watch() {
|
||||
}
|
||||
}
|
||||
|
||||
func (obj *PkgRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
log.Printf("%v[%v]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
||||
|
||||
if obj.State == "" { // TODO: Validate() should replace this check!
|
||||
log.Fatalf("%v[%v]: Package state is undefined!", obj.Kind(), obj.GetName())
|
||||
}
|
||||
|
||||
if obj.isStateOK { // cache the state
|
||||
return true, nil
|
||||
}
|
||||
|
||||
bus := NewBus()
|
||||
if bus == nil {
|
||||
return false, errors.New("Can't connect to PackageKit bus.")
|
||||
}
|
||||
defer bus.Close()
|
||||
func (obj *PkgRes) PkgMappingHelper(bus *Conn) (*PkPackageIdActionData, error) {
|
||||
|
||||
var packageMap = map[string]string{
|
||||
obj.Name: obj.State, // key is pkg name, value is pkg state
|
||||
@@ -180,16 +193,41 @@ func (obj *PkgRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
}
|
||||
result, e := bus.PackagesToPackageIds(packageMap, filter)
|
||||
if e != nil {
|
||||
return false, errors.New(fmt.Sprintf("PackagesToPackageIds error: %v", e))
|
||||
return nil, errors.New(fmt.Sprintf("Can't run PackagesToPackageIds: %v", e))
|
||||
}
|
||||
|
||||
data, ok := result[obj.Name] // lookup single package
|
||||
// package doesn't exist, this is an error!
|
||||
if !ok || !data.Found {
|
||||
return false, errors.New(fmt.Sprintf("Can't find package named '%s'.", obj.Name))
|
||||
return nil, errors.New(fmt.Sprintf("Can't find package named '%s'.", obj.Name))
|
||||
}
|
||||
|
||||
//obj.State == "installed" || "uninstalled" || "newest" || "4.2-1.fc23"
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (obj *PkgRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
log.Printf("%v[%v]: CheckApply(%t)", obj.Kind(), obj.GetName(), apply)
|
||||
|
||||
if obj.State == "" { // TODO: Validate() should replace this check!
|
||||
log.Fatalf("%v[%v]: Package state is undefined!", obj.Kind(), obj.GetName())
|
||||
}
|
||||
|
||||
if obj.isStateOK { // cache the state
|
||||
return true, nil
|
||||
}
|
||||
|
||||
bus := NewBus()
|
||||
if bus == nil {
|
||||
return false, errors.New("Can't connect to PackageKit bus.")
|
||||
}
|
||||
defer bus.Close()
|
||||
|
||||
data, err := obj.PkgMappingHelper(bus)
|
||||
if err != nil {
|
||||
return false, errors.New(fmt.Sprintf("The PkgMappingHelper failed with: %v.", err))
|
||||
}
|
||||
|
||||
// obj.State == "installed" || "uninstalled" || "newest" || "4.2-1.fc23"
|
||||
switch obj.State {
|
||||
case "installed":
|
||||
if data.Installed {
|
||||
@@ -248,8 +286,26 @@ func (obj *PkgRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
return false, nil // success
|
||||
}
|
||||
|
||||
type PkgUUID struct {
|
||||
BaseUUID
|
||||
name string // pkg name
|
||||
state string // pkg state or "version"
|
||||
}
|
||||
|
||||
// if and only if they are equivalent, return true
|
||||
// if they are not equivalent, return false
|
||||
func (obj *PkgUUID) IFF(uuid ResUUID) bool {
|
||||
res, ok := uuid.(*PkgUUID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// FIXME: match on obj.state vs. res.state ?
|
||||
return obj.name == res.name
|
||||
}
|
||||
|
||||
type PkgResAutoEdges struct {
|
||||
fileList []string
|
||||
svcUUIDs []ResUUID
|
||||
testIsNext bool // safety
|
||||
name string // saved data from PkgRes obj
|
||||
kind string
|
||||
@@ -260,8 +316,13 @@ func (obj *PkgResAutoEdges) Next() []ResUUID {
|
||||
log.Fatal("Expecting a call to Test()")
|
||||
}
|
||||
obj.testIsNext = true // set after all the errors paths are past
|
||||
var result []ResUUID
|
||||
|
||||
// first return any matching svcUUIDs
|
||||
if x := obj.svcUUIDs; len(x) > 0 {
|
||||
return x
|
||||
}
|
||||
|
||||
var result []ResUUID
|
||||
// return UUID's for whatever is in obj.fileList
|
||||
for _, x := range obj.fileList {
|
||||
var reversed bool = false // cheat by passing a pointer
|
||||
@@ -281,6 +342,17 @@ func (obj *PkgResAutoEdges) Test(input []bool) bool {
|
||||
if !obj.testIsNext {
|
||||
log.Fatal("Expecting a call to Next()")
|
||||
}
|
||||
|
||||
// ack the svcUUID's...
|
||||
if x := obj.svcUUIDs; len(x) > 0 {
|
||||
if y := len(x); y != len(input) {
|
||||
log.Fatalf("Expecting %d value(s)!", y)
|
||||
}
|
||||
obj.svcUUIDs = []ResUUID{} // empty
|
||||
obj.testIsNext = false
|
||||
return true
|
||||
}
|
||||
|
||||
count := len(obj.fileList)
|
||||
if count != len(input) {
|
||||
log.Fatalf("Expecting %d value(s)!", count)
|
||||
@@ -316,27 +388,29 @@ func (obj *PkgResAutoEdges) Test(input []bool) bool {
|
||||
return true // continue, there are more files!
|
||||
}
|
||||
|
||||
type PkgUUID struct {
|
||||
BaseUUID
|
||||
}
|
||||
|
||||
// if and only if they are equivalent, return true
|
||||
// if they are not equivalent, return false
|
||||
func (obj *PkgUUID) IFF(uuid ResUUID) bool {
|
||||
res, ok := uuid.(*PkgUUID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return obj.name == res.name
|
||||
}
|
||||
|
||||
// produce an object which generates a minimal pkg file optimization sequence
|
||||
func (obj *PkgRes) AutoEdges() AutoEdge {
|
||||
// in contrast with the FileRes AutoEdges() function which contains
|
||||
// more of the mechanics, most of the AutoEdge mechanics for the PkgRes
|
||||
// is contained in the Test() method! This design is completely okay!
|
||||
|
||||
// add matches for any svc resources found in pkg definition!
|
||||
var svcUUIDs []ResUUID
|
||||
for _, x := range ReturnSvcInFileList(obj.fileList) {
|
||||
var reversed bool = false
|
||||
svcUUIDs = append(svcUUIDs, &SvcUUID{
|
||||
BaseUUID: BaseUUID{
|
||||
name: obj.GetName(),
|
||||
kind: obj.Kind(),
|
||||
reversed: &reversed,
|
||||
},
|
||||
name: x, // the svc name itself in the SvcUUID object!
|
||||
}) // build list
|
||||
}
|
||||
|
||||
return &PkgResAutoEdges{
|
||||
fileList: obj.fileList,
|
||||
fileList: RemoveCommonFilePrefixes(obj.fileList), // clean start!
|
||||
svcUUIDs: svcUUIDs,
|
||||
testIsNext: false, // start with Next() call
|
||||
name: obj.GetName(), // save data for PkgResAutoEdges obj
|
||||
kind: obj.Kind(),
|
||||
@@ -347,15 +421,10 @@ func (obj *PkgRes) AutoEdges() AutoEdge {
|
||||
func (obj *PkgRes) GetUUIDs() []ResUUID {
|
||||
x := &PkgUUID{
|
||||
BaseUUID: BaseUUID{name: obj.GetName(), kind: obj.Kind()},
|
||||
name: obj.Name,
|
||||
state: obj.State,
|
||||
}
|
||||
result := []ResUUID{x}
|
||||
for _, path := range obj.fileList {
|
||||
x := &FileUUID{
|
||||
BaseUUID: BaseUUID{name: obj.GetName(), kind: obj.Kind()},
|
||||
path: path,
|
||||
}
|
||||
result = append(result, x)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -383,3 +452,22 @@ func (obj *PkgRes) Compare(res Res) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// return a list of svc names for matches like /usr/lib/systemd/system/*.service
|
||||
func ReturnSvcInFileList(fileList []string) []string {
|
||||
result := []string{}
|
||||
for _, x := range fileList {
|
||||
dirname, basename := path.Split(path.Clean(x))
|
||||
// TODO: do we also want to look for /etc/systemd/system/ ?
|
||||
if dirname != "/usr/lib/systemd/system/" {
|
||||
continue
|
||||
}
|
||||
if !strings.HasSuffix(basename, ".service") {
|
||||
continue
|
||||
}
|
||||
if s := strings.TrimSuffix(basename, ".service"); !StrInList(s, result) {
|
||||
result = append(result, s)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ type ResUUID interface {
|
||||
}
|
||||
|
||||
type BaseUUID struct {
|
||||
name string
|
||||
name string // name and kind are the values of where this is coming from
|
||||
kind string
|
||||
|
||||
reversed *bool // piggyback edge information here
|
||||
@@ -467,6 +467,7 @@ func (obj *NoopRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
|
||||
type NoopUUID struct {
|
||||
BaseUUID
|
||||
name string
|
||||
}
|
||||
|
||||
func (obj *NoopRes) AutoEdges() AutoEdge {
|
||||
@@ -474,10 +475,11 @@ func (obj *NoopRes) AutoEdges() AutoEdge {
|
||||
}
|
||||
|
||||
// include all params to make a unique identification of this object
|
||||
// most resources only return one
|
||||
// most resources only return one, although some resources return multiple
|
||||
func (obj *NoopRes) GetUUIDs() []ResUUID {
|
||||
x := &NoopUUID{
|
||||
BaseUUID: BaseUUID{name: obj.GetName(), kind: obj.Kind()},
|
||||
name: obj.Name,
|
||||
}
|
||||
return []ResUUID{x}
|
||||
}
|
||||
|
||||
72
svc.go
72
svc.go
@@ -310,7 +310,12 @@ func (obj *SvcRes) CheckApply(apply bool) (stateok bool, err error) {
|
||||
}
|
||||
|
||||
type SvcUUID struct {
|
||||
// NOTE: there is also a name variable in the BaseUUID struct, this is
|
||||
// information about where this UUID came from, and is unrelated to the
|
||||
// information about the resource we're matching. That data which is
|
||||
// used in the IFF function, is what you see in the struct fields here.
|
||||
BaseUUID
|
||||
name string // the svc name
|
||||
}
|
||||
|
||||
// if and only if they are equivalent, return true
|
||||
@@ -323,17 +328,74 @@ func (obj *SvcUUID) IFF(uuid ResUUID) bool {
|
||||
return obj.name == res.name
|
||||
}
|
||||
|
||||
type SvcResAutoEdges struct {
|
||||
data []ResUUID
|
||||
pointer int
|
||||
found bool
|
||||
}
|
||||
|
||||
func (obj *SvcResAutoEdges) Next() []ResUUID {
|
||||
if obj.found {
|
||||
log.Fatal("Shouldn't be called anymore!")
|
||||
}
|
||||
if len(obj.data) == 0 { // check length for rare scenarios
|
||||
return nil
|
||||
}
|
||||
value := obj.data[obj.pointer]
|
||||
obj.pointer += 1
|
||||
return []ResUUID{value} // we return one, even though api supports N
|
||||
}
|
||||
|
||||
// get results of the earlier Next() call, return if we should continue!
|
||||
func (obj *SvcResAutoEdges) Test(input []bool) bool {
|
||||
// if there aren't any more remaining
|
||||
if len(obj.data) <= obj.pointer {
|
||||
return false
|
||||
}
|
||||
if obj.found { // already found, done!
|
||||
return false
|
||||
}
|
||||
if len(input) != 1 { // in case we get given bad data
|
||||
log.Fatal("Expecting a single value!")
|
||||
}
|
||||
if input[0] { // if a match is found, we're done!
|
||||
obj.found = true // no more to find!
|
||||
return false
|
||||
}
|
||||
return true // keep going
|
||||
}
|
||||
|
||||
func (obj *SvcRes) AutoEdges() AutoEdge {
|
||||
// TODO: add auto edges to the files that provide the service files,
|
||||
// which might come from a pkg resource perhaps!
|
||||
return nil
|
||||
var data []ResUUID
|
||||
svcFiles := []string{
|
||||
fmt.Sprintf("/etc/systemd/system/%s.service", obj.Name), // takes precedence
|
||||
fmt.Sprintf("/usr/lib/systemd/system/%s.service", obj.Name), // pkg default
|
||||
}
|
||||
for _, x := range svcFiles {
|
||||
var reversed bool = true
|
||||
data = append(data, &FileUUID{
|
||||
BaseUUID: BaseUUID{
|
||||
name: obj.GetName(),
|
||||
kind: obj.Kind(),
|
||||
reversed: &reversed,
|
||||
},
|
||||
path: x, // what matters
|
||||
})
|
||||
}
|
||||
return &FileResAutoEdges{
|
||||
data: data,
|
||||
pointer: 0,
|
||||
found: false,
|
||||
}
|
||||
}
|
||||
|
||||
// include all params to make a unique identification of this object
|
||||
func (obj *SvcRes) GetUUIDs() []ResUUID {
|
||||
x := &SvcUUID{BaseUUID: BaseUUID{name: obj.GetName(), kind: obj.Kind()}}
|
||||
x := &SvcUUID{
|
||||
BaseUUID: BaseUUID{name: obj.GetName(), kind: obj.Kind()},
|
||||
name: obj.Name, // svc name
|
||||
}
|
||||
return []ResUUID{x}
|
||||
|
||||
}
|
||||
|
||||
func (obj *SvcRes) Compare(res Res) bool {
|
||||
|
||||
Reference in New Issue
Block a user