Skip to content

Commit

Permalink
VMware: Fix guestinfo.*.config.data and *.config.url variables
Browse files Browse the repository at this point in the history
The decision whether to use ignition.config.data or coreos.config.data
was based on their presence in ovfenv. If this was missing, coreos.config.data
would always be used. Also, if the retrieval of the guestinfo would have an error,
the value from ovfenv would not be used even though it was supposed to be a fallback.
Thus, refactor the logic to get variables from the ovfenv as fallback while preferring the
direct guestinfo variables. With this new function, fix the logic of falling back to
coreos.config.data but preferring ignition.config.data.

The OVF metadata for CoreOS specified guestinfo.coreos.config.url but that was
never used to fetch the Ignition config.
Thus, use guestinfo.*.config.url as fallback if no guestinfo.*.config.data variables are set.
  • Loading branch information
pothos authored and tormath1 committed Nov 10, 2021
1 parent df9cfce commit 2d1ca66
Showing 1 changed file with 75 additions and 24 deletions.
99 changes: 75 additions & 24 deletions internal/providers/vmware/vmware_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package vmware

import (
"net/url"

"github.com/coreos/ignition/v2/config/v3_4_experimental/types"
"github.com/coreos/ignition/v2/internal/providers"
"github.com/coreos/ignition/v2/internal/providers/util"
Expand All @@ -26,7 +28,7 @@ import (
"github.com/coreos/vcontext/report"
"github.com/vmware/vmw-guestinfo/rpcvmx"
"github.com/vmware/vmw-guestinfo/vmcheck"
"github.com/vmware/vmw-ovflib"
ovf "github.com/vmware/vmw-ovflib"
)

func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
Expand All @@ -36,26 +38,83 @@ func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
return types.Config{}, report.Report{}, providers.ErrNoProvider
}

config, err := fetchRawConfig(f)
config, err := fetchDataConfig(f)
if err == nil && len(config) == 0 {
config, err = fetchUrlConfig(f)
}
if err != nil {
return types.Config{}, report.Report{}, err
}

decodedData, err := decodeConfig(config)
f.Logger.Debug("config successfully fetched")
return util.ParseConfig(f.Logger, config)
}

func fetchDataConfig(f *resource.Fetcher) ([]byte, error) {
var data string
var encoding string
var err error

data, err = getVariable(f, "ignition.config.data")
if err == nil && data != "" {
encoding, _ = getVariable(f, "ignition.config.data.encoding")
} else {
data, _ = getVariable(f, "coreos.config.data")
if err == nil && data != "" {
encoding, _ = getVariable(f, "coreos.config.data.encoding")
}
}
// Do not check against err from "encoding" because leaving it empty is ok
if data == "" {
f.Logger.Debug("failed to fetch config")
return []byte{}, nil
}

decodedData, err := decodeConfig(config{
data: data,
encoding: encoding,
})
if err != nil {
f.Logger.Debug("failed to decode config: %v", err)
return types.Config{}, report.Report{}, err
return nil, err
}

f.Logger.Debug("config successfully fetched")
return util.ParseConfig(f.Logger, decodedData)
return decodedData, nil
}

func fetchRawConfig(f *resource.Fetcher) (config, error) {
func fetchUrlConfig(f *resource.Fetcher) ([]byte, error) {
rawUrl, err := getVariable(f, "ignition.config.url")
if err != nil || rawUrl == "" {
rawUrl, err = getVariable(f, "coreos.config.url")
}
if err != nil || rawUrl == "" {
f.Logger.Info("no config URL provided")
return []byte{}, nil
}

f.Logger.Debug("found url: %q", rawUrl)

url, err := url.Parse(rawUrl)
if err != nil {
f.Logger.Err("failed to parse url: %v", err)
return nil, err
}
if url == nil {
return []byte{}, nil
}

data, err := f.FetchToBuffer(*url, resource.FetchOptions{})
if err != nil {
return nil, err
}

return data, nil
}

func getVariable(f *resource.Fetcher, key string) (string, error) {
info := rpcvmx.NewConfig()

var ovfData string
var ovfEncoding string

ovfEnv, err := info.String("ovfenv", "")
if err != nil {
Expand All @@ -65,26 +124,18 @@ func fetchRawConfig(f *resource.Fetcher) (config, error) {
env, err := ovf.ReadEnvironment([]byte(ovfEnv))
if err != nil {
f.Logger.Warning("failed to parse OVF environment: %v. Continuing...", err)
} else {
ovfData = env.Properties["guestinfo."+key]
}

ovfData = env.Properties["guestinfo.ignition.config.data"]
ovfEncoding = env.Properties["guestinfo.ignition.config.data.encoding"]
}

data, err := info.String("ignition.config.data", ovfData)
if err != nil {
f.Logger.Debug("failed to fetch config: %v", err)
return config{}, err
}

encoding, err := info.String("ignition.config.data.encoding", ovfEncoding)
// The guest variables get preference over the ovfenv variables which are given here as fallback
data, err := info.String(key, ovfData)
if err != nil {
f.Logger.Debug("failed to fetch config encoding: %v", err)
return config{}, err
f.Logger.Debug("failed to fetch variable, falling back to ovfenv value: %v", err)
return ovfData, nil
}

return config{
data: data,
encoding: encoding,
}, nil
// An empty string will be returned if nothing was found
return data, nil
}

0 comments on commit 2d1ca66

Please sign in to comment.