fix: correctly render hosts.toml with multiple endpoints

We should preserve the order of keys in generated `hosts.toml`, but
go-toml library has no real way to do that on marshaling, so fix the
previous workaround, as it was generating invalid TOML.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
Andrey Smirnov 2022-08-26 22:48:40 +04:00
parent cdd0f08bc5
commit 4e9c322564
No known key found for this signature in database
GPG Key ID: 7B26396447AB6DFD
2 changed files with 28 additions and 6 deletions

View File

@ -110,9 +110,7 @@ func GenerateHosts(cfg config.Registries, basePath string) (*HostsConfig, error)
var buf bytes.Buffer
enc := toml.NewEncoder(&buf)
for _, endpoint := range endpoints.Endpoints() {
for i, endpoint := range endpoints.Endpoints() {
hostsToml := HostsToml{
HostConfigs: map[string]*HostToml{},
}
@ -128,9 +126,33 @@ func GenerateHosts(cfg config.Registries, basePath string) (*HostsConfig, error)
configureTLS(u.Host, directoryName, hostsToml.HostConfigs[endpoint], directory)
if err = enc.Encode(hostsToml); err != nil {
tomlBytes, err := toml.Marshal(hostsToml)
if err != nil {
return nil, err
}
// this is an ugly hack, and neither TOML format nor go-toml library make it easier
//
// we need to marshal each endpoint in the order they are specified in the config, but go-toml defines
// the tree as map[string]interface{} and doesn't guarantee the order of keys
//
// so we marshal each entry separately and combine the output, which results in something like:
//
// [host]
// [host."foo.bar"]
// [host]
// [host."bar.foo"]
//
// but this is invalid TOML, as `[host]' is repeated, so we do an ugly hack and remove it below
const hostPrefix = "\n[host]\n"
if i > 0 {
if bytes.HasPrefix(tomlBytes, []byte(hostPrefix)) {
tomlBytes = tomlBytes[len(hostPrefix):]
}
}
buf.Write(tomlBytes) //nolint:errcheck
}
directory.Files = append(directory.Files,

View File

@ -59,7 +59,7 @@ func TestGenerateHosts(t *testing.T) {
{
Name: "hosts.toml",
Mode: 0o600,
Contents: []byte("\n[host]\n\n [host.\"https://registry-1.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n\n[host]\n\n [host.\"https://registry-2.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n skip_verify = true\n"), //nolint:lll
Contents: []byte("\n[host]\n\n [host.\"https://registry-1.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n\n [host.\"https://registry-2.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n skip_verify = true\n"), //nolint:lll
},
},
},
@ -127,7 +127,7 @@ func TestGenerateHosts(t *testing.T) {
{
Name: "hosts.toml",
Mode: 0o600,
Contents: []byte("\n[host]\n\n [host.\"https://registry-1.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n\n[host]\n\n [host.\"https://registry-2.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n"), //nolint:lll
Contents: []byte("\n[host]\n\n [host.\"https://registry-1.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n\n [host.\"https://registry-2.docker.io\"]\n capabilities = [\"pull\", \"resolve\"]\n"), //nolint:lll
},
},
},