ignores empty structs

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-10-25 14:38:52 -05:00
parent 34edf97565
commit fbd0d35660
1 changed files with 63 additions and 12 deletions

View File

@ -367,6 +367,21 @@ func dumpNonStandardXML(domcfg *libvirtxml.Domain) (string, error) {
if secnormal {
domcfg.SecLabel = nil
}
// ignore Metadata
// this is probably something about what kind of OS you might be running
// todo: get this directly from the disk image
if domcfg.Metadata != nil {
fmt.Printf("Not saving Domain.Metadata: %+v\n", domcfg.Metadata)
domcfg.Metadata = nil
}
// ignore Resource
if domcfg.Resource != nil {
if domcfg.Resource.Partition == "/machine" {
domcfg.Resource = nil
} else {
fmt.Printf("non-standard Domain.Resource: %+v\n", domcfg.Resource)
}
}
// this will move elsewhere in the protobuf someday
// ignore all these for now
@ -650,10 +665,6 @@ func finalEmptyCheck(domcfg *libvirtxml.Domain) (string, error) {
}
if libvirtxmlDomainEmpty(*domcfg) {
log.Info("CPU THIS SHOULD NEVER HAPPEN")
log.Info("CPU THIS SHOULD NEVER HAPPEN")
log.Info("CPU THIS SHOULD NEVER HAPPEN")
// fmt.Println("Domain Devices are empty")
domcfg = nil
return warnUserOfNonStandardXML(domcfg)
}
@ -785,7 +796,7 @@ func libvirtxmlDomainEmpty(mydom libvirtxml.Domain) bool {
// Ensure that we are working with a struct
if v.Kind() == reflect.Struct {
fmt.Println("Fields and values in libvirtxml.DomainDeviceList:")
// fmt.Println("Fields and values in libvirtxml.DomainDeviceList:")
// Loop through each field in the struct
for i := 0; i < v.NumField(); i++ {
@ -796,15 +807,14 @@ func libvirtxmlDomainEmpty(mydom libvirtxml.Domain) bool {
value := v.Field(i)
if !value.IsValid() {
fmt.Printf("Field: %s is nil or invalid\n", field)
continue
}
if (field == "IOThreads") || (field == "XMLName") {
fmt.Printf("Field: %s is nil or invalid\n", field)
fmt.Printf("Field: %s is nil or invalid\n", field)
fmt.Printf("Field: %s is a String with value: %s\n", field, value.String())
fmt.Printf("Field: %s is invalid\n", field)
continue
}
// processed as Domain.Metadata & Domain.Resource
// if (field == "IOThreads") || (field == "XMLName") {
// fmt.Printf("Field: %s is: %s\n", field, value.String())
// continue
// }
// Check if the field is a string, array, or slice
switch value.Kind() {
@ -823,6 +833,15 @@ func libvirtxmlDomainEmpty(mydom libvirtxml.Domain) bool {
fmt.Printf("Field: %s is an Array with length: %d\n", field, value.Len())
empty = false
}
case reflect.Struct:
if IsStructEmptyOrNil(value) {
fmt.Printf("XML Field ignore empty Struct %s\n", field)
} else {
fmt.Printf("Field Struct is not empty %s is %+v\n", field, value)
empty = false
}
case reflect.Uint:
// probably ignore ints. when has that ever gone wrong?
case reflect.Ptr:
if value.IsValid() {
if value.IsNil() {
@ -850,3 +869,35 @@ func libvirtxmlDomainEmpty(mydom libvirtxml.Domain) bool {
}
return empty
}
// IsStructEmptyOrNil checks if a struct or pointer to struct is empty, blank, or nil
func IsStructEmptyOrNil(value interface{}) bool {
val := reflect.ValueOf(value)
// If the value is a pointer, check if it's nil and dereference it if not
if val.Kind() == reflect.Ptr {
if val.IsNil() {
return true
}
val = val.Elem()
}
// Ensure we're dealing with a struct after potential dereferencing
if val.Kind() != reflect.Struct {
return false // Not a struct
}
// Check each field in the struct for its zero value
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
// Skip unexported fields as we can't access them
if !field.CanInterface() {
continue
}
if !reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()).Interface()) {
return false // Found a non-zero field
}
}
return true // All fields are zero values
}