Skip to content

Commit 1431bd5

Browse files
authored
Support machine configuration directly in fly.toml (#4045)
* Support machine configuration directly in fly.toml * Move it to experimental and simplify as a single string option * fly m run --machine-config
1 parent ad1099a commit 1431bd5

File tree

6 files changed

+69
-3
lines changed

6 files changed

+69
-3
lines changed

internal/appconfig/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ type Experimental struct {
162162
EnableEtcd bool `toml:"enable_etcd,omitempty" json:"enable_etcd,omitempty"`
163163
LazyLoadImages bool `toml:"lazy_load_images,omitempty" json:"lazy_load_images,omitempty"`
164164
Attached Attached `toml:"attached,omitempty" json:"attached,omitempty"`
165+
MachineConfig string `toml:"machine_config,omitempty" json:"machine_config,omitempty"`
165166
}
166167

167168
type Attached struct {

internal/appconfig/machines.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package appconfig
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"io"
7+
"os"
8+
"strings"
59

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

148152
if c.Experimental != nil {
149-
mConfig.Init.Entrypoint = c.Experimental.Entrypoint
153+
if v := c.Experimental.Entrypoint; v != nil {
154+
mConfig.Init.Entrypoint = v
155+
}
150156
}
151157

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

244+
if c.Experimental != nil && len(c.Experimental.MachineConfig) > 0 {
245+
emc := c.Experimental.MachineConfig
246+
var buf []byte
247+
switch {
248+
case strings.HasPrefix(emc, "{"):
249+
buf = []byte(emc)
250+
case strings.HasSuffix(emc, ".json"):
251+
fo, err := os.Open(emc)
252+
if err != nil {
253+
return nil, err
254+
}
255+
buf, err = io.ReadAll(fo)
256+
if err != nil {
257+
return nil, err
258+
}
259+
default:
260+
return nil, fmt.Errorf("invalid machine config source: %q", emc)
261+
}
262+
263+
if err := json.Unmarshal(buf, mConfig); err != nil {
264+
return nil, fmt.Errorf("invalid machine config %q: %w", emc, err)
265+
}
266+
}
267+
238268
// Metrics
239269
mConfig.Metrics = nil
240270
if len(c.Metrics) > 0 {

internal/appconfig/machines_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func TestToMachineConfig(t *testing.T) {
5353
Restart: &fly.MachineRestart{
5454
Policy: fly.MachineRestartPolicyAlways,
5555
},
56+
DNS: &fly.DNSConfig{Nameservers: []string{"1.2.3.4"}},
5657
}
5758

5859
got, err := cfg.ToMachineConfig("", nil)
@@ -79,7 +80,7 @@ func TestToMachineConfig(t *testing.T) {
7980
assert.Equal(t, "24/7", got.Schedule)
8081
assert.Equal(t, true, got.AutoDestroy)
8182
assert.Equal(t, &fly.MachineRestart{Policy: "always"}, got.Restart)
82-
assert.Equal(t, &fly.DNSConfig{SkipRegistration: true}, got.DNS)
83+
assert.Equal(t, &fly.DNSConfig{SkipRegistration: true, Nameservers: []string{"1.2.3.4"}}, got.DNS)
8384
assert.Equal(t, "propagated", got.Metadata["retain"])
8485
assert.Empty(t, got.Init.Cmd)
8586
}
@@ -460,7 +461,7 @@ func TestToTestMachineConfigWTestMachine(t *testing.T) {
460461
}
461462
got, err := cfg.ToTestMachineConfig(check, machine)
462463
assert.NoError(t, err)
463-
assert.Equal(t, got, want)
464+
assert.Equal(t, want, got)
464465
}
465466

466467
func TestToConsoleMachineConfig(t *testing.T) {

internal/appconfig/processgroups.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ func (c *Config) Flatten(groupName string) (*Config, error) {
162162
dst.Metrics[i].Processes = []string{groupName}
163163
}
164164

165+
// [[restart]]
165166
dst.Restart = lo.Filter(dst.Restart, func(x Restart, _ int) bool {
166167
return matchesGroups(x.Processes)
167168
})

internal/appconfig/testdata/tomachine.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ guest_path = "/guest/path"
4646
url_prefix = "/url/prefix"
4747
tigris_bucket = "example-bucket"
4848
index_document = "index.html"
49+
50+
[experimental]
51+
machine_config = '{"dns": {"nameservers": ["1.2.3.4"]}}'

internal/command/machine/run.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package machine
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
7+
"io"
68
"math/rand"
9+
"os"
710
"strconv"
811
"strings"
912
"time"
@@ -91,6 +94,10 @@ var sharedFlags = flag.Set{
9194
Description: "Do not use the cache when building the image",
9295
Hidden: true,
9396
},
97+
flag.String{
98+
Name: "machine-config",
99+
Description: "Read machine config from json file or string",
100+
},
94101
flag.StringArray{
95102
Name: "kernel-arg",
96103
Description: "A list of kernel arguments to provide to the init. Can be specified multiple times.",
@@ -636,6 +643,29 @@ func determineMachineConfig(
636643
) (*fly.MachineConfig, error) {
637644
machineConf := mach.CloneConfig(&input.initialMachineConf)
638645

646+
if emc := flag.GetString(ctx, "machine-config"); emc != "" {
647+
var buf []byte
648+
switch {
649+
case strings.HasPrefix(emc, "{"):
650+
buf = []byte(emc)
651+
case strings.HasSuffix(emc, ".json"):
652+
fo, err := os.Open(emc)
653+
if err != nil {
654+
return nil, err
655+
}
656+
buf, err = io.ReadAll(fo)
657+
if err != nil {
658+
return nil, err
659+
}
660+
default:
661+
return nil, fmt.Errorf("invalid machine config source: %q", emc)
662+
}
663+
664+
if err := json.Unmarshal(buf, machineConf); err != nil {
665+
return nil, fmt.Errorf("invalid machine config %q: %w", emc, err)
666+
}
667+
}
668+
639669
var err error
640670
machineConf.Guest, err = flag.GetMachineGuest(ctx, machineConf.Guest)
641671
if err != nil {

0 commit comments

Comments
 (0)