mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
package compose
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
const MachinesExtensionKey = "x-machines"
|
|
|
|
// MachinesSource represents the parsed x-machines extension data as slice of strings
|
|
type MachinesSource []string
|
|
|
|
// DecodeMapstructure implements custom decoding for multiple input types
|
|
func (m *MachinesSource) DecodeMapstructure(value interface{}) error {
|
|
switch v := value.(type) {
|
|
case *MachinesSource:
|
|
// Handle case where compose-go passes a pointer to an already created instance
|
|
*m = *v
|
|
return nil
|
|
case MachinesSource:
|
|
// Handle case where compose-go passes a direct instance
|
|
*m = v
|
|
return nil
|
|
case string:
|
|
// Support single string value or comma-separated values
|
|
// x-machines: my-machine or x-machines: "machine-1,machine-2"
|
|
machines, err := parseMachineNames(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*m = MachinesSource(machines)
|
|
return nil
|
|
case []string:
|
|
// Support string array: x-machines: ["machine-1", "machine-2"]
|
|
machines, err := validateMachineNames(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*m = MachinesSource(machines)
|
|
return nil
|
|
case []interface{}:
|
|
// Support interface array that may come from YAML parsing
|
|
machineNames := make([]string, 0, len(v))
|
|
for i, machine := range v {
|
|
str, ok := machine.(string)
|
|
if !ok {
|
|
return fmt.Errorf("x-machines[%d] is not a string, got %T", i, machine)
|
|
}
|
|
machineNames = append(machineNames, str)
|
|
}
|
|
machines, err := validateMachineNames(machineNames)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*m = MachinesSource(machines)
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("x-machines must be a string or list of strings, got %T", value)
|
|
}
|
|
}
|
|
|
|
// parseMachineNames parses a single string that may contain comma-separated machine names
|
|
func parseMachineNames(machinesStr string) ([]string, error) {
|
|
// Split by comma and process each machine name, works for both single and multiple values
|
|
parts := strings.Split(machinesStr, ",")
|
|
machines := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
machines = append(machines, strings.TrimSpace(part))
|
|
}
|
|
return validateMachineNames(machines)
|
|
}
|
|
|
|
// validateMachineNames validates machine names to ensure they are not empty and contain valid characters.
|
|
func validateMachineNames(machines []string) ([]string, error) {
|
|
for i, machine := range machines {
|
|
machine = strings.TrimSpace(machine)
|
|
if machine == "" {
|
|
return nil, fmt.Errorf("x-machines[%d] cannot be empty", i)
|
|
}
|
|
machines[i] = machine
|
|
}
|
|
return machines, nil
|
|
}
|