Skip to content

Commit 210a1d3

Browse files
committed
Add a --volume/-v config create option
Signed-off-by: Kimmo Lehto <[email protected]>
1 parent aa6df6b commit 210a1d3

File tree

5 files changed

+58
-15
lines changed

5 files changed

+58
-15
lines changed

cmd/bootloose/config_create.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package bootloose
77
import (
88
"fmt"
99
"os"
10+
"path/filepath"
11+
"strings"
1012

1113
"github.com/k0sproject/bootloose/pkg/cluster"
1214
"github.com/k0sproject/bootloose/pkg/config"
@@ -17,6 +19,7 @@ import (
1719
type configCreateOptions struct {
1820
override bool
1921
config config.Config
22+
volumes []string
2023
}
2124

2225
func NewConfigCreateCommand() *cobra.Command {
@@ -50,6 +53,8 @@ func NewConfigCreateCommand() *cobra.Command {
5053
containerCmd := &opts.config.Machines[0].Spec.Cmd
5154
cmd.Flags().StringVarP(containerCmd, "cmd", "d", *containerCmd, "The command to execute on the container")
5255

56+
cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil, "Volumes to mount in the container")
57+
5358
return cmd
5459
}
5560

@@ -72,6 +77,45 @@ func (opts *configCreateOptions) create(cmd *cobra.Command, args []string) error
7277
if configExists(cfgFile) && !opts.override {
7378
return fmt.Errorf("configuration file at %s already exists", cfgFile)
7479
}
80+
for _, v := range opts.volumes {
81+
volume, err := parseVolume(v)
82+
if err != nil {
83+
return err
84+
}
85+
for _, machine := range opts.config.Machines {
86+
machine.Spec.Volumes = append(machine.Spec.Volumes, volume)
87+
}
88+
}
7589
return cluster.Save(cfgFile)
7690
}
7791

92+
// volume flags can be in the form of:
93+
// -v /host/path:/container/path (bind mount)
94+
// -v volume:/container/path (volume mount)
95+
// or contain the permissions field:
96+
// -v /host/path:/container/path:ro (bind mount (read only))
97+
// -v volume:/container/path:rw (volume mount (read write))
98+
func parseVolume(v string) (config.Volume, error) {
99+
if v == "" {
100+
return config.Volume{}, fmt.Errorf("empty volume value")
101+
}
102+
parts := strings.Split(v, ":")
103+
if len(parts) < 2 || len(parts) > 3 {
104+
return config.Volume{}, fmt.Errorf("invalid volume value: %v", v)
105+
}
106+
107+
vol := config.Volume{}
108+
if filepath.IsAbs(parts[0]) {
109+
vol.Type = "bind"
110+
} else {
111+
vol.Type = "volume"
112+
}
113+
114+
if len(parts) == 3 {
115+
vol.ReadOnly = parts[2] == "ro"
116+
}
117+
118+
vol.Source = parts[0]
119+
vol.Destination = parts[1]
120+
return vol, nil
121+
}

pkg/cluster/cluster.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (c *Cluster) forEachMachine(do func(*Machine, int) error) error {
125125
for _, template := range c.spec.Machines {
126126
for i := 0; i < template.Count; i++ {
127127
// machine name indexed with i
128-
machine := c.machine(&template.Spec, i)
128+
machine := c.machine(template.Spec, i)
129129
// but to prevent port collision, we use machineIndex for the real machine creation
130130
if err := do(machine, machineIndex); err != nil {
131131
return err
@@ -144,7 +144,7 @@ func (c *Cluster) forSpecificMachines(do func(*Machine, int) error, machineNames
144144
}
145145
for _, template := range c.spec.Machines {
146146
for i := 0; i < template.Count; i++ {
147-
machine := c.machine(&template.Spec, i)
147+
machine := c.machine(template.Spec, i)
148148
_, ok := machineToStart[machine.name]
149149
if ok {
150150
if err := do(machine, i); err != nil {
@@ -546,7 +546,7 @@ func (c *Cluster) gatherMachinesByCluster() (machines []*Machine) {
546546
for _, template := range c.spec.Machines {
547547
for i := 0; i < template.Count; i++ {
548548
s := template.Spec
549-
machine := c.machine(&s, i)
549+
machine := c.machine(s, i)
550550
machines = append(machines, machine)
551551
}
552552
}
@@ -673,7 +673,7 @@ func (c *Cluster) machineFromHostname(hostname string) (*Machine, error) {
673673
for _, template := range c.spec.Machines {
674674
for i := 0; i < template.Count; i++ {
675675
if hostname == f(template.Spec.Name, i) {
676-
return c.machine(&template.Spec, i), nil
676+
return c.machine(template.Spec, i), nil
677677
}
678678
}
679679
}

pkg/cluster/cluster_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ machines:
5555
assert.Equal(t, uint16(22), portMapping.ContainerPort)
5656
assert.Equal(t, uint16(2222), portMapping.HostPort)
5757

58-
machine0 := cluster.machine(&template.Spec, 0)
58+
machine0 := cluster.machine(template.Spec, 0)
5959
args0 := cluster.createMachineRunArgs(machine0, machine0.ContainerName(), 0)
6060
i := indexOf("-p", args0)
6161
assert.NotEqual(t, -1, i)
6262
assert.Equal(t, "2222:22", args0[i+1])
6363

64-
machine1 := cluster.machine(&template.Spec, 1)
64+
machine1 := cluster.machine(template.Spec, 1)
6565
args1 := cluster.createMachineRunArgs(machine1, machine1.ContainerName(), 1)
6666
i = indexOf("-p", args1)
6767
assert.NotEqual(t, -1, i)
@@ -96,13 +96,12 @@ func TestCluster_EnsureSSHKeys(t *testing.T) {
9696

9797
privStat, err = os.Stat(keyPath)
9898
if assert.NoError(t, err, "failed to stat private key file") {
99-
assert.Equal(t, privStat.Mode().Perm(), os.FileMode(0600), "private key file has wrong permissions")
100-
99+
assert.Equal(t, privStat.Mode().Perm(), os.FileMode(0o600), "private key file has wrong permissions")
101100
}
102101

103102
pubStat, err = os.Stat(keyPath + ".pub")
104103
if assert.NoError(t, err, "failed to stat public key file") {
105-
assert.Equal(t, pubStat.Mode().Perm(), os.FileMode(0644), "public key file has wrong permissions")
104+
assert.Equal(t, pubStat.Mode().Perm(), os.FileMode(0o644), "public key file has wrong permissions")
106105
}
107106
})
108107

pkg/config/cluster.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ func NewConfigFromFile(path string) (*Config, error) {
3030

3131
// MachineReplicas are a number of machine following the same specification.
3232
type MachineReplicas struct {
33-
Spec Machine `json:"spec"`
34-
Count int `json:"count"`
33+
Spec *Machine `json:"spec"`
34+
Count int `json:"count"`
3535
}
3636

3737
// Cluster is a set of Machines.
@@ -85,7 +85,7 @@ func DefaultConfig() Config {
8585
Machines: []MachineReplicas{
8686
{
8787
Count: 1,
88-
Spec: Machine{
88+
Spec: &Machine{
8989
Name: "node%d",
9090
Image: "quay.io/k0sproject/bootloose-ubuntu20.04",
9191
PortMappings: []PortMapping{

pkg/config/get_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ func TestGetValueFromConfig(t *testing.T) {
1010
config := Config{
1111
Cluster: Cluster{Name: "clustername", PrivateKey: "privatekey"},
1212
Machines: []MachineReplicas{
13-
MachineReplicas{
13+
{
1414
Count: 3,
15-
Spec: Machine{
15+
Spec: &Machine{
1616
Image: "myImage",
1717
Name: "myName",
1818
Privileged: true,
@@ -32,7 +32,7 @@ func TestGetValueFromConfig(t *testing.T) {
3232
"cluster.name",
3333
Config{
3434
Cluster: Cluster{Name: "clustername", PrivateKey: "privatekey"},
35-
Machines: []MachineReplicas{MachineReplicas{Count: 3, Spec: Machine{}}},
35+
Machines: []MachineReplicas{{Count: 3, Spec: &Machine{}}},
3636
},
3737
"clustername",
3838
},

0 commit comments

Comments
 (0)