Skip to content

Commit

Permalink
Support More Complex Cmdline Configuration
Browse files Browse the repository at this point in the history
Fixes rancher#2755. Allows for quoted arguments with spaces in the kernel cmdline to be parsed properly.

An example command line:

```
$ cat /proc/cmdline
earlyprintk=serial console=ttyS0 rancher.autologin=ttyS0 rancher.defaults.hostname=ros-vm1 rancher.defaults.network.dns.nameservers=[192.168.64.1] rancher.network.interfaces.eth0.dhcp=true rancher.network.interfaces.eth1.dhcp=false rancher.network.interfaces.eth1.address=192.168.99.11/24 rancher.state.dev=LABEL=RANCHER_STATE rancher.state.autoformat=[/dev/vda] rancher.state.formatzero cc.ssh_authorized_keys=['ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOz8mD0tRrNsHBLHD5jVgmXO26JA7eKFZrj4Ic9KR2y3qXlxU9JCYYn/qDyTCmExt8Rw6SaU/BvgU7WT3Bjsi6c=','ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJj5mkpBHBBAW5XClcB5aFTWph+VCL7I0W8gm93AT5w4','ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfb0O2qXgIgrtD5Mj7fBYdg4jMrT7wetBbkG2e4maDsRR3AtSYjEB3NeEifM8gdvIf0gYs1BNB/Ar76agaQGeqW+Ewb2LWdypr4Ipw09yWCrC9ttVbCnHuzVLYjML0CNgpjIRC+FC5r1X1gm2LufRN4orZ1NQvNhRRWJVT37vRtHo79TecK0DKQmy87Zpj3cNiI/5iObnTk56pZWpIAEiC5hEVkcVxmdkLJs3YonWVZzmK/Y8uvFtF+GhA6Jcpc38zDQHKsOjFWvj3qbWtVEQteNDxsM2pNeXY5wdrhRn4YSdKme9Cm7CdAogIdAdPtqPIfq/jY0QczS12qFZH7zt']
```

Results in:

```
$ sudo ros config export
rancher:
  defaults:
    hostname: ros-vm1
    network:
      dns:
        nameservers:
        - 192.168.64.1
  environment:
    EXTRA_CMDLINE: /init AAAAC3NzaC1lZDI1NTE5AAAAIJj5mkpBHBBAW5XClcB5aFTWph+VCL7I0W8gm93AT5w4','ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfb0O2qXgIgrtD5Mj7fBYdg4jMrT7wetBbkG2e4maDsRR3AtSYjEB3NeEifM8gdvIf0gYs1BNB/Ar76agaQGeqW+Ewb2LWdypr4Ipw09yWCrC9ttVbCnHuzVLYjML0CNgpjIRC+FC5r1X1gm2LufRN4orZ1NQvNhRRWJVT37vRtHo79TecK0DKQmy87Zpj3cNiI/5iObnTk56pZWpIAEiC5hEVkcVxmdkLJs3YonWVZzmK/Y8uvFtF+GhA6Jcpc38zDQHKsOjFWvj3qbWtVEQteNDxsM2pNeXY5wdrhRn4YSdKme9Cm7CdAogIdAdPtqPIfq/jY0QczS12qFZH7zt']
  network:
    interfaces:
      eth0:
        dhcp: true
      eth1:
        address: 192.168.99.11/24
        dhcp: false
  state:
    autoformat:
    - /dev/vda
    dev: LABEL=RANCHER_STATE
    formatzero: true
ssh_authorized_keys:
- ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOz8mD0tRrNsHBLHD5jVgmXO26JA7eKFZrj4Ic9KR2y3qXlxU9JCYYn/qDyTCmExt8Rw6SaU/BvgU7WT3Bjsi6c=
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJj5mkpBHBBAW5XClcB5aFTWph+VCL7I0W8gm93AT5w4
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfb0O2qXgIgrtD5Mj7fBYdg4jMrT7wetBbkG2e4maDsRR3AtSYjEB3NeEifM8gdvIf0gYs1BNB/Ar76agaQGeqW+Ewb2LWdypr4Ipw09yWCrC9ttVbCnHuzVLYjML0CNgpjIRC+FC5r1X1gm2LufRN4orZ1NQvNhRRWJVT37vRtHo79TecK0DKQmy87Zpj3cNiI/5iObnTk56pZWpIAEiC5hEVkcVxmdkLJs3YonWVZzmK/Y8uvFtF+GhA6Jcpc38zDQHKsOjFWvj3qbWtVEQteNDxsM2pNeXY5wdrhRn4YSdKme9Cm7CdAogIdAdPtqPIfq/jY0QczS12qFZH7zt
```
  • Loading branch information
bensallen committed Aug 10, 2019
1 parent 7bff07e commit 0351af7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
26 changes: 25 additions & 1 deletion config/cmdline/cmdline.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmdline
import (
"io/ioutil"
"strings"
"unicode"

"github.com/rancher/os/pkg/util"

Expand Down Expand Up @@ -125,11 +126,34 @@ func UnmarshalOrReturnString(value string) (result interface{}) {
return
}

//splitCmdLine splits on spaces except when a space is within a quoted or bracketed string.
func splitCmdLine(cmdLine string) []string {
lastRune := rune(0)
f := func(c rune) bool {
switch {
case c == lastRune:
lastRune = rune(0)
return false
case lastRune != rune(0):
return false
case unicode.In(c, unicode.Quotation_Mark):
lastRune = c
return false
case c == '[':
lastRune = ']'
return false
default:
return c == ' '
}
}
return strings.FieldsFunc(cmdLine, f)
}

func Parse(cmdLine string, parseAll bool) map[interface{}]interface{} {
result := map[interface{}]interface{}{}

outer:
for _, part := range strings.Split(cmdLine, " ") {
for _, part := range splitCmdLine(cmdLine) {
if strings.HasPrefix(part, "cc.") {
part = part[3:]
} else if !strings.HasPrefix(part, "rancher.") {
Expand Down
30 changes: 27 additions & 3 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ func TestCmdlineParse(t *testing.T) {
},
}, cmdline.Parse("rancher.key=a\nb", false), false)

assert.Equal(map[interface{}]interface{}{
"rancher": map[interface{}]interface{}{
"key": "a b",
},
}, cmdline.Parse("rancher.key='a b'", false), false)

assert.Equal(map[interface{}]interface{}{
"rancher": map[interface{}]interface{}{
"key": "a:b",
Expand Down Expand Up @@ -158,6 +164,24 @@ func TestCmdlineParse(t *testing.T) {
"strArray": []interface{}{"url:http://192.168.1.100/cloud-config?a=b"},
},
}, cmdline.Parse("rancher.strArray=[url:http://192.168.1.100/cloud-config?a=b]", false), false)

assert.Equal(map[interface{}]interface{}{
"rancher": map[interface{}]interface{}{
"strArray": []interface{}{"part1 part2", "part3"},
},
}, cmdline.Parse("rancher.strArray=['part1 part2',part3]", false), false)

assert.Equal(map[interface{}]interface{}{
"rancher": map[interface{}]interface{}{
"strArray": []interface{}{"part1 part2", "part3"},
},
}, cmdline.Parse("rancher.strArray=[\"part1 part2\",part3]", false), false)

assert.Equal(map[interface{}]interface{}{
"rancher": map[interface{}]interface{}{
"strArray": []interface{}{"part1 part2", "part3"},
},
}, cmdline.Parse("rancher.strArray=[ \"part1 part2\", part3 ]", false), false)
}

func TestGet(t *testing.T) {
Expand All @@ -174,11 +198,11 @@ func TestGet(t *testing.T) {
}

tests := map[string]interface{}{
"key": "value",
"key": "value",
"rancher.key2.subkey": "subvalue",
"rancher.key2.subnum": 42,
"rancher.key2.subkey2": "",
"foo": "",
"foo": "",
}

for k, v := range tests {
Expand Down Expand Up @@ -217,7 +241,7 @@ func TestSet(t *testing.T) {
}

tests := map[string]interface{}{
"key": "value2",
"key": "value2",
"rancher.key2.subkey": "subvalue2",
"rancher.key2.subkey2": "value",
"rancher.key2.subkey3": 43,
Expand Down

0 comments on commit 0351af7

Please sign in to comment.