Skip to content

Commit

Permalink
Support machine configuration directly in fly.toml (#4045)
Browse files Browse the repository at this point in the history
* Support machine configuration directly in fly.toml

* Move it to experimental and simplify as a single string option

* fly m run --machine-config
  • Loading branch information
dangra authored Nov 5, 2024
1 parent ad1099a commit 1431bd5
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 3 deletions.
1 change: 1 addition & 0 deletions internal/appconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ type Experimental struct {
EnableEtcd bool `toml:"enable_etcd,omitempty" json:"enable_etcd,omitempty"`
LazyLoadImages bool `toml:"lazy_load_images,omitempty" json:"lazy_load_images,omitempty"`
Attached Attached `toml:"attached,omitempty" json:"attached,omitempty"`
MachineConfig string `toml:"machine_config,omitempty" json:"machine_config,omitempty"`
}

type Attached struct {
Expand Down
32 changes: 31 additions & 1 deletion internal/appconfig/machines.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package appconfig

import (
"encoding/json"
"fmt"
"io"
"os"
"strings"

"github.com/docker/go-units"
"github.com/google/shlex"
Expand Down Expand Up @@ -146,7 +150,9 @@ func (c *Config) ToTestMachineConfig(svc *ServiceMachineCheck, origMachine *fly.
}

if c.Experimental != nil {
mConfig.Init.Entrypoint = c.Experimental.Entrypoint
if v := c.Experimental.Entrypoint; v != nil {
mConfig.Init.Entrypoint = v
}
}

mConfig.Env["FLY_TEST_COMMAND"] = "1"
Expand Down Expand Up @@ -235,6 +241,30 @@ func (c *Config) updateMachineConfig(src *fly.MachineConfig) (*fly.MachineConfig
mConfig = helpers.Clone(src)
}

if c.Experimental != nil && len(c.Experimental.MachineConfig) > 0 {
emc := c.Experimental.MachineConfig
var buf []byte
switch {
case strings.HasPrefix(emc, "{"):
buf = []byte(emc)
case strings.HasSuffix(emc, ".json"):
fo, err := os.Open(emc)
if err != nil {
return nil, err
}
buf, err = io.ReadAll(fo)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("invalid machine config source: %q", emc)
}

if err := json.Unmarshal(buf, mConfig); err != nil {
return nil, fmt.Errorf("invalid machine config %q: %w", emc, err)
}
}

// Metrics
mConfig.Metrics = nil
if len(c.Metrics) > 0 {
Expand Down
5 changes: 3 additions & 2 deletions internal/appconfig/machines_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestToMachineConfig(t *testing.T) {
Restart: &fly.MachineRestart{
Policy: fly.MachineRestartPolicyAlways,
},
DNS: &fly.DNSConfig{Nameservers: []string{"1.2.3.4"}},
}

got, err := cfg.ToMachineConfig("", nil)
Expand All @@ -79,7 +80,7 @@ func TestToMachineConfig(t *testing.T) {
assert.Equal(t, "24/7", got.Schedule)
assert.Equal(t, true, got.AutoDestroy)
assert.Equal(t, &fly.MachineRestart{Policy: "always"}, got.Restart)
assert.Equal(t, &fly.DNSConfig{SkipRegistration: true}, got.DNS)
assert.Equal(t, &fly.DNSConfig{SkipRegistration: true, Nameservers: []string{"1.2.3.4"}}, got.DNS)
assert.Equal(t, "propagated", got.Metadata["retain"])
assert.Empty(t, got.Init.Cmd)
}
Expand Down Expand Up @@ -460,7 +461,7 @@ func TestToTestMachineConfigWTestMachine(t *testing.T) {
}
got, err := cfg.ToTestMachineConfig(check, machine)
assert.NoError(t, err)
assert.Equal(t, got, want)
assert.Equal(t, want, got)
}

func TestToConsoleMachineConfig(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions internal/appconfig/processgroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ func (c *Config) Flatten(groupName string) (*Config, error) {
dst.Metrics[i].Processes = []string{groupName}
}

// [[restart]]
dst.Restart = lo.Filter(dst.Restart, func(x Restart, _ int) bool {
return matchesGroups(x.Processes)
})
Expand Down
3 changes: 3 additions & 0 deletions internal/appconfig/testdata/tomachine.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ guest_path = "/guest/path"
url_prefix = "/url/prefix"
tigris_bucket = "example-bucket"
index_document = "index.html"

[experimental]
machine_config = '{"dns": {"nameservers": ["1.2.3.4"]}}'
30 changes: 30 additions & 0 deletions internal/command/machine/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package machine

import (
"context"
"encoding/json"
"fmt"
"io"
"math/rand"
"os"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -91,6 +94,10 @@ var sharedFlags = flag.Set{
Description: "Do not use the cache when building the image",
Hidden: true,
},
flag.String{
Name: "machine-config",
Description: "Read machine config from json file or string",
},
flag.StringArray{
Name: "kernel-arg",
Description: "A list of kernel arguments to provide to the init. Can be specified multiple times.",
Expand Down Expand Up @@ -636,6 +643,29 @@ func determineMachineConfig(
) (*fly.MachineConfig, error) {
machineConf := mach.CloneConfig(&input.initialMachineConf)

if emc := flag.GetString(ctx, "machine-config"); emc != "" {
var buf []byte
switch {
case strings.HasPrefix(emc, "{"):
buf = []byte(emc)
case strings.HasSuffix(emc, ".json"):
fo, err := os.Open(emc)
if err != nil {
return nil, err
}
buf, err = io.ReadAll(fo)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("invalid machine config source: %q", emc)
}

if err := json.Unmarshal(buf, machineConf); err != nil {
return nil, fmt.Errorf("invalid machine config %q: %w", emc, err)
}
}

var err error
machineConf.Guest, err = flag.GetMachineGuest(ctx, machineConf.Guest)
if err != nil {
Expand Down

0 comments on commit 1431bd5

Please sign in to comment.