From ecb36e0b47436e124e844ba14a0ac75ddf1f2dc3 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:19:23 +0100 Subject: [PATCH 1/9] test/ignition: add units test this test is backport from coreos-assembler to test systemd instantiated services enabled via ignition. Signed-off-by: Mathieu Tortuyaux --- kola/tests/ignition/units.go | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 kola/tests/ignition/units.go diff --git a/kola/tests/ignition/units.go b/kola/tests/ignition/units.go new file mode 100644 index 000000000..ff24a740a --- /dev/null +++ b/kola/tests/ignition/units.go @@ -0,0 +1,56 @@ +// Copyright The Mantle Authors +// Copyright 2020 Red Hat +// SPDX-License-Identifier: Apache-2.0 +package ignition + +import ( + "github.com/flatcar-linux/mantle/kola/cluster" + "github.com/flatcar-linux/mantle/kola/register" + "github.com/flatcar-linux/mantle/platform/conf" +) + +func init() { + register.Register(®ister.Test{ + Name: "cl.ignition.instantiated.enable-unit", + Run: enableSystemdInstantiatedService, + ClusterSize: 1, + UserData: conf.Ignition(`{ + "ignition": {"version": "3.0.0"}, + "systemd": { + "units": [{ + "name": "echo@.service", + "contents": "[Unit]\nDescription=f\n[Service]\nType=oneshot\nExecStart=/bin/echo %i\nRemainAfterExit=yes\n[Install]\nWantedBy=multi-user.target\n" + }, + { + "name": "echo@.timer", + "contents": "[Unit]\nDescription=echo timer template\n[Timer]\nOnUnitInactiveSec=10s\n[Install]\nWantedBy=timers.target" + }, + { + "enabled": true, + "name": "echo@bar.service" + }, + { + "enabled": true, + "name": "echo@foo.service" + }, + { + "enabled": true, + "name": "echo@foo.timer" + }] + } +}`), + Distros: []string{"cl"}, + }) +} + +func enableSystemdInstantiatedService(c cluster.TestCluster) { + m := c.Machines()[0] + // MustSSH function will throw an error if the exit code + // of the command is anything other than 0. + _ = c.MustSSH(m, "systemctl -q is-active echo@foo.service") + _ = c.MustSSH(m, "systemctl -q is-active echo@bar.service") + _ = c.MustSSH(m, "systemctl -q is-enabled echo@foo.service") + _ = c.MustSSH(m, "systemctl -q is-enabled echo@bar.service") + _ = c.MustSSH(m, "systemctl -q is-active echo@foo.timer") + _ = c.MustSSH(m, "systemctl -q is-enabled echo@foo.timer") +} From 907d1a673758aab1fb80895976b5b53fa078d23c Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:27:58 +0100 Subject: [PATCH 2/9] kola/cluster: add helper to check cmd output this helper runs cmd via SSH and panics if stdout does not contain expected Signed-off-by: Mathieu Tortuyaux --- kola/cluster/cluster.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kola/cluster/cluster.go b/kola/cluster/cluster.go index 72218ea3d..65b1ec95a 100644 --- a/kola/cluster/cluster.go +++ b/kola/cluster/cluster.go @@ -131,3 +131,13 @@ func (t *TestCluster) MustSSH(m platform.Machine, cmd string) []byte { } return out } + +// AssertCmdOutputContains runs cmd via SSH and panics if stdout does not contain expected +func (t *TestCluster) AssertCmdOutputContains(m platform.Machine, cmd string, expected string) { + t.Logf("+ " + cmd) + outputBuf := t.MustSSH(m, cmd) + output := string(outputBuf) + if !strings.Contains(output, expected) { + t.Fatalf("cmd %s did not output %s", cmd, expected) + } +} From 73a12cf2ce514d58b82f561b4fd66b014c131b16 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:28:41 +0100 Subject: [PATCH 3/9] test/ignition: add symlink test this test creates a symlink via ignition and assert it's correct. Signed-off-by: Mathieu Tortuyaux --- kola/tests/ignition/symlink.go | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 kola/tests/ignition/symlink.go diff --git a/kola/tests/ignition/symlink.go b/kola/tests/ignition/symlink.go new file mode 100644 index 000000000..206141c1d --- /dev/null +++ b/kola/tests/ignition/symlink.go @@ -0,0 +1,47 @@ +// Copyright The Mantle Authors +// Copyright 2020 Red Hat +// SPDX-License-Identifier: Apache-2.0 +package ignition + +import ( + "github.com/coreos/go-semver/semver" + "github.com/flatcar-linux/mantle/kola/cluster" + "github.com/flatcar-linux/mantle/kola/register" + "github.com/flatcar-linux/mantle/platform/conf" +) + +func init() { + register.Register(®ister.Test{ + Name: "cl.ignition.symlink", + Run: writeAbsoluteSymlink, + ClusterSize: 1, + UserData: conf.Ignition(`{ + "ignition": { + "version": "3.0.0" + }, + "storage": { + "links": [ + { + "group": { + "name": "core" + }, + "overwrite": true, + "path": "/etc/localtime", + "user": { + "name": "core" + }, + "hard": false, + "target": "/usr/share/zoneinfo/Europe/Zurich" + } + ] + } + }`), + MinVersion: semver.Version{Major: 3185}, + }) +} + +func writeAbsoluteSymlink(c cluster.TestCluster) { + m := c.Machines()[0] + + c.AssertCmdOutputContains(m, "readlink /etc/localtime", "/usr/share/zoneinfo/Europe/Zurich") +} From edf16cb897324771092269cfa73956d786519f2b Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:46:19 +0100 Subject: [PATCH 4/9] mod: bump ignition/v2 mainly to support config > 3.0.0 Signed-off-by: Mathieu Tortuyaux --- go.mod | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 001cc77ec..1f30e9b03 100644 --- a/go.mod +++ b/go.mod @@ -19,8 +19,8 @@ require ( github.com/coreos/yaml v0.0.0-20141224210557-6b16a5714269 // indirect github.com/digitalocean/godo v1.45.0 github.com/flatcar-linux/container-linux-config-transpiler v0.9.3-0.20220208152502-6e8303479682 - github.com/flatcar-linux/ignition v0.36.1 - github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220107090316-32908ec8bade + github.com/flatcar-linux/ignition v0.36.2-0.20220221101037-de4e6cc9bbba + github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220311122140-cb95c51122f5 github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect github.com/godbus/dbus v0.0.0-20181025153459-66d97aec3384 github.com/golang/protobuf v1.5.2 @@ -31,7 +31,7 @@ require ( github.com/pborman/uuid v1.2.0 github.com/pin/tftp v2.1.0+incompatible github.com/spf13/cobra v1.1.3 - github.com/spf13/pflag v1.0.5 + github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/stretchr/testify v1.7.0 github.com/ulikunitz/xz v0.5.10 github.com/vincent-petithory/dataurl v1.0.0 From e598c97ade192afc6369f339459435664df9a9c2 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:46:48 +0100 Subject: [PATCH 5/9] sum: go mod tidy Signed-off-by: Mathieu Tortuyaux --- go.sum | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/go.sum b/go.sum index a6c459242..9a7bbee93 100644 --- a/go.sum +++ b/go.sum @@ -105,6 +105,7 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/clarketm/json v1.14.1/go.mod h1:ynr2LRfb0fQU34l07csRNBTcivjySLLiY1YzQqKVfdo= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -169,10 +170,13 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flatcar-linux/container-linux-config-transpiler v0.9.3-0.20220208152502-6e8303479682 h1:CiIJbwa0iC52LGviALcCtpnLpNa2hYXEdM64xFgALa0= github.com/flatcar-linux/container-linux-config-transpiler v0.9.3-0.20220208152502-6e8303479682/go.mod h1:AGVTulMzeIKwurV9ExYH3UiokET1Ur65g+EIeRDMwzM= -github.com/flatcar-linux/ignition v0.36.1 h1:yNvS9sQvm9HJ8VgxXskx88DsF73qdF35ALJkbTwcYhY= +github.com/flatcar-linux/ign-converter v0.1.1-0.20220311112608-f121a881f370/go.mod h1:t/kcw0CQ/uKMCyZwDAzuwMO3CShxaimEJhQzLGCsb3Y= github.com/flatcar-linux/ignition v0.36.1/go.mod h1:0jS5n4AopgOdwgi7QDo5MFgkMx/fQUDYjuxlGJC1Txg= -github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220107090316-32908ec8bade h1:9GBoxuiqpcmCH6nGz4tbPLxrW21fRUdkR68qXVu4FMQ= -github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220107090316-32908ec8bade/go.mod h1:edsyBkLOoqVhT99HwgWUXip9QNrR1dC2NF4oGhQj1gY= +github.com/flatcar-linux/ignition v0.36.2-0.20220221101037-de4e6cc9bbba h1:HiTCL7737Hi944kXfLN8ReGoJtAiibGIsCk3MGlYy9M= +github.com/flatcar-linux/ignition v0.36.2-0.20220221101037-de4e6cc9bbba/go.mod h1:JzHCIdCu9dy0xtezyBit/aOY4QIlJ12UYU6nXNPnnRE= +github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220302150437-ce14e51676e9/go.mod h1:n076OVuGbg6f+j3YYoxFCjRyMU2hxsx6Q4Gy0xwO7cM= +github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220311122140-cb95c51122f5 h1:k7xpW9MfyAxjsoA0HW6nnHlQnlNlPrPhHPNuT4uf7Xo= +github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220311122140-cb95c51122f5/go.mod h1:C0FynALB9lic4GBqxCuNqUqfZlny9rySbFx0VVXy7uU= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= @@ -437,8 +441,9 @@ github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA= +github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -453,7 +458,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/vincent-petithory/dataurl v0.0.0-20160330182126-9a301d65acbb/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 h1:+UB2BJA852UkGH42H+Oee69djmxS3ANzl2b/JtT1YiA= @@ -522,6 +526,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go4.org v0.0.0-20160314031811-03efcb870d84/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +go4.org v0.0.0-20200104003542-c7e774b10ea0/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20201209231011-d4a079459e60 h1:iqAGo78tVOJXELHQFRjR6TMwItrvXH4hrGJ32I/NFF8= go4.org v0.0.0-20201209231011-d4a079459e60/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From d74aaf894a8b39599e12076e12d3fcad9518c22c Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 15:46:54 +0100 Subject: [PATCH 6/9] vendor: go mod vendor Signed-off-by: Mathieu Tortuyaux --- .../ignition/config/shared/errors/errors.go | 15 +- .../ignition/config/util/parsingErrors.go | 2 +- .../ignition/config/v2_4/types/ca.go | 58 ++++ .../types/config.go | 5 +- .../types/directory.go | 0 .../{v2_4_experimental => v2_4}/types/disk.go | 0 .../{v2_4_experimental => v2_4}/types/file.go | 29 ++ .../types/filesystem.go | 0 .../ignition/config/v2_4/types/headers.go | 47 ++++ .../types/ignition.go | 30 +++ .../{v2_4_experimental => v2_4}/types/mode.go | 0 .../{v2_4_experimental => v2_4}/types/node.go | 0 .../types/partition.go | 0 .../types/passwd.go | 0 .../{v2_4_experimental => v2_4}/types/path.go | 0 .../{v2_4_experimental => v2_4}/types/raid.go | 0 .../types/schema.go | 10 + .../{v2_4_experimental => v2_4}/types/unit.go | 0 .../{v2_4_experimental => v2_4}/types/url.go | 0 .../types/verification.go | 0 .../ignition/v2/config/translate/translate.go | 187 +++++++++++++ .../ignition/v2/config/util/config.go | 11 +- .../ignition/v2/config/util/parsingErrors.go | 39 +++ .../ignition/v2/config/v3_0/types/url.go | 2 +- .../ignition/v2/config/v3_1/config.go | 78 ++++++ .../v2/config/v3_1/translate/translate.go | 106 ++++++++ .../ignition/v2/config/v3_1/types/config.go | 26 ++ .../ignition/v2/config/v3_1/types/device.go | 25 ++ .../v2/config/v3_1/types/directory.go | 26 ++ .../ignition/v2/config/v3_1/types/disk.go | 135 ++++++++++ .../ignition/v2/config/v3_1/types/file.go | 43 +++ .../v2/config/v3_1/types/filesystem.go | 106 ++++++++ .../ignition/v2/config/v3_1/types/headers.go | 65 +++++ .../ignition/v2/config/v3_1/types/ignition.go | 49 ++++ .../ca.go => v2/config/v3_1/types/mode.go} | 13 +- .../ignition/v2/config/v3_1/types/node.go | 59 ++++ .../v2/config/v3_1/types/partition.go | 91 +++++++ .../ignition/v2/config/v3_1/types/passwd.go | 23 ++ .../ignition/v2/config/v3_1/types/path.go | 42 +++ .../ignition/v2/config/v3_1/types/proxy.go | 49 ++++ .../ignition/v2/config/v3_1/types/raid.go | 58 ++++ .../ignition/v2/config/v3_1/types/resource.go | 91 +++++++ .../ignition/v2/config/v3_1/types/schema.go | 211 +++++++++++++++ .../ignition/v2/config/v3_1/types/storage.go | 71 +++++ .../ignition/v2/config/v3_1/types/tls.go | 27 ++ .../ignition/v2/config/v3_1/types/unit.go | 82 ++++++ .../ignition/v2/config/v3_1/types/url.go | 57 ++++ .../v2/config/v3_1/types/verification.go | 71 +++++ .../ignition/v2/config/v3_2/config.go | 78 ++++++ .../v2/config/v3_2/translate/translate.go | 90 +++++++ .../ignition/v2/config/v3_2/types/config.go | 26 ++ .../ignition/v2/config/v3_2/types/custom.go | 37 +++ .../ignition/v2/config/v3_2/types/device.go | 25 ++ .../v2/config/v3_2/types/directory.go | 26 ++ .../ignition/v2/config/v3_2/types/disk.go | 135 ++++++++++ .../ignition/v2/config/v3_2/types/file.go | 43 +++ .../v2/config/v3_2/types/filesystem.go | 106 ++++++++ .../ignition/v2/config/v3_2/types/headers.go | 65 +++++ .../ignition/v2/config/v3_2/types/ignition.go | 49 ++++ .../ignition/v2/config/v3_2/types/luks.go | 73 +++++ .../ignition/v2/config/v3_2/types/mode.go | 26 ++ .../ignition/v2/config/v3_2/types/node.go | 59 ++++ .../v2/config/v3_2/types/partition.go | 91 +++++++ .../ignition/v2/config/v3_2/types/passwd.go | 23 ++ .../ignition/v2/config/v3_2/types/path.go | 42 +++ .../ignition/v2/config/v3_2/types/proxy.go | 49 ++++ .../ignition/v2/config/v3_2/types/raid.go | 58 ++++ .../ignition/v2/config/v3_2/types/resource.go | 91 +++++++ .../ignition/v2/config/v3_2/types/schema.go | 246 +++++++++++++++++ .../ignition/v2/config/v3_2/types/storage.go | 71 +++++ .../ignition/v2/config/v3_2/types/tang.go | 51 ++++ .../ignition/v2/config/v3_2/types/tls.go | 27 ++ .../ignition/v2/config/v3_2/types/unit.go | 82 ++++++ .../ignition/v2/config/v3_2/types/url.go | 57 ++++ .../v2/config/v3_2/types/verification.go | 71 +++++ .../ignition/v2/config/v3_3/config.go | 78 ++++++ .../v2/config/v3_3/translate/translate.go | 95 +++++++ .../ignition/v2/config/v3_3/types/clevis.go | 49 ++++ .../ignition/v2/config/v3_3/types/config.go | 26 ++ .../ignition/v2/config/v3_3/types/device.go | 25 ++ .../v2/config/v3_3/types/directory.go | 26 ++ .../ignition/v2/config/v3_3/types/disk.go | 135 ++++++++++ .../ignition/v2/config/v3_3/types/file.go | 43 +++ .../v2/config/v3_3/types/filesystem.go | 106 ++++++++ .../ignition/v2/config/v3_3/types/headers.go | 65 +++++ .../ignition/v2/config/v3_3/types/ignition.go | 49 ++++ .../ignition/v2/config/v3_3/types/kargs.go | 22 ++ .../ignition/v2/config/v3_3/types/luks.go | 71 +++++ .../ignition/v2/config/v3_3/types/mode.go | 26 ++ .../ignition/v2/config/v3_3/types/node.go | 59 ++++ .../v2/config/v3_3/types/partition.go | 91 +++++++ .../ignition/v2/config/v3_3/types/passwd.go | 23 ++ .../ignition/v2/config/v3_3/types/path.go | 42 +++ .../ignition/v2/config/v3_3/types/proxy.go | 49 ++++ .../ignition/v2/config/v3_3/types/raid.go | 62 +++++ .../ignition/v2/config/v3_3/types/resource.go | 91 +++++++ .../ignition/v2/config/v3_3/types/schema.go | 254 ++++++++++++++++++ .../ignition/v2/config/v3_3/types/storage.go | 75 ++++++ .../ignition/v2/config/v3_3/types/tang.go | 51 ++++ .../ignition/v2/config/v3_3/types/tls.go | 27 ++ .../ignition/v2/config/v3_3/types/unit.go | 82 ++++++ .../ignition/v2/config/v3_3/types/url.go | 57 ++++ .../v2/config/v3_3/types/verification.go | 71 +++++ vendor/github.com/spf13/pflag/flag.go | 29 +- vendor/github.com/spf13/pflag/ip.go | 3 + vendor/github.com/spf13/pflag/ipnet_slice.go | 147 ++++++++++ vendor/github.com/spf13/pflag/string_array.go | 4 - vendor/modules.txt | 18 +- 108 files changed, 5849 insertions(+), 38 deletions(-) create mode 100644 vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ca.go rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/config.go (97%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/directory.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/disk.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/file.go (78%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/filesystem.go (100%) create mode 100644 vendor/github.com/flatcar-linux/ignition/config/v2_4/types/headers.go rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/ignition.go (75%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/mode.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/node.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/partition.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/passwd.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/path.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/raid.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/schema.go (96%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/unit.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/url.go (100%) rename vendor/github.com/flatcar-linux/ignition/config/{v2_4_experimental => v2_4}/types/verification.go (100%) create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/translate/translate.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/translate/translate.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/device.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/directory.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/disk.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/file.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/filesystem.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/headers.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/ignition.go rename vendor/github.com/flatcar-linux/ignition/{config/v2_4_experimental/types/ca.go => v2/config/v3_1/types/mode.go} (68%) create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/node.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/partition.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/passwd.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/path.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/proxy.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/raid.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/resource.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/schema.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/storage.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/tls.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/unit.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/url.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/verification.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/translate/translate.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/custom.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/device.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/directory.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/disk.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/file.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/filesystem.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/headers.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/ignition.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/luks.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/mode.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/node.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/partition.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/passwd.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/path.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/proxy.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/raid.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/resource.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/schema.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/storage.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tang.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tls.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/unit.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/url.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/verification.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/translate/translate.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/clevis.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/config.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/device.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/directory.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/disk.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/file.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/filesystem.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/headers.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/ignition.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/kargs.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/luks.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/mode.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/node.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/partition.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/passwd.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/path.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/proxy.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/raid.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/resource.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/schema.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/storage.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tang.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tls.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/unit.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/url.go create mode 100644 vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/verification.go create mode 100644 vendor/github.com/spf13/pflag/ipnet_slice.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/shared/errors/errors.go b/vendor/github.com/flatcar-linux/ignition/config/shared/errors/errors.go index 81e857621..f2b47cf90 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/shared/errors/errors.go +++ b/vendor/github.com/flatcar-linux/ignition/config/shared/errors/errors.go @@ -88,12 +88,15 @@ var ( ErrInvalidNetworkdDropinExt = errors.New("invalid networkd drop-in extension") // Misc errors - ErrInvalidScheme = errors.New("invalid url scheme") - ErrInvalidUrl = errors.New("unable to parse url") - ErrHashMalformed = errors.New("malformed hash specifier") - ErrHashWrongSize = errors.New("incorrect size for hash sum") - ErrHashUnrecognized = errors.New("unrecognized hash function") - ErrEngineConfiguration = errors.New("engine incorrectly configured") + ErrInvalidScheme = errors.New("invalid url scheme") + ErrInvalidUrl = errors.New("unable to parse url") + ErrEmptyHTTPHeaderName = errors.New("HTTP header name can't be empty") + ErrDuplicateHTTPHeaders = errors.New("all header names in the list must be unique") + ErrUnsupportedSchemeForHTTPHeaders = errors.New("cannot use HTTP headers with this source scheme") + ErrHashMalformed = errors.New("malformed hash specifier") + ErrHashWrongSize = errors.New("incorrect size for hash sum") + ErrHashUnrecognized = errors.New("unrecognized hash function") + ErrEngineConfiguration = errors.New("engine incorrectly configured") // AWS S3 specific errors ErrInvalidS3ObjectVersionId = errors.New("invalid S3 object VersionId") diff --git a/vendor/github.com/flatcar-linux/ignition/config/util/parsingErrors.go b/vendor/github.com/flatcar-linux/ignition/config/util/parsingErrors.go index 45464f971..fbd712f3b 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/util/parsingErrors.go +++ b/vendor/github.com/flatcar-linux/ignition/config/util/parsingErrors.go @@ -19,7 +19,7 @@ import ( "errors" configErrors "github.com/flatcar-linux/ignition/config/shared/errors" - "github.com/flatcar-linux/ignition/config/v2_4_experimental/types" + "github.com/flatcar-linux/ignition/config/v2_4/types" "github.com/flatcar-linux/ignition/config/validate/report" json "github.com/ajeddeloh/go-json" diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ca.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ca.go new file mode 100644 index 000000000..3955fd224 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ca.go @@ -0,0 +1,58 @@ +// Copyright 2018 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/config/shared/errors" + "github.com/flatcar-linux/ignition/config/validate/report" +) + +func (c CaReference) ValidateSource() report.Report { + err := validateURL(c.Source) + if err != nil { + return report.ReportFromError(err, report.EntryError) + } + return report.Report{} +} + +func (c CaReference) ValidateHTTPHeaders() report.Report { + r := report.Report{} + + if len(c.HTTPHeaders) < 1 { + return r + } + + u, err := url.Parse(c.Source) + if err != nil { + r.Add(report.Entry{ + Message: errors.ErrInvalidUrl.Error(), + Kind: report.EntryError, + }) + return r + } + + switch u.Scheme { + case "http", "https": + default: + r.Add(report.Entry{ + Message: errors.ErrUnsupportedSchemeForHTTPHeaders.Error(), + Kind: report.EntryError, + }) + } + + return r +} diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/config.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/config.go similarity index 97% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/config.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/config.go index 596ff397a..ceb79e9e5 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/config.go +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/config.go @@ -24,9 +24,8 @@ import ( var ( MaxVersion = semver.Version{ - Major: 2, - Minor: 4, - PreRelease: "experimental", + Major: 2, + Minor: 4, } ) diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/directory.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/directory.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/directory.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/directory.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/disk.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/disk.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/disk.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/disk.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/file.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/file.go similarity index 78% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/file.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/file.go index 6e2a0c7aa..6bc717fe8 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/file.go +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/file.go @@ -16,6 +16,7 @@ package types import ( "fmt" + "net/url" "github.com/flatcar-linux/ignition/config/shared/errors" "github.com/flatcar-linux/ignition/config/validate/report" @@ -69,3 +70,31 @@ func (fc FileContents) ValidateSource() report.Report { } return r } + +func (fc FileContents) ValidateHTTPHeaders() report.Report { + r := report.Report{} + + if len(fc.HTTPHeaders) < 1 { + return r + } + + u, err := url.Parse(fc.Source) + if err != nil { + r.Add(report.Entry{ + Message: errors.ErrInvalidUrl.Error(), + Kind: report.EntryError, + }) + return r + } + + switch u.Scheme { + case "http", "https": + default: + r.Add(report.Entry{ + Message: errors.ErrUnsupportedSchemeForHTTPHeaders.Error(), + Kind: report.EntryError, + }) + } + + return r +} diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/filesystem.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/filesystem.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/filesystem.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/filesystem.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/headers.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/headers.go new file mode 100644 index 000000000..3d34587af --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/headers.go @@ -0,0 +1,47 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/config/shared/errors" + "github.com/flatcar-linux/ignition/config/validate/report" + + "fmt" +) + +func (h HTTPHeaders) Validate() report.Report { + r := report.Report{} + found := make(map[string]struct{}) + for _, header := range h { + // Header name can't be empty + if header.Name == "" { + r.Add(report.Entry{ + Message: errors.ErrEmptyHTTPHeaderName.Error(), + Kind: report.EntryError, + }) + continue + } + // Header names must be unique + if _, ok := found[header.Name]; ok { + r.Add(report.Entry{ + Message: fmt.Sprintf("Found duplicate HTTP header: %q", header.Name), + Kind: report.EntryError, + }) + continue + } + found[header.Name] = struct{}{} + } + return r +} diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ignition.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ignition.go similarity index 75% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ignition.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ignition.go index 513012e10..a6e2bc6e5 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ignition.go +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/ignition.go @@ -15,6 +15,8 @@ package types import ( + "net/url" + "github.com/coreos/go-semver/semver" "github.com/flatcar-linux/ignition/config/shared/errors" @@ -33,6 +35,34 @@ func (c ConfigReference) ValidateSource() report.Report { return r } +func (c ConfigReference) ValidateHTTPHeaders() report.Report { + r := report.Report{} + + if len(c.HTTPHeaders) < 1 { + return r + } + + u, err := url.Parse(c.Source) + if err != nil { + r.Add(report.Entry{ + Message: errors.ErrInvalidUrl.Error(), + Kind: report.EntryError, + }) + return r + } + + switch u.Scheme { + case "http", "https": + default: + r.Add(report.Entry{ + Message: errors.ErrUnsupportedSchemeForHTTPHeaders.Error(), + Kind: report.EntryError, + }) + } + + return r +} + func (v Ignition) Semver() (*semver.Version, error) { return semver.NewVersion(v.Version) } diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/mode.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/mode.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/mode.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/mode.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/node.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/node.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/node.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/node.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/partition.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/partition.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/partition.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/partition.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/passwd.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/passwd.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/passwd.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/passwd.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/path.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/path.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/path.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/path.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/raid.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/raid.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/raid.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/raid.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/schema.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/schema.go similarity index 96% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/schema.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/schema.go index 7d938cbde..4bf7ec841 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/schema.go +++ b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/schema.go @@ -3,6 +3,7 @@ package types // generated by "schematyper --package=types schema/ignition.json -o internal/config/types/schema.go --root-type=Config" -- DO NOT EDIT type CaReference struct { + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` Source string `json:"source"` Verification Verification `json:"verification,omitempty"` } @@ -16,6 +17,7 @@ type Config struct { } type ConfigReference struct { + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` Source string `json:"source"` Verification Verification `json:"verification,omitempty"` } @@ -51,6 +53,7 @@ type File struct { type FileContents struct { Compression string `json:"compression,omitempty"` + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` Source string `json:"source,omitempty"` Verification Verification `json:"verification,omitempty"` } @@ -69,6 +72,13 @@ type Filesystem struct { type Group string +type HTTPHeader struct { + Name string `json:"name"` + Value string `json:"value"` +} + +type HTTPHeaders []HTTPHeader + type Ignition struct { Config IgnitionConfig `json:"config,omitempty"` Proxy Proxy `json:"proxy,omitempty"` diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/unit.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/unit.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/unit.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/unit.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/url.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/url.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/url.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/url.go diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/verification.go b/vendor/github.com/flatcar-linux/ignition/config/v2_4/types/verification.go similarity index 100% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/verification.go rename to vendor/github.com/flatcar-linux/ignition/config/v2_4/types/verification.go diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/translate/translate.go b/vendor/github.com/flatcar-linux/ignition/v2/config/translate/translate.go new file mode 100644 index 000000000..ee4183a74 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/translate/translate.go @@ -0,0 +1,187 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package translate + +import ( + "fmt" + "reflect" + + "github.com/flatcar-linux/ignition/v2/config/util" +) + +/* + * This is an automatic translator that replace boilerplate code to copy one + * struct into a nearly identical struct in another package. To use it first + * call NewTranslator() to get a translator instance. This can then have + * additional translation rules (in the form of functions) to translate from + * types in one struct to the other. Those functions are in the form: + * func(typeFromInputStruct) -> typeFromOutputStruct + * These can be closures that reference the translator as well. This allows for + * manually translating some fields but resuming automatic translation on the + * other fields through the Translator.Translate() function. + */ + +// Returns if this type can be translated without a custom translator. Children or other +// ancestors might require custom translators however +func (t translator) translatable(t1, t2 reflect.Type) bool { + k1 := t1.Kind() + k2 := t2.Kind() + if k1 != k2 { + return false + } + switch { + case util.IsPrimitive(k1): + return true + case util.IsInvalidInConfig(k1): + panic(fmt.Sprintf("Encountered invalid kind %s in config. This is a bug, please file a report", k1)) + case k1 == reflect.Ptr || k1 == reflect.Slice: + return t.translatable(t1.Elem(), t2.Elem()) || t.hasTranslator(t1.Elem(), t2.Elem()) + case k1 == reflect.Struct: + return t.translatableStruct(t1, t2) + default: + panic(fmt.Sprintf("Encountered unknown kind %s in config. This is a bug, please file a report", k1)) + } +} + +// precondition: t1, t2 are both of Kind 'struct' +func (t translator) translatableStruct(t1, t2 reflect.Type) bool { + if t1.NumField() != t2.NumField() || t1.Name() != t2.Name() { + return false + } + for i := 0; i < t1.NumField(); i++ { + t1f := t1.Field(i) + t2f, ok := t2.FieldByName(t1f.Name) + + if !ok { + return false + } + if !t.translatable(t1f.Type, t2f.Type) && !t.hasTranslator(t1f.Type, t2f.Type) { + return false + } + } + return true +} + +// checks that t could reasonably be the type of a translator function +func couldBeValidTranslator(t reflect.Type) bool { + if t.Kind() != reflect.Func { + return false + } + if t.NumIn() != 1 || t.NumOut() != 1 { + return false + } + if util.IsInvalidInConfig(t.In(0).Kind()) || util.IsInvalidInConfig(t.Out(0).Kind()) { + return false + } + return true +} + +// translate from one type to another, but deep copy all data +// precondition: vFrom and vTo are the same type as defined by translatable() +// precondition: vTo is addressable and settable +func (t translator) translateSameType(vFrom, vTo reflect.Value) { + k := vFrom.Kind() + switch { + case util.IsPrimitive(k): + // Use convert, even if not needed; type alias to primitives are not + // directly assignable and calling Convert on primitives does no harm + vTo.Set(vFrom.Convert(vTo.Type())) + case k == reflect.Ptr: + if vFrom.IsNil() { + return + } + vTo.Set(reflect.New(vTo.Type().Elem())) + t.translate(vFrom.Elem(), vTo.Elem()) + case k == reflect.Slice: + if vFrom.IsNil() { + return + } + vTo.Set(reflect.MakeSlice(vTo.Type(), vFrom.Len(), vFrom.Len())) + for i := 0; i < vFrom.Len(); i++ { + t.translate(vFrom.Index(i), vTo.Index(i)) + } + case k == reflect.Struct: + for i := 0; i < vFrom.NumField(); i++ { + t.translate(vFrom.Field(i), vTo.FieldByName(vFrom.Type().Field(i).Name)) + } + default: + panic("Encountered types that are not the same when they should be. This is a bug, please file a report") + } +} + +// helper to return if a custom translator was defined +func (t translator) hasTranslator(tFrom, tTo reflect.Type) bool { + return t.getTranslator(tFrom, tTo).IsValid() +} + +// vTo must be addressable, should be acquired by calling reflect.ValueOf() on a variable of the correct type +func (t translator) translate(vFrom, vTo reflect.Value) { + tFrom := vFrom.Type() + tTo := vTo.Type() + if fnv := t.getTranslator(tFrom, tTo); fnv.IsValid() { + vTo.Set(fnv.Call([]reflect.Value{vFrom})[0]) + return + } + if t.translatable(tFrom, tTo) { + t.translateSameType(vFrom, vTo) + return + } + + panic(fmt.Sprintf("Translator not defined for %v to %v", tFrom, tTo)) +} + +type Translator interface { + AddCustomTranslator(t interface{}) + Translate(from, to interface{}) +} + +func NewTranslator() Translator { + return &translator{} +} + +type translator struct { + // List of custom translation funcs, must pass couldBeValidTranslator + // This is only for fields that cannot or should not be trivially translated, + // All trivially translated fields use the default behavior. + translators []reflect.Value +} + +func (t *translator) AddCustomTranslator(fn interface{}) { + fnv := reflect.ValueOf(fn) + if !couldBeValidTranslator(fnv.Type()) { + panic("Tried to register invalid translator function") + } + t.translators = append(t.translators, fnv) +} + +func (t translator) getTranslator(from, to reflect.Type) reflect.Value { + for _, fn := range t.translators { + if fn.Type().In(0) == from && fn.Type().Out(0) == to { + return fn + } + } + return reflect.Value{} +} + +func (t translator) Translate(from, to interface{}) { + fv := reflect.ValueOf(from) + tv := reflect.ValueOf(to) + if fv.Kind() != reflect.Ptr || tv.Kind() != reflect.Ptr { + panic("Translate needs to be called on pointers") + } + fv = fv.Elem() + tv = tv.Elem() + t.translate(fv, tv) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/util/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/util/config.go index 9fb88d8e8..89d815b8d 100644 --- a/vendor/github.com/flatcar-linux/ignition/v2/config/util/config.go +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/util/config.go @@ -14,6 +14,8 @@ package util import ( + "strconv" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" "github.com/coreos/go-semver/semver" @@ -24,6 +26,7 @@ type versionStub struct { Ignition struct { Version string } + IgnitionVersion int } // GetConfigVersion parses the version from the given raw config @@ -37,7 +40,13 @@ func GetConfigVersion(raw []byte) (semver.Version, report.Report, error) { return semver.Version{}, rpt, err } - version, err := semver.NewVersion(stub.Ignition.Version) + v := stub.Ignition.Version + // if v is empty, it might be a version 1 configuration. + if v == "" { + v = strconv.Itoa(stub.IgnitionVersion) + ".0.0" + } + + version, err := semver.NewVersion(v) if err != nil { return semver.Version{}, report.Report{}, errors.ErrInvalidVersion } diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/util/parsingErrors.go b/vendor/github.com/flatcar-linux/ignition/v2/config/util/parsingErrors.go index 5e2b4a2bc..061a488d2 100644 --- a/vendor/github.com/flatcar-linux/ignition/v2/config/util/parsingErrors.go +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/util/parsingErrors.go @@ -15,7 +15,12 @@ package util import ( + "bytes" + "compress/gzip" "encoding/json" + "io/ioutil" + "strings" + "unicode" "github.com/flatcar-linux/ignition/v2/config/shared/errors" @@ -24,10 +29,44 @@ import ( "github.com/coreos/vcontext/tree" ) +func isCloudConfig(userdata []byte) bool { + header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0] + + // Trim trailing whitespaces + header = strings.TrimRightFunc(header, unicode.IsSpace) + + return (header == "#cloud-config") +} + +func isScript(userdata []byte) bool { + header := strings.SplitN(string(decompressIfGzipped(userdata)), "\n", 2)[0] + return strings.HasPrefix(header, "#!") +} + +func decompressIfGzipped(data []byte) []byte { + if reader, err := gzip.NewReader(bytes.NewReader(data)); err == nil { + uncompressedData, err := ioutil.ReadAll(reader) + reader.Close() + if err == nil { + return uncompressedData + } else { + return data + } + } else { + return data + } +} + // HandleParseErrors will attempt to unmarshal an invalid rawConfig into "to". // If it fails to unmarsh it will generate a report.Report from the errors. func HandleParseErrors(rawConfig []byte, to interface{}) (report.Report, error) { r := report.Report{} + + if isCloudConfig(rawConfig) || isScript(rawConfig) { + // returning ErrEmpty will make ignition ignoring this user provided config. + return report.Report{}, errors.ErrEmpty + } + err := json.Unmarshal(rawConfig, to) if err == nil { return report.Report{}, nil diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_0/types/url.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_0/types/url.go index 90d903f25..33b7643a3 100644 --- a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_0/types/url.go +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_0/types/url.go @@ -30,7 +30,7 @@ func validateURL(s string) error { } switch u.Scheme { - case "http", "https", "tftp": + case "http", "https", "tftp", "oem": return nil case "s3": if v, ok := u.Query()["versionId"]; ok { diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/config.go new file mode 100644 index 000000000..f7c06856a --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/config.go @@ -0,0 +1,78 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3_1 + +import ( + "github.com/flatcar-linux/ignition/v2/config/merge" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + prev "github.com/flatcar-linux/ignition/v2/config/v3_0" + "github.com/flatcar-linux/ignition/v2/config/v3_1/translate" + "github.com/flatcar-linux/ignition/v2/config/v3_1/types" + "github.com/flatcar-linux/ignition/v2/config/validate" + + "github.com/coreos/go-semver/semver" + "github.com/coreos/vcontext/report" +) + +func Merge(parent, child types.Config) types.Config { + res, _ := merge.MergeStructTranscribe(parent, child) + return res.(types.Config) +} + +// Parse parses the raw config into a types.Config struct and generates a report of any +// errors, warnings, info, and deprecations it encountered +func Parse(rawConfig []byte) (types.Config, report.Report, error) { + if len(rawConfig) == 0 { + return types.Config{}, report.Report{}, errors.ErrEmpty + } + + var config types.Config + if rpt, err := util.HandleParseErrors(rawConfig, &config); err != nil { + return types.Config{}, rpt, err + } + + version, err := semver.NewVersion(config.Ignition.Version) + + if err != nil || *version != types.MaxVersion { + return types.Config{}, report.Report{}, errors.ErrUnknownVersion + } + + rpt := validate.ValidateWithContext(config, rawConfig) + if rpt.IsFatal() { + return types.Config{}, rpt, errors.ErrInvalid + } + + return config, rpt, nil +} + +// ParseCompatibleVersion parses the raw config of version 3.1.0 or lesser +// into a 3.1 types.Config struct and generates a report of any errors, warnings, +// info, and deprecations it encountered +func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) { + version, rpt, err := util.GetConfigVersion(raw) + if err != nil { + return types.Config{}, rpt, err + } + + if version == types.MaxVersion { + return Parse(raw) + } + prevCfg, r, err := prev.ParseCompatibleVersion(raw) + if err != nil { + return types.Config{}, r, err + } + return translate.Translate(prevCfg), r, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/translate/translate.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/translate/translate.go new file mode 100644 index 000000000..d16abc200 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/translate/translate.go @@ -0,0 +1,106 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package translate + +import ( + "github.com/flatcar-linux/ignition/v2/config/translate" + "github.com/flatcar-linux/ignition/v2/config/util" + old_types "github.com/flatcar-linux/ignition/v2/config/v3_0/types" + "github.com/flatcar-linux/ignition/v2/config/v3_1/types" +) + +func translateFilesystem(old old_types.Filesystem) (ret types.Filesystem) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.Translate(&old.Device, &ret.Device) + tr.Translate(&old.Format, &ret.Format) + tr.Translate(&old.Label, &ret.Label) + tr.Translate(&old.Options, &ret.Options) + tr.Translate(&old.Path, &ret.Path) + tr.Translate(&old.UUID, &ret.UUID) + tr.Translate(&old.WipeFilesystem, &ret.WipeFilesystem) + return +} + +func translateConfigReference(old old_types.ConfigReference) (ret types.Resource) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.Translate(&old.Source, &ret.Source) + tr.Translate(&old.Verification, &ret.Verification) + return +} + +func translateCAReference(old old_types.CaReference) (ret types.Resource) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + ret.Source = util.StrToPtr(old.Source) + tr.Translate(&old.Verification, &ret.Verification) + return +} + +func translateFileContents(old old_types.FileContents) (ret types.Resource) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.Translate(&old.Compression, &ret.Compression) + tr.Translate(&old.Source, &ret.Source) + tr.Translate(&old.Verification, &ret.Verification) + return +} + +func translateIgnitionConfig(old old_types.IgnitionConfig) (ret types.IgnitionConfig) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateConfigReference) + tr.Translate(&old.Merge, &ret.Merge) + tr.Translate(&old.Replace, &ret.Replace) + return +} + +func translateSecurity(old old_types.Security) (ret types.Security) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateTLS) + tr.Translate(&old.TLS, &ret.TLS) + return +} + +func translateTLS(old old_types.TLS) (ret types.TLS) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateCAReference) + tr.Translate(&old.CertificateAuthorities, &ret.CertificateAuthorities) + return +} + +func translateIgnition(old old_types.Ignition) (ret types.Ignition) { + // use a new translator so we don't recurse infinitely + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateIgnitionConfig) + tr.AddCustomTranslator(translateSecurity) + tr.Translate(&old.Config, &ret.Config) + tr.Translate(&old.Security, &ret.Security) + tr.Translate(&old.Timeouts, &ret.Timeouts) + ret.Version = types.MaxVersion.String() + return +} + +func Translate(old old_types.Config) (ret types.Config) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateFileContents) + tr.AddCustomTranslator(translateIgnition) + tr.AddCustomTranslator(translateFilesystem) + tr.Translate(&old, &ret) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/config.go new file mode 100644 index 000000000..23ba8dd18 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/config.go @@ -0,0 +1,26 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" +) + +var ( + MaxVersion = semver.Version{ + Major: 3, + Minor: 1, + } +) diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/device.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/device.go new file mode 100644 index 000000000..0fa7c2845 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/device.go @@ -0,0 +1,25 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Device) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c, validatePath(string(d))) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/directory.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/directory.go new file mode 100644 index 000000000..c1cc24404 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/directory.go @@ -0,0 +1,26 @@ +// Copyright 2017 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Directory) Validate(c path.ContextPath) (r report.Report) { + r.Merge(d.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(d.Mode)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/disk.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/disk.go new file mode 100644 index 000000000..3137b6522 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/disk.go @@ -0,0 +1,135 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Disk) Key() string { + return d.Device +} + +func (n Disk) Validate(c path.ContextPath) (r report.Report) { + if len(n.Device) == 0 { + r.AddOnError(c.Append("device"), errors.ErrDiskDeviceRequired) + return + } + r.AddOnError(c.Append("device"), validatePath(n.Device)) + + if collides, p := n.partitionNumbersCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionNumbersCollide) + } + if overlaps, p := n.partitionsOverlap(); overlaps { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionsOverlap) + } + if n.partitionsMixZeroesAndNonexistence() { + r.AddOnError(c.Append("partitions"), errors.ErrZeroesWithShouldNotExist) + } + if collides, p := n.partitionLabelsCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrDuplicateLabels) + } + return +} + +// partitionNumbersCollide returns true if partition numbers in n.Partitions are not unique. It also returns the +// index of the colliding partition +func (n Disk) partitionNumbersCollide() (bool, int) { + m := map[int][]int{} // from partition number to index into array + for i, p := range n.Partitions { + if p.Number != 0 { + // a number of 0 means next available number, multiple devices can specify this + m[p.Number] = append(m[p.Number], i) + } + } + for _, n := range m { + if len(n) > 1 { + // TODO(vc): return information describing the collision for logging + return true, n[1] + } + } + return false, 0 +} + +func (d Disk) partitionLabelsCollide() (bool, int) { + m := map[string]struct{}{} + for i, p := range d.Partitions { + if p.Label != nil { + // a number of 0 means next available number, multiple devices can specify this + if _, exists := m[*p.Label]; exists { + return true, i + } + m[*p.Label] = struct{}{} + } + } + return false, 0 +} + +// end returns the last sector of a partition. Only used by partitionsOverlap. Requires non-nil Start and Size. +func (p Partition) end() int { + if *p.SizeMiB == 0 { + // a size of 0 means "fill available", just return the start as the end for those. + return *p.StartMiB + } + return *p.StartMiB + *p.SizeMiB - 1 +} + +// partitionsOverlap returns true if any explicitly dimensioned partitions overlap. It also returns the index of +// the overlapping partition +func (n Disk) partitionsOverlap() (bool, int) { + for _, p := range n.Partitions { + // Starts of 0 are placed by sgdisk into the "largest available block" at that time. + // We aren't going to check those for overlap since we don't have the disk geometry. + if p.StartMiB == nil || p.SizeMiB == nil || *p.StartMiB == 0 { + continue + } + + for i, o := range n.Partitions { + if o.StartMiB == nil || o.SizeMiB == nil || p == o || *o.StartMiB == 0 { + continue + } + + // is p.StartMiB within o? + if *p.StartMiB >= *o.StartMiB && *p.StartMiB <= o.end() { + return true, i + } + + // is p.end() within o? + if p.end() >= *o.StartMiB && p.end() <= o.end() { + return true, i + } + + // do p.StartMiB and p.end() straddle o? + if *p.StartMiB < *o.StartMiB && p.end() > o.end() { + return true, i + } + } + } + return false, 0 +} + +func (n Disk) partitionsMixZeroesAndNonexistence() bool { + hasZero := false + hasShouldNotExist := false + for _, p := range n.Partitions { + hasShouldNotExist = hasShouldNotExist || util.IsFalse(p.ShouldExist) + hasZero = hasZero || (p.Number == 0) + } + return hasZero && hasShouldNotExist +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/file.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/file.go new file mode 100644 index 000000000..44f24583d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/file.go @@ -0,0 +1,43 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f File) Validate(c path.ContextPath) (r report.Report) { + r.Merge(f.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(f.Mode)) + r.AddOnError(c.Append("overwrite"), f.validateOverwrite()) + return +} + +func (f File) validateOverwrite() error { + if util.IsTrue(f.Overwrite) && f.Contents.Source == nil { + return errors.ErrOverwriteAndNilSource + } + return nil +} + +func (f FileEmbedded1) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Append": {}, + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/filesystem.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/filesystem.go new file mode 100644 index 000000000..0cc4e6661 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/filesystem.go @@ -0,0 +1,106 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f Filesystem) Key() string { + return f.Device +} + +func (f Filesystem) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + "MountOptions": {}, + } +} + +func (f Filesystem) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), f.validatePath()) + r.AddOnError(c.Append("device"), validatePath(f.Device)) + r.AddOnError(c.Append("format"), f.validateFormat()) + r.AddOnError(c.Append("label"), f.validateLabel()) + return +} + +func (f Filesystem) validatePath() error { + return validatePathNilOK(f.Path) +} + +func (f Filesystem) validateFormat() error { + if util.NilOrEmpty(f.Format) { + if util.NotEmpty(f.Path) || + util.NotEmpty(f.Label) || + util.NotEmpty(f.UUID) || + util.IsTrue(f.WipeFilesystem) || + len(f.MountOptions) != 0 || + len(f.Options) != 0 { + return errors.ErrFormatNilWithOthers + } + } else { + switch *f.Format { + case "ext4", "btrfs", "xfs", "swap", "vfat": + default: + return errors.ErrFilesystemInvalidFormat + } + } + return nil +} + +func (f Filesystem) validateLabel() error { + if util.NilOrEmpty(f.Label) { + return nil + } + if util.NilOrEmpty(f.Format) { + return errors.ErrLabelNeedsFormat + } + + switch *f.Format { + case "ext4": + if len(*f.Label) > 16 { + // source: man mkfs.ext4 + return errors.ErrExt4LabelTooLong + } + case "btrfs": + if len(*f.Label) > 256 { + // source: man mkfs.btrfs + return errors.ErrBtrfsLabelTooLong + } + case "xfs": + if len(*f.Label) > 12 { + // source: man mkfs.xfs + return errors.ErrXfsLabelTooLong + } + case "swap": + // mkswap's man page does not state a limit on label size, but through + // experimentation it appears that mkswap will truncate long labels to + // 15 characters, so let's enforce that. + if len(*f.Label) > 15 { + return errors.ErrSwapLabelTooLong + } + case "vfat": + if len(*f.Label) > 11 { + // source: man mkfs.fat + return errors.ErrVfatLabelTooLong + } + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/headers.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/headers.go new file mode 100644 index 000000000..8bac0d636 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/headers.go @@ -0,0 +1,65 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/http" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" +) + +// Parse generates standard net/http headers from the data in HTTPHeaders +func (hs HTTPHeaders) Parse() (http.Header, error) { + headers := http.Header{} + for _, header := range hs { + if header.Name == "" { + return nil, errors.ErrEmptyHTTPHeaderName + } + if header.Value == nil || string(*header.Value) == "" { + return nil, errors.ErrInvalidHTTPHeader + } + headers.Add(header.Name, string(*header.Value)) + } + return headers, nil +} + +func (h HTTPHeader) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), h.validateName()) + r.AddOnError(c.Append("value"), h.validateValue()) + return +} + +func (h HTTPHeader) validateName() error { + if h.Name == "" { + return errors.ErrEmptyHTTPHeaderName + } + return nil +} + +func (h HTTPHeader) validateValue() error { + if h.Value == nil { + return nil + } + if string(*h.Value) == "" { + return errors.ErrInvalidHTTPHeader + } + return nil +} + +func (h HTTPHeader) Key() string { + return h.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/ignition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/ignition.go new file mode 100644 index 000000000..c23e0ed6e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/ignition.go @@ -0,0 +1,49 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (v Ignition) Semver() (*semver.Version, error) { + return semver.NewVersion(v.Version) +} + +func (ic IgnitionConfig) Validate(c path.ContextPath) (r report.Report) { + for i, res := range ic.Merge { + r.AddOnError(c.Append("merge", i), res.validateRequiredSource()) + } + return +} + +func (v Ignition) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("version") + tv, err := v.Semver() + if err != nil { + r.AddOnError(c, errors.ErrInvalidVersion) + return + } + + if MaxVersion != *tv { + r.AddOnError(c, errors.ErrUnknownVersion) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ca.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/mode.go similarity index 68% rename from vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ca.go rename to vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/mode.go index d5045ff42..e4f7f3f75 100644 --- a/vendor/github.com/flatcar-linux/ignition/config/v2_4_experimental/types/ca.go +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/mode.go @@ -1,4 +1,4 @@ -// Copyright 2018 CoreOS, Inc. +// Copyright 2017 CoreOS, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,13 +15,12 @@ package types import ( - "github.com/flatcar-linux/ignition/config/validate/report" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" ) -func (c CaReference) ValidateSource() report.Report { - err := validateURL(c.Source) - if err != nil { - return report.ReportFromError(err, report.EntryError) +func validateMode(m *int) error { + if m != nil && (*m < 0 || *m > 07777) { + return errors.ErrFileIllegalMode } - return report.Report{} + return nil } diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/node.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/node.go new file mode 100644 index 000000000..f030be404 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/node.go @@ -0,0 +1,59 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (n Node) Key() string { + return n.Path +} + +func (n Node) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), validatePath(n.Path)) + return +} + +func (n Node) Depth() int { + count := 0 + for p := path.Clean(string(n.Path)); p != "/"; count++ { + p = path.Dir(p) + } + return count +} + +func validateIDorName(id *int, name *string) error { + if id != nil && util.NotEmpty(name) { + return errors.ErrBothIDAndNameSet + } + return nil +} + +func (nu NodeUser) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(nu.ID, nu.Name)) + return +} + +func (ng NodeGroup) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(ng.ID, ng.Name)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/partition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/partition.go new file mode 100644 index 000000000..567d6930d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/partition.go @@ -0,0 +1,91 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "regexp" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +const ( + guidRegexStr = "^(|[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12})$" +) + +var ( + guidRegex = regexp.MustCompile(guidRegexStr) +) + +func (p Partition) Key() string { + if p.Number != 0 { + return fmt.Sprintf("number:%d", p.Number) + } else if p.Label != nil { + return fmt.Sprintf("label:%s", *p.Label) + } else { + return "" + } +} + +func (p Partition) Validate(c path.ContextPath) (r report.Report) { + if util.IsFalse(p.ShouldExist) && + (p.Label != nil || util.NotEmpty(p.TypeGUID) || util.NotEmpty(p.GUID) || p.StartMiB != nil || p.SizeMiB != nil) { + r.AddOnError(c, errors.ErrShouldNotExistWithOthers) + } + if p.Number == 0 && p.Label == nil { + r.AddOnError(c, errors.ErrNeedLabelOrNumber) + } + + r.AddOnError(c.Append("label"), p.validateLabel()) + r.AddOnError(c.Append("guid"), validateGUID(p.GUID)) + r.AddOnError(c.Append("typeGuid"), validateGUID(p.TypeGUID)) + return +} + +func (p Partition) validateLabel() error { + if p.Label == nil { + return nil + } + // http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries: + // 56 (0x38) 72 bytes Partition name (36 UTF-16LE code units) + + // XXX(vc): note GPT calls it a name, we're using label for consistency + // with udev naming /dev/disk/by-partlabel/*. + if len(*p.Label) > 36 { + return errors.ErrLabelTooLong + } + + // sgdisk uses colons for delimitting compound arguments and does not allow escaping them. + if strings.Contains(*p.Label, ":") { + return errors.ErrLabelContainsColon + } + return nil +} + +func validateGUID(guidPointer *string) error { + if guidPointer == nil { + return nil + } + guid := *guidPointer + if ok := guidRegex.MatchString(guid); !ok { + return errors.ErrDoesntMatchGUIDRegex + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/passwd.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/passwd.go new file mode 100644 index 000000000..ff25eac38 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/passwd.go @@ -0,0 +1,23 @@ +// Copyright 2017 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +func (p PasswdUser) Key() string { + return p.Name +} + +func (g PasswdGroup) Key() string { + return g.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/path.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/path.go new file mode 100644 index 000000000..5757ac868 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/path.go @@ -0,0 +1,42 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validatePath(p string) error { + if p == "" { + return errors.ErrNoPath + } + if !path.IsAbs(p) { + return errors.ErrPathRelative + } + if path.Clean(p) != p { + return errors.ErrDirtyPath + } + return nil +} + +func validatePathNilOK(p *string) error { + if util.NilOrEmpty(p) { + return nil + } + return validatePath(*p) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/proxy.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/proxy.go new file mode 100644 index 000000000..afe121b09 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/proxy.go @@ -0,0 +1,49 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (p Proxy) Validate(c path.ContextPath) (r report.Report) { + validateProxyURL(p.HTTPProxy, c.Append("httpProxy"), &r, true) + validateProxyURL(p.HTTPSProxy, c.Append("httpsProxy"), &r, false) + return +} + +func validateProxyURL(s *string, p path.ContextPath, r *report.Report, httpOk bool) { + if s == nil { + return + } + u, err := url.Parse(*s) + if err != nil { + r.AddOnError(p, errors.ErrInvalidUrl) + return + } + + if u.Scheme != "https" && u.Scheme != "http" { + r.AddOnError(p, errors.ErrInvalidProxy) + return + } + if u.Scheme == "http" && !httpOk { + r.AddOnWarn(p, errors.ErrInsecureProxy) + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/raid.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/raid.go new file mode 100644 index 000000000..85be6d3fa --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/raid.go @@ -0,0 +1,58 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (r Raid) Key() string { + return r.Name +} + +func (r Raid) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + } +} + +func (ra Raid) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("level"), ra.validateLevel()) + if len(ra.Devices) == 0 { + r.AddOnError(c.Append("devices"), errors.ErrRaidDevicesRequired) + } + return +} + +func (r Raid) validateLevel() error { + switch r.Level { + case "linear", "raid0", "0", "stripe": + if r.Spares != nil && *r.Spares != 0 { + return errors.ErrSparesUnsupportedForLevel + } + case "raid1", "1", "mirror": + case "raid4", "4": + case "raid5", "5": + case "raid6", "6": + case "raid10", "10": + default: + return errors.ErrUnrecognizedRaidLevel + } + + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/resource.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/resource.go new file mode 100644 index 000000000..8c03b7f5e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/resource.go @@ -0,0 +1,91 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (res Resource) Key() string { + if res.Source == nil { + return "" + } + return *res.Source +} + +func (res Resource) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("compression"), res.validateCompression()) + r.AddOnError(c.Append("verification", "hash"), res.validateVerification()) + r.AddOnError(c.Append("source"), validateURLNilOK(res.Source)) + r.AddOnError(c.Append("httpHeaders"), res.validateSchemeForHTTPHeaders()) + return +} + +func (res Resource) validateCompression() error { + if res.Compression != nil { + switch *res.Compression { + case "", "gzip": + default: + return errors.ErrCompressionInvalid + } + } + return nil +} + +func (res Resource) validateVerification() error { + if res.Verification.Hash != nil && res.Source == nil { + return errors.ErrVerificationAndNilSource + } + return nil +} + +func (res Resource) validateSchemeForHTTPHeaders() error { + if len(res.HTTPHeaders) < 1 { + return nil + } + + if util.NilOrEmpty(res.Source) { + return errors.ErrInvalidUrl + } + + u, err := url.Parse(*res.Source) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https": + return nil + default: + return errors.ErrUnsupportedSchemeForHTTPHeaders + } +} + +// Ensure that the Source is specified and valid. This is not called by +// Resource.Validate() because some structs that embed Resource don't +// require Source to be specified. Containing structs that require Source +// should call this function from their Validate(). +func (res Resource) validateRequiredSource() error { + if util.NilOrEmpty(res.Source) { + return errors.ErrSourceRequired + } + return validateURL(*res.Source) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/schema.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/schema.go new file mode 100644 index 000000000..94781514f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/schema.go @@ -0,0 +1,211 @@ +package types + +// generated by "schematyper --package=types config/v3_1/schema/ignition.json -o config/v3_1/types/schema.go --root-type=Config" -- DO NOT EDIT + +type Config struct { + Ignition Ignition `json:"ignition"` + Passwd Passwd `json:"passwd,omitempty"` + Storage Storage `json:"storage,omitempty"` + Systemd Systemd `json:"systemd,omitempty"` +} + +type Device string + +type Directory struct { + Node + DirectoryEmbedded1 +} + +type DirectoryEmbedded1 struct { + Mode *int `json:"mode,omitempty"` +} + +type Disk struct { + Device string `json:"device"` + Partitions []Partition `json:"partitions,omitempty"` + WipeTable *bool `json:"wipeTable,omitempty"` +} + +type Dropin struct { + Contents *string `json:"contents,omitempty"` + Name string `json:"name"` +} + +type File struct { + Node + FileEmbedded1 +} + +type FileEmbedded1 struct { + Append []Resource `json:"append,omitempty"` + Contents Resource `json:"contents,omitempty"` + Mode *int `json:"mode,omitempty"` +} + +type Filesystem struct { + Device string `json:"device"` + Format *string `json:"format,omitempty"` + Label *string `json:"label,omitempty"` + MountOptions []MountOption `json:"mountOptions,omitempty"` + Options []FilesystemOption `json:"options,omitempty"` + Path *string `json:"path,omitempty"` + UUID *string `json:"uuid,omitempty"` + WipeFilesystem *bool `json:"wipeFilesystem,omitempty"` +} + +type FilesystemOption string + +type Group string + +type HTTPHeader struct { + Name string `json:"name"` + Value *string `json:"value,omitempty"` +} + +type HTTPHeaders []HTTPHeader + +type Ignition struct { + Config IgnitionConfig `json:"config,omitempty"` + Proxy Proxy `json:"proxy,omitempty"` + Security Security `json:"security,omitempty"` + Timeouts Timeouts `json:"timeouts,omitempty"` + Version string `json:"version,omitempty"` +} + +type IgnitionConfig struct { + Merge []Resource `json:"merge,omitempty"` + Replace Resource `json:"replace,omitempty"` +} + +type Link struct { + Node + LinkEmbedded1 +} + +type LinkEmbedded1 struct { + Hard *bool `json:"hard,omitempty"` + Target string `json:"target"` +} + +type MountOption string + +type NoProxyItem string + +type Node struct { + Group NodeGroup `json:"group,omitempty"` + Overwrite *bool `json:"overwrite,omitempty"` + Path string `json:"path"` + User NodeUser `json:"user,omitempty"` +} + +type NodeGroup struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type NodeUser struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type Partition struct { + GUID *string `json:"guid,omitempty"` + Label *string `json:"label,omitempty"` + Number int `json:"number,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + SizeMiB *int `json:"sizeMiB,omitempty"` + StartMiB *int `json:"startMiB,omitempty"` + TypeGUID *string `json:"typeGuid,omitempty"` + WipePartitionEntry *bool `json:"wipePartitionEntry,omitempty"` +} + +type Passwd struct { + Groups []PasswdGroup `json:"groups,omitempty"` + Users []PasswdUser `json:"users,omitempty"` +} + +type PasswdGroup struct { + Gid *int `json:"gid,omitempty"` + Name string `json:"name"` + PasswordHash *string `json:"passwordHash,omitempty"` + System *bool `json:"system,omitempty"` +} + +type PasswdUser struct { + Gecos *string `json:"gecos,omitempty"` + Groups []Group `json:"groups,omitempty"` + HomeDir *string `json:"homeDir,omitempty"` + Name string `json:"name"` + NoCreateHome *bool `json:"noCreateHome,omitempty"` + NoLogInit *bool `json:"noLogInit,omitempty"` + NoUserGroup *bool `json:"noUserGroup,omitempty"` + PasswordHash *string `json:"passwordHash,omitempty"` + PrimaryGroup *string `json:"primaryGroup,omitempty"` + SSHAuthorizedKeys []SSHAuthorizedKey `json:"sshAuthorizedKeys,omitempty"` + Shell *string `json:"shell,omitempty"` + System *bool `json:"system,omitempty"` + UID *int `json:"uid,omitempty"` +} + +type Proxy struct { + HTTPProxy *string `json:"httpProxy,omitempty"` + HTTPSProxy *string `json:"httpsProxy,omitempty"` + NoProxy []NoProxyItem `json:"noProxy,omitempty"` +} + +type Raid struct { + Devices []Device `json:"devices"` + Level string `json:"level"` + Name string `json:"name"` + Options []RaidOption `json:"options,omitempty"` + Spares *int `json:"spares,omitempty"` +} + +type RaidOption string + +type Resource struct { + Compression *string `json:"compression,omitempty"` + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` + Source *string `json:"source,omitempty"` + Verification Verification `json:"verification,omitempty"` +} + +type SSHAuthorizedKey string + +type Security struct { + TLS TLS `json:"tls,omitempty"` +} + +type Storage struct { + Directories []Directory `json:"directories,omitempty"` + Disks []Disk `json:"disks,omitempty"` + Files []File `json:"files,omitempty"` + Filesystems []Filesystem `json:"filesystems,omitempty"` + Links []Link `json:"links,omitempty"` + Raid []Raid `json:"raid,omitempty"` +} + +type Systemd struct { + Units []Unit `json:"units,omitempty"` +} + +type TLS struct { + CertificateAuthorities []Resource `json:"certificateAuthorities,omitempty"` +} + +type Timeouts struct { + HTTPResponseHeaders *int `json:"httpResponseHeaders,omitempty"` + HTTPTotal *int `json:"httpTotal,omitempty"` +} + +type Unit struct { + Contents *string `json:"contents,omitempty"` + Dropins []Dropin `json:"dropins,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Mask *bool `json:"mask,omitempty"` + Name string `json:"name"` +} + +type Verification struct { + Hash *string `json:"hash,omitempty"` +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/storage.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/storage.go new file mode 100644 index 000000000..44b3bf045 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/storage.go @@ -0,0 +1,71 @@ +// Copyright 2019 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (s Storage) MergedKeys() map[string]string { + return map[string]string{ + "Directories": "Node", + "Files": "Node", + "Links": "Node", + } +} + +func (s Storage) Validate(c vpath.ContextPath) (r report.Report) { + for i, d := range s.Directories { + for _, l := range s.Links { + if strings.HasPrefix(d.Path, l.Path+"/") { + r.AddOnError(c.Append("directories", i), errors.ErrDirectoryUsedSymlink) + } + } + } + for i, f := range s.Files { + for _, l := range s.Links { + if strings.HasPrefix(f.Path, l.Path+"/") { + r.AddOnError(c.Append("files", i), errors.ErrFileUsedSymlink) + } + } + } + for i, l1 := range s.Links { + for _, l2 := range s.Links { + if strings.HasPrefix(l1.Path, l2.Path+"/") { + r.AddOnError(c.Append("links", i), errors.ErrLinkUsedSymlink) + } + } + if !util.IsTrue(l1.Hard) { + continue + } + target := path.Clean(l1.Target) + if !path.IsAbs(target) { + target = path.Join(l1.Path, l1.Target) + } + for _, d := range s.Directories { + if target == d.Path { + r.AddOnError(c.Append("links", i), errors.ErrHardLinkToDirectory) + } + } + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/tls.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/tls.go new file mode 100644 index 000000000..8890e397e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/tls.go @@ -0,0 +1,27 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (tls TLS) Validate(c path.ContextPath) (r report.Report) { + for i, ca := range tls.CertificateAuthorities { + r.AddOnError(c.Append("certificateAuthorities", i), ca.validateRequiredSource()) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/unit.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/unit.go new file mode 100644 index 000000000..200931dd0 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/unit.go @@ -0,0 +1,82 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/shared/validations" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/go-systemd/v22/unit" + cpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (u Unit) Key() string { + return u.Name +} + +func (d Dropin) Key() string { + return d.Name +} + +func (u Unit) Validate(c cpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), validateName(u.Name)) + c = c.Append("contents") + opts, err := validateUnitContent(u.Contents) + r.AddOnError(c, err) + + r.AddOnWarn(c, validations.ValidateInstallSection(u.Name, util.IsTrue(u.Enabled), util.NilOrEmpty(u.Contents), opts)) + + return +} + +func validateName(name string) error { + switch path.Ext(name) { + case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope": + default: + return errors.ErrInvalidSystemdExt + } + return nil +} + +func (d Dropin) Validate(c cpath.ContextPath) (r report.Report) { + _, err := validateUnitContent(d.Contents) + r.AddOnError(c.Append("contents"), err) + + switch path.Ext(d.Name) { + case ".conf": + default: + r.AddOnError(c.Append("name"), errors.ErrInvalidSystemdDropinExt) + } + + return +} + +func validateUnitContent(content *string) ([]*unit.UnitOption, error) { + if content == nil { + return []*unit.UnitOption{}, nil + } + c := strings.NewReader(*content) + opts, err := unit.Deserialize(c) + if err != nil { + return nil, fmt.Errorf("invalid unit content: %s", err) + } + return opts, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/url.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/url.go new file mode 100644 index 000000000..33b7643a3 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/url.go @@ -0,0 +1,57 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/vincent-petithory/dataurl" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validateURL(s string) error { + u, err := url.Parse(s) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https", "tftp", "oem": + return nil + case "s3": + if v, ok := u.Query()["versionId"]; ok { + if len(v) == 0 || v[0] == "" { + return errors.ErrInvalidS3ObjectVersionId + } + } + return nil + case "data": + if _, err := dataurl.DecodeString(s); err != nil { + return err + } + return nil + default: + return errors.ErrInvalidScheme + } +} + +func validateURLNilOK(s *string) error { + if util.NilOrEmpty(s) { + return nil + } + return validateURL(*s) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/verification.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/verification.go new file mode 100644 index 000000000..d1090f9ab --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_1/types/verification.go @@ -0,0 +1,71 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "crypto" + "encoding/hex" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +// HashParts will return the sum and function (in that order) of the hash stored +// in this Verification, or an error if there is an issue during parsing. +func (v Verification) HashParts() (string, string, error) { + if v.Hash == nil { + // The hash can be nil + return "", "", nil + } + parts := strings.SplitN(*v.Hash, "-", 2) + if len(parts) != 2 { + return "", "", errors.ErrHashMalformed + } + + return parts[0], parts[1], nil +} + +func (v Verification) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("hash") + if v.Hash == nil { + // The hash can be nil + return + } + + function, sum, err := v.HashParts() + if err != nil { + r.AddOnError(c, err) + return + } + var hash crypto.Hash + switch function { + case "sha512": + hash = crypto.SHA512 + case "sha256": + hash = crypto.SHA256 + default: + r.AddOnError(c, errors.ErrHashUnrecognized) + return + } + + if len(sum) != hex.EncodedLen(hash.Size()) { + r.AddOnError(c, errors.ErrHashWrongSize) + } + + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/config.go new file mode 100644 index 000000000..3f4ca5228 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/config.go @@ -0,0 +1,78 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3_2 + +import ( + "github.com/flatcar-linux/ignition/v2/config/merge" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + prev "github.com/flatcar-linux/ignition/v2/config/v3_1" + "github.com/flatcar-linux/ignition/v2/config/v3_2/translate" + "github.com/flatcar-linux/ignition/v2/config/v3_2/types" + "github.com/flatcar-linux/ignition/v2/config/validate" + + "github.com/coreos/go-semver/semver" + "github.com/coreos/vcontext/report" +) + +func Merge(parent, child types.Config) types.Config { + res, _ := merge.MergeStructTranscribe(parent, child) + return res.(types.Config) +} + +// Parse parses the raw config into a types.Config struct and generates a report of any +// errors, warnings, info, and deprecations it encountered +func Parse(rawConfig []byte) (types.Config, report.Report, error) { + if len(rawConfig) == 0 { + return types.Config{}, report.Report{}, errors.ErrEmpty + } + + var config types.Config + if rpt, err := util.HandleParseErrors(rawConfig, &config); err != nil { + return types.Config{}, rpt, err + } + + version, err := semver.NewVersion(config.Ignition.Version) + + if err != nil || *version != types.MaxVersion { + return types.Config{}, report.Report{}, errors.ErrUnknownVersion + } + + rpt := validate.ValidateWithContext(config, rawConfig) + if rpt.IsFatal() { + return types.Config{}, rpt, errors.ErrInvalid + } + + return config, rpt, nil +} + +// ParseCompatibleVersion parses the raw config of version 3.2.0 or lesser +// into a 3.2 types.Config struct and generates a report of any errors, warnings, +// info, and deprecations it encountered +func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) { + version, rpt, err := util.GetConfigVersion(raw) + if err != nil { + return types.Config{}, rpt, err + } + + if version == types.MaxVersion { + return Parse(raw) + } + prevCfg, r, err := prev.ParseCompatibleVersion(raw) + if err != nil { + return types.Config{}, r, err + } + return translate.Translate(prevCfg), r, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/translate/translate.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/translate/translate.go new file mode 100644 index 000000000..9066221ff --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/translate/translate.go @@ -0,0 +1,90 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package translate + +import ( + "github.com/flatcar-linux/ignition/v2/config/translate" + old_types "github.com/flatcar-linux/ignition/v2/config/v3_1/types" + "github.com/flatcar-linux/ignition/v2/config/v3_2/types" +) + +func translateIgnition(old old_types.Ignition) (ret types.Ignition) { + // use a new translator so we don't recurse infinitely + translate.NewTranslator().Translate(&old, &ret) + ret.Version = types.MaxVersion.String() + return +} + +func translateStorage(old old_types.Storage) (ret types.Storage) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translatePartition) + tr.Translate(&old.Directories, &ret.Directories) + tr.Translate(&old.Disks, &ret.Disks) + tr.Translate(&old.Files, &ret.Files) + tr.Translate(&old.Filesystems, &ret.Filesystems) + tr.Translate(&old.Links, &ret.Links) + tr.Translate(&old.Raid, &ret.Raid) + return +} + +func translatePasswdUser(old old_types.PasswdUser) (ret types.PasswdUser) { + tr := translate.NewTranslator() + tr.Translate(&old.Gecos, &ret.Gecos) + tr.Translate(&old.Groups, &ret.Groups) + tr.Translate(&old.HomeDir, &ret.HomeDir) + tr.Translate(&old.Name, &ret.Name) + tr.Translate(&old.NoCreateHome, &ret.NoCreateHome) + tr.Translate(&old.NoLogInit, &ret.NoLogInit) + tr.Translate(&old.NoUserGroup, &ret.NoUserGroup) + tr.Translate(&old.PasswordHash, &ret.PasswordHash) + tr.Translate(&old.PrimaryGroup, &ret.PrimaryGroup) + tr.Translate(&old.SSHAuthorizedKeys, &ret.SSHAuthorizedKeys) + tr.Translate(&old.Shell, &ret.Shell) + tr.Translate(&old.System, &ret.System) + tr.Translate(&old.UID, &ret.UID) + return +} + +func translatePasswdGroup(old old_types.PasswdGroup) (ret types.PasswdGroup) { + tr := translate.NewTranslator() + tr.Translate(&old.Gid, &ret.Gid) + tr.Translate(&old.Name, &ret.Name) + tr.Translate(&old.PasswordHash, &ret.PasswordHash) + tr.Translate(&old.System, &ret.System) + return +} + +func translatePartition(old old_types.Partition) (ret types.Partition) { + tr := translate.NewTranslator() + tr.Translate(&old.GUID, &ret.GUID) + tr.Translate(&old.Label, &ret.Label) + tr.Translate(&old.Number, &ret.Number) + tr.Translate(&old.ShouldExist, &ret.ShouldExist) + tr.Translate(&old.SizeMiB, &ret.SizeMiB) + tr.Translate(&old.StartMiB, &ret.StartMiB) + tr.Translate(&old.TypeGUID, &ret.TypeGUID) + tr.Translate(&old.WipePartitionEntry, &ret.WipePartitionEntry) + return +} + +func Translate(old old_types.Config) (ret types.Config) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateIgnition) + tr.AddCustomTranslator(translateStorage) + tr.AddCustomTranslator(translatePasswdUser) + tr.AddCustomTranslator(translatePasswdGroup) + tr.Translate(&old, &ret) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/config.go new file mode 100644 index 000000000..4b18d5378 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/config.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" +) + +var ( + MaxVersion = semver.Version{ + Major: 3, + Minor: 2, + } +) diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/custom.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/custom.go new file mode 100644 index 000000000..5191d1e25 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/custom.go @@ -0,0 +1,37 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (cu Custom) Validate(c path.ContextPath) (r report.Report) { + if cu.Pin == "" && cu.Config == "" { + return + } + switch cu.Pin { + case "tpm2", "tang", "sss": + default: + r.AddOnError(c.Append("pin"), errors.ErrUnknownClevisPin) + } + if cu.Config == "" { + r.AddOnError(c.Append("config"), errors.ErrClevisConfigRequired) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/device.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/device.go new file mode 100644 index 000000000..a10ce97b0 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/device.go @@ -0,0 +1,25 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Device) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c, validatePath(string(d))) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/directory.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/directory.go new file mode 100644 index 000000000..f6f068455 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/directory.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Directory) Validate(c path.ContextPath) (r report.Report) { + r.Merge(d.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(d.Mode)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/disk.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/disk.go new file mode 100644 index 000000000..24c36547d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/disk.go @@ -0,0 +1,135 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Disk) Key() string { + return d.Device +} + +func (n Disk) Validate(c path.ContextPath) (r report.Report) { + if len(n.Device) == 0 { + r.AddOnError(c.Append("device"), errors.ErrDiskDeviceRequired) + return + } + r.AddOnError(c.Append("device"), validatePath(n.Device)) + + if collides, p := n.partitionNumbersCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionNumbersCollide) + } + if overlaps, p := n.partitionsOverlap(); overlaps { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionsOverlap) + } + if n.partitionsMixZeroesAndNonexistence() { + r.AddOnError(c.Append("partitions"), errors.ErrZeroesWithShouldNotExist) + } + if collides, p := n.partitionLabelsCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrDuplicateLabels) + } + return +} + +// partitionNumbersCollide returns true if partition numbers in n.Partitions are not unique. It also returns the +// index of the colliding partition +func (n Disk) partitionNumbersCollide() (bool, int) { + m := map[int][]int{} // from partition number to index into array + for i, p := range n.Partitions { + if p.Number != 0 { + // a number of 0 means next available number, multiple devices can specify this + m[p.Number] = append(m[p.Number], i) + } + } + for _, n := range m { + if len(n) > 1 { + // TODO(vc): return information describing the collision for logging + return true, n[1] + } + } + return false, 0 +} + +func (d Disk) partitionLabelsCollide() (bool, int) { + m := map[string]struct{}{} + for i, p := range d.Partitions { + if p.Label != nil { + // a number of 0 means next available number, multiple devices can specify this + if _, exists := m[*p.Label]; exists { + return true, i + } + m[*p.Label] = struct{}{} + } + } + return false, 0 +} + +// end returns the last sector of a partition. Only used by partitionsOverlap. Requires non-nil Start and Size. +func (p Partition) end() int { + if *p.SizeMiB == 0 { + // a size of 0 means "fill available", just return the start as the end for those. + return *p.StartMiB + } + return *p.StartMiB + *p.SizeMiB - 1 +} + +// partitionsOverlap returns true if any explicitly dimensioned partitions overlap. It also returns the index of +// the overlapping partition +func (n Disk) partitionsOverlap() (bool, int) { + for _, p := range n.Partitions { + // Starts of 0 are placed by sgdisk into the "largest available block" at that time. + // We aren't going to check those for overlap since we don't have the disk geometry. + if p.StartMiB == nil || p.SizeMiB == nil || *p.StartMiB == 0 { + continue + } + + for i, o := range n.Partitions { + if o.StartMiB == nil || o.SizeMiB == nil || p == o || *o.StartMiB == 0 { + continue + } + + // is p.StartMiB within o? + if *p.StartMiB >= *o.StartMiB && *p.StartMiB <= o.end() { + return true, i + } + + // is p.end() within o? + if p.end() >= *o.StartMiB && p.end() <= o.end() { + return true, i + } + + // do p.StartMiB and p.end() straddle o? + if *p.StartMiB < *o.StartMiB && p.end() > o.end() { + return true, i + } + } + } + return false, 0 +} + +func (n Disk) partitionsMixZeroesAndNonexistence() bool { + hasZero := false + hasShouldNotExist := false + for _, p := range n.Partitions { + hasShouldNotExist = hasShouldNotExist || util.IsFalse(p.ShouldExist) + hasZero = hasZero || (p.Number == 0) + } + return hasZero && hasShouldNotExist +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/file.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/file.go new file mode 100644 index 000000000..dafdf5afb --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/file.go @@ -0,0 +1,43 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f File) Validate(c path.ContextPath) (r report.Report) { + r.Merge(f.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(f.Mode)) + r.AddOnError(c.Append("overwrite"), f.validateOverwrite()) + return +} + +func (f File) validateOverwrite() error { + if util.IsTrue(f.Overwrite) && f.Contents.Source == nil { + return errors.ErrOverwriteAndNilSource + } + return nil +} + +func (f FileEmbedded1) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Append": {}, + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/filesystem.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/filesystem.go new file mode 100644 index 000000000..fa68c2d11 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/filesystem.go @@ -0,0 +1,106 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f Filesystem) Key() string { + return f.Device +} + +func (f Filesystem) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + "MountOptions": {}, + } +} + +func (f Filesystem) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), f.validatePath()) + r.AddOnError(c.Append("device"), validatePath(f.Device)) + r.AddOnError(c.Append("format"), f.validateFormat()) + r.AddOnError(c.Append("label"), f.validateLabel()) + return +} + +func (f Filesystem) validatePath() error { + return validatePathNilOK(f.Path) +} + +func (f Filesystem) validateFormat() error { + if util.NilOrEmpty(f.Format) { + if util.NotEmpty(f.Path) || + util.NotEmpty(f.Label) || + util.NotEmpty(f.UUID) || + util.IsTrue(f.WipeFilesystem) || + len(f.MountOptions) != 0 || + len(f.Options) != 0 { + return errors.ErrFormatNilWithOthers + } + } else { + switch *f.Format { + case "ext4", "btrfs", "xfs", "swap", "vfat": + default: + return errors.ErrFilesystemInvalidFormat + } + } + return nil +} + +func (f Filesystem) validateLabel() error { + if util.NilOrEmpty(f.Label) { + return nil + } + if util.NilOrEmpty(f.Format) { + return errors.ErrLabelNeedsFormat + } + + switch *f.Format { + case "ext4": + if len(*f.Label) > 16 { + // source: man mkfs.ext4 + return errors.ErrExt4LabelTooLong + } + case "btrfs": + if len(*f.Label) > 256 { + // source: man mkfs.btrfs + return errors.ErrBtrfsLabelTooLong + } + case "xfs": + if len(*f.Label) > 12 { + // source: man mkfs.xfs + return errors.ErrXfsLabelTooLong + } + case "swap": + // mkswap's man page does not state a limit on label size, but through + // experimentation it appears that mkswap will truncate long labels to + // 15 characters, so let's enforce that. + if len(*f.Label) > 15 { + return errors.ErrSwapLabelTooLong + } + case "vfat": + if len(*f.Label) > 11 { + // source: man mkfs.fat + return errors.ErrVfatLabelTooLong + } + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/headers.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/headers.go new file mode 100644 index 000000000..8bac0d636 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/headers.go @@ -0,0 +1,65 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/http" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" +) + +// Parse generates standard net/http headers from the data in HTTPHeaders +func (hs HTTPHeaders) Parse() (http.Header, error) { + headers := http.Header{} + for _, header := range hs { + if header.Name == "" { + return nil, errors.ErrEmptyHTTPHeaderName + } + if header.Value == nil || string(*header.Value) == "" { + return nil, errors.ErrInvalidHTTPHeader + } + headers.Add(header.Name, string(*header.Value)) + } + return headers, nil +} + +func (h HTTPHeader) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), h.validateName()) + r.AddOnError(c.Append("value"), h.validateValue()) + return +} + +func (h HTTPHeader) validateName() error { + if h.Name == "" { + return errors.ErrEmptyHTTPHeaderName + } + return nil +} + +func (h HTTPHeader) validateValue() error { + if h.Value == nil { + return nil + } + if string(*h.Value) == "" { + return errors.ErrInvalidHTTPHeader + } + return nil +} + +func (h HTTPHeader) Key() string { + return h.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/ignition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/ignition.go new file mode 100644 index 000000000..746218a62 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/ignition.go @@ -0,0 +1,49 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (v Ignition) Semver() (*semver.Version, error) { + return semver.NewVersion(v.Version) +} + +func (ic IgnitionConfig) Validate(c path.ContextPath) (r report.Report) { + for i, res := range ic.Merge { + r.AddOnError(c.Append("merge", i), res.validateRequiredSource()) + } + return +} + +func (v Ignition) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("version") + tv, err := v.Semver() + if err != nil { + r.AddOnError(c, errors.ErrInvalidVersion) + return + } + + if MaxVersion != *tv { + r.AddOnError(c, errors.ErrUnknownVersion) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/luks.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/luks.go new file mode 100644 index 000000000..592d49b8a --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/luks.go @@ -0,0 +1,73 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (l Luks) Key() string { + return l.Name +} + +func (l Luks) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + } +} + +func (l Luks) Validate(c path.ContextPath) (r report.Report) { + if strings.Contains(l.Name, "/") { + r.AddOnError(c.Append("name"), errors.ErrLuksNameContainsSlash) + } + r.AddOnError(c.Append("label"), l.validateLabel()) + if util.NilOrEmpty(l.Device) { + r.AddOnError(c.Append("device"), errors.ErrDiskDeviceRequired) + } else { + r.AddOnError(c.Append("device"), validatePath(*l.Device)) + } + + if l.Clevis != nil { + if l.Clevis.Custom != nil && (len(l.Clevis.Tang) > 0 || util.IsTrue(l.Clevis.Tpm2) || (l.Clevis.Threshold != nil && *l.Clevis.Threshold != 0)) { + r.AddOnError(c.Append("clevis"), errors.ErrClevisCustomWithOthers) + } + } + + // fail if a key file is provided and is not valid + if err := validateURLNilOK(l.KeyFile.Source); err != nil { + r.AddOnError(c.Append("keys"), errors.ErrInvalidLuksKeyFile) + } + return +} + +func (l Luks) validateLabel() error { + if util.NilOrEmpty(l.Label) { + return nil + } + + if len(*l.Label) > 47 { + // LUKS2_LABEL_L has a maximum length of 48 (including the null terminator) + // https://gitlab.com/cryptsetup/cryptsetup/-/blob/1633f030e89ad2f11ae649ba9600997a41abd3fc/lib/luks2/luks2.h#L86 + return errors.ErrLuksLabelTooLong + } + + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/mode.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/mode.go new file mode 100644 index 000000000..5e57bb651 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/mode.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" +) + +func validateMode(m *int) error { + if m != nil && (*m < 0 || *m > 07777) { + return errors.ErrFileIllegalMode + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/node.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/node.go new file mode 100644 index 000000000..e23730f23 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/node.go @@ -0,0 +1,59 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (n Node) Key() string { + return n.Path +} + +func (n Node) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), validatePath(n.Path)) + return +} + +func (n Node) Depth() int { + count := 0 + for p := path.Clean(string(n.Path)); p != "/"; count++ { + p = path.Dir(p) + } + return count +} + +func validateIDorName(id *int, name *string) error { + if id != nil && util.NotEmpty(name) { + return errors.ErrBothIDAndNameSet + } + return nil +} + +func (nu NodeUser) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(nu.ID, nu.Name)) + return +} + +func (ng NodeGroup) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(ng.ID, ng.Name)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/partition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/partition.go new file mode 100644 index 000000000..8363be285 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/partition.go @@ -0,0 +1,91 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "regexp" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +const ( + guidRegexStr = "^(|[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12})$" +) + +var ( + guidRegex = regexp.MustCompile(guidRegexStr) +) + +func (p Partition) Key() string { + if p.Number != 0 { + return fmt.Sprintf("number:%d", p.Number) + } else if p.Label != nil { + return fmt.Sprintf("label:%s", *p.Label) + } else { + return "" + } +} + +func (p Partition) Validate(c path.ContextPath) (r report.Report) { + if util.IsFalse(p.ShouldExist) && + (p.Label != nil || util.NotEmpty(p.TypeGUID) || util.NotEmpty(p.GUID) || p.StartMiB != nil || p.SizeMiB != nil) { + r.AddOnError(c, errors.ErrShouldNotExistWithOthers) + } + if p.Number == 0 && p.Label == nil { + r.AddOnError(c, errors.ErrNeedLabelOrNumber) + } + + r.AddOnError(c.Append("label"), p.validateLabel()) + r.AddOnError(c.Append("guid"), validateGUID(p.GUID)) + r.AddOnError(c.Append("typeGuid"), validateGUID(p.TypeGUID)) + return +} + +func (p Partition) validateLabel() error { + if p.Label == nil { + return nil + } + // http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries: + // 56 (0x38) 72 bytes Partition name (36 UTF-16LE code units) + + // XXX(vc): note GPT calls it a name, we're using label for consistency + // with udev naming /dev/disk/by-partlabel/*. + if len(*p.Label) > 36 { + return errors.ErrLabelTooLong + } + + // sgdisk uses colons for delimitting compound arguments and does not allow escaping them. + if strings.Contains(*p.Label, ":") { + return errors.ErrLabelContainsColon + } + return nil +} + +func validateGUID(guidPointer *string) error { + if guidPointer == nil { + return nil + } + guid := *guidPointer + if ok := guidRegex.MatchString(guid); !ok { + return errors.ErrDoesntMatchGUIDRegex + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/passwd.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/passwd.go new file mode 100644 index 000000000..4060a2a6f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/passwd.go @@ -0,0 +1,23 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +func (p PasswdUser) Key() string { + return p.Name +} + +func (g PasswdGroup) Key() string { + return g.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/path.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/path.go new file mode 100644 index 000000000..d6d394a7f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/path.go @@ -0,0 +1,42 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validatePath(p string) error { + if p == "" { + return errors.ErrNoPath + } + if !path.IsAbs(p) { + return errors.ErrPathRelative + } + if path.Clean(p) != p { + return errors.ErrDirtyPath + } + return nil +} + +func validatePathNilOK(p *string) error { + if util.NilOrEmpty(p) { + return nil + } + return validatePath(*p) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/proxy.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/proxy.go new file mode 100644 index 000000000..088459d8f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/proxy.go @@ -0,0 +1,49 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (p Proxy) Validate(c path.ContextPath) (r report.Report) { + validateProxyURL(p.HTTPProxy, c.Append("httpProxy"), &r, true) + validateProxyURL(p.HTTPSProxy, c.Append("httpsProxy"), &r, false) + return +} + +func validateProxyURL(s *string, p path.ContextPath, r *report.Report, httpOk bool) { + if s == nil { + return + } + u, err := url.Parse(*s) + if err != nil { + r.AddOnError(p, errors.ErrInvalidUrl) + return + } + + if u.Scheme != "https" && u.Scheme != "http" { + r.AddOnError(p, errors.ErrInvalidProxy) + return + } + if u.Scheme == "http" && !httpOk { + r.AddOnWarn(p, errors.ErrInsecureProxy) + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/raid.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/raid.go new file mode 100644 index 000000000..22155cd0f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/raid.go @@ -0,0 +1,58 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (r Raid) Key() string { + return r.Name +} + +func (r Raid) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + } +} + +func (ra Raid) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("level"), ra.validateLevel()) + if len(ra.Devices) == 0 { + r.AddOnError(c.Append("devices"), errors.ErrRaidDevicesRequired) + } + return +} + +func (r Raid) validateLevel() error { + switch r.Level { + case "linear", "raid0", "0", "stripe": + if r.Spares != nil && *r.Spares != 0 { + return errors.ErrSparesUnsupportedForLevel + } + case "raid1", "1", "mirror": + case "raid4", "4": + case "raid5", "5": + case "raid6", "6": + case "raid10", "10": + default: + return errors.ErrUnrecognizedRaidLevel + } + + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/resource.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/resource.go new file mode 100644 index 000000000..8c03b7f5e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/resource.go @@ -0,0 +1,91 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (res Resource) Key() string { + if res.Source == nil { + return "" + } + return *res.Source +} + +func (res Resource) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("compression"), res.validateCompression()) + r.AddOnError(c.Append("verification", "hash"), res.validateVerification()) + r.AddOnError(c.Append("source"), validateURLNilOK(res.Source)) + r.AddOnError(c.Append("httpHeaders"), res.validateSchemeForHTTPHeaders()) + return +} + +func (res Resource) validateCompression() error { + if res.Compression != nil { + switch *res.Compression { + case "", "gzip": + default: + return errors.ErrCompressionInvalid + } + } + return nil +} + +func (res Resource) validateVerification() error { + if res.Verification.Hash != nil && res.Source == nil { + return errors.ErrVerificationAndNilSource + } + return nil +} + +func (res Resource) validateSchemeForHTTPHeaders() error { + if len(res.HTTPHeaders) < 1 { + return nil + } + + if util.NilOrEmpty(res.Source) { + return errors.ErrInvalidUrl + } + + u, err := url.Parse(*res.Source) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https": + return nil + default: + return errors.ErrUnsupportedSchemeForHTTPHeaders + } +} + +// Ensure that the Source is specified and valid. This is not called by +// Resource.Validate() because some structs that embed Resource don't +// require Source to be specified. Containing structs that require Source +// should call this function from their Validate(). +func (res Resource) validateRequiredSource() error { + if util.NilOrEmpty(res.Source) { + return errors.ErrSourceRequired + } + return validateURL(*res.Source) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/schema.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/schema.go new file mode 100644 index 000000000..b02c5a48e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/schema.go @@ -0,0 +1,246 @@ +package types + +// generated by "schematyper --package=types config/v3_2/schema/ignition.json -o config/v3_2/types/schema.go --root-type=Config" -- DO NOT EDIT + +type Clevis struct { + Custom *Custom `json:"custom,omitempty"` + Tang []Tang `json:"tang,omitempty"` + Threshold *int `json:"threshold,omitempty"` + Tpm2 *bool `json:"tpm2,omitempty"` +} + +type Config struct { + Ignition Ignition `json:"ignition"` + Passwd Passwd `json:"passwd,omitempty"` + Storage Storage `json:"storage,omitempty"` + Systemd Systemd `json:"systemd,omitempty"` +} + +type Custom struct { + Config string `json:"config"` + NeedsNetwork *bool `json:"needsNetwork,omitempty"` + Pin string `json:"pin"` +} + +type Device string + +type Directory struct { + Node + DirectoryEmbedded1 +} + +type DirectoryEmbedded1 struct { + Mode *int `json:"mode,omitempty"` +} + +type Disk struct { + Device string `json:"device"` + Partitions []Partition `json:"partitions,omitempty"` + WipeTable *bool `json:"wipeTable,omitempty"` +} + +type Dropin struct { + Contents *string `json:"contents,omitempty"` + Name string `json:"name"` +} + +type File struct { + Node + FileEmbedded1 +} + +type FileEmbedded1 struct { + Append []Resource `json:"append,omitempty"` + Contents Resource `json:"contents,omitempty"` + Mode *int `json:"mode,omitempty"` +} + +type Filesystem struct { + Device string `json:"device"` + Format *string `json:"format,omitempty"` + Label *string `json:"label,omitempty"` + MountOptions []MountOption `json:"mountOptions,omitempty"` + Options []FilesystemOption `json:"options,omitempty"` + Path *string `json:"path,omitempty"` + UUID *string `json:"uuid,omitempty"` + WipeFilesystem *bool `json:"wipeFilesystem,omitempty"` +} + +type FilesystemOption string + +type Group string + +type HTTPHeader struct { + Name string `json:"name"` + Value *string `json:"value,omitempty"` +} + +type HTTPHeaders []HTTPHeader + +type Ignition struct { + Config IgnitionConfig `json:"config,omitempty"` + Proxy Proxy `json:"proxy,omitempty"` + Security Security `json:"security,omitempty"` + Timeouts Timeouts `json:"timeouts,omitempty"` + Version string `json:"version,omitempty"` +} + +type IgnitionConfig struct { + Merge []Resource `json:"merge,omitempty"` + Replace Resource `json:"replace,omitempty"` +} + +type Link struct { + Node + LinkEmbedded1 +} + +type LinkEmbedded1 struct { + Hard *bool `json:"hard,omitempty"` + Target string `json:"target"` +} + +type Luks struct { + Clevis *Clevis `json:"clevis,omitempty"` + Device *string `json:"device,omitempty"` + KeyFile Resource `json:"keyFile,omitempty"` + Label *string `json:"label,omitempty"` + Name string `json:"name"` + Options []LuksOption `json:"options,omitempty"` + UUID *string `json:"uuid,omitempty"` + WipeVolume *bool `json:"wipeVolume,omitempty"` +} + +type LuksOption string + +type MountOption string + +type NoProxyItem string + +type Node struct { + Group NodeGroup `json:"group,omitempty"` + Overwrite *bool `json:"overwrite,omitempty"` + Path string `json:"path"` + User NodeUser `json:"user,omitempty"` +} + +type NodeGroup struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type NodeUser struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type Partition struct { + GUID *string `json:"guid,omitempty"` + Label *string `json:"label,omitempty"` + Number int `json:"number,omitempty"` + Resize *bool `json:"resize,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + SizeMiB *int `json:"sizeMiB,omitempty"` + StartMiB *int `json:"startMiB,omitempty"` + TypeGUID *string `json:"typeGuid,omitempty"` + WipePartitionEntry *bool `json:"wipePartitionEntry,omitempty"` +} + +type Passwd struct { + Groups []PasswdGroup `json:"groups,omitempty"` + Users []PasswdUser `json:"users,omitempty"` +} + +type PasswdGroup struct { + Gid *int `json:"gid,omitempty"` + Name string `json:"name"` + PasswordHash *string `json:"passwordHash,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + System *bool `json:"system,omitempty"` +} + +type PasswdUser struct { + Gecos *string `json:"gecos,omitempty"` + Groups []Group `json:"groups,omitempty"` + HomeDir *string `json:"homeDir,omitempty"` + Name string `json:"name"` + NoCreateHome *bool `json:"noCreateHome,omitempty"` + NoLogInit *bool `json:"noLogInit,omitempty"` + NoUserGroup *bool `json:"noUserGroup,omitempty"` + PasswordHash *string `json:"passwordHash,omitempty"` + PrimaryGroup *string `json:"primaryGroup,omitempty"` + SSHAuthorizedKeys []SSHAuthorizedKey `json:"sshAuthorizedKeys,omitempty"` + Shell *string `json:"shell,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + System *bool `json:"system,omitempty"` + UID *int `json:"uid,omitempty"` +} + +type Proxy struct { + HTTPProxy *string `json:"httpProxy,omitempty"` + HTTPSProxy *string `json:"httpsProxy,omitempty"` + NoProxy []NoProxyItem `json:"noProxy,omitempty"` +} + +type Raid struct { + Devices []Device `json:"devices"` + Level string `json:"level"` + Name string `json:"name"` + Options []RaidOption `json:"options,omitempty"` + Spares *int `json:"spares,omitempty"` +} + +type RaidOption string + +type Resource struct { + Compression *string `json:"compression,omitempty"` + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` + Source *string `json:"source,omitempty"` + Verification Verification `json:"verification,omitempty"` +} + +type SSHAuthorizedKey string + +type Security struct { + TLS TLS `json:"tls,omitempty"` +} + +type Storage struct { + Directories []Directory `json:"directories,omitempty"` + Disks []Disk `json:"disks,omitempty"` + Files []File `json:"files,omitempty"` + Filesystems []Filesystem `json:"filesystems,omitempty"` + Links []Link `json:"links,omitempty"` + Luks []Luks `json:"luks,omitempty"` + Raid []Raid `json:"raid,omitempty"` +} + +type Systemd struct { + Units []Unit `json:"units,omitempty"` +} + +type TLS struct { + CertificateAuthorities []Resource `json:"certificateAuthorities,omitempty"` +} + +type Tang struct { + Thumbprint *string `json:"thumbprint,omitempty"` + URL string `json:"url,omitempty"` +} + +type Timeouts struct { + HTTPResponseHeaders *int `json:"httpResponseHeaders,omitempty"` + HTTPTotal *int `json:"httpTotal,omitempty"` +} + +type Unit struct { + Contents *string `json:"contents,omitempty"` + Dropins []Dropin `json:"dropins,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Mask *bool `json:"mask,omitempty"` + Name string `json:"name"` +} + +type Verification struct { + Hash *string `json:"hash,omitempty"` +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/storage.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/storage.go new file mode 100644 index 000000000..9e3e29311 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/storage.go @@ -0,0 +1,71 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (s Storage) MergedKeys() map[string]string { + return map[string]string{ + "Directories": "Node", + "Files": "Node", + "Links": "Node", + } +} + +func (s Storage) Validate(c vpath.ContextPath) (r report.Report) { + for i, d := range s.Directories { + for _, l := range s.Links { + if strings.HasPrefix(d.Path, l.Path+"/") { + r.AddOnError(c.Append("directories", i), errors.ErrDirectoryUsedSymlink) + } + } + } + for i, f := range s.Files { + for _, l := range s.Links { + if strings.HasPrefix(f.Path, l.Path+"/") { + r.AddOnError(c.Append("files", i), errors.ErrFileUsedSymlink) + } + } + } + for i, l1 := range s.Links { + for _, l2 := range s.Links { + if strings.HasPrefix(l1.Path, l2.Path+"/") { + r.AddOnError(c.Append("links", i), errors.ErrLinkUsedSymlink) + } + } + if !util.IsTrue(l1.Hard) { + continue + } + target := path.Clean(l1.Target) + if !path.IsAbs(target) { + target = path.Join(l1.Path, l1.Target) + } + for _, d := range s.Directories { + if target == d.Path { + r.AddOnError(c.Append("links", i), errors.ErrHardLinkToDirectory) + } + } + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tang.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tang.go new file mode 100644 index 000000000..d6df1d986 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tang.go @@ -0,0 +1,51 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (t Tang) Key() string { + return t.URL +} + +func (t Tang) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("url"), validateTangURL(t.URL)) + if util.NilOrEmpty(t.Thumbprint) { + r.AddOnError(c.Append("thumbprint"), errors.ErrTangThumbprintRequired) + } + return +} + +func validateTangURL(s string) error { + u, err := url.Parse(s) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https": + return nil + default: + return errors.ErrInvalidScheme + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tls.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tls.go new file mode 100644 index 000000000..8890e397e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/tls.go @@ -0,0 +1,27 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (tls TLS) Validate(c path.ContextPath) (r report.Report) { + for i, ca := range tls.CertificateAuthorities { + r.AddOnError(c.Append("certificateAuthorities", i), ca.validateRequiredSource()) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/unit.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/unit.go new file mode 100644 index 000000000..933163a75 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/unit.go @@ -0,0 +1,82 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/shared/validations" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/go-systemd/v22/unit" + cpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (u Unit) Key() string { + return u.Name +} + +func (d Dropin) Key() string { + return d.Name +} + +func (u Unit) Validate(c cpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), validateName(u.Name)) + c = c.Append("contents") + opts, err := validateUnitContent(u.Contents) + r.AddOnError(c, err) + + r.AddOnWarn(c, validations.ValidateInstallSection(u.Name, util.IsTrue(u.Enabled), util.NilOrEmpty(u.Contents), opts)) + + return +} + +func validateName(name string) error { + switch path.Ext(name) { + case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope": + default: + return errors.ErrInvalidSystemdExt + } + return nil +} + +func (d Dropin) Validate(c cpath.ContextPath) (r report.Report) { + _, err := validateUnitContent(d.Contents) + r.AddOnError(c.Append("contents"), err) + + switch path.Ext(d.Name) { + case ".conf": + default: + r.AddOnError(c.Append("name"), errors.ErrInvalidSystemdDropinExt) + } + + return +} + +func validateUnitContent(content *string) ([]*unit.UnitOption, error) { + if content == nil { + return []*unit.UnitOption{}, nil + } + c := strings.NewReader(*content) + opts, err := unit.Deserialize(c) + if err != nil { + return nil, fmt.Errorf("invalid unit content: %s", err) + } + return opts, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/url.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/url.go new file mode 100644 index 000000000..8f3da4d9d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/url.go @@ -0,0 +1,57 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/vincent-petithory/dataurl" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validateURL(s string) error { + u, err := url.Parse(s) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https", "tftp", "gs", "oem": + return nil + case "s3": + if v, ok := u.Query()["versionId"]; ok { + if len(v) == 0 || v[0] == "" { + return errors.ErrInvalidS3ObjectVersionId + } + } + return nil + case "data": + if _, err := dataurl.DecodeString(s); err != nil { + return err + } + return nil + default: + return errors.ErrInvalidScheme + } +} + +func validateURLNilOK(s *string) error { + if util.NilOrEmpty(s) { + return nil + } + return validateURL(*s) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/verification.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/verification.go new file mode 100644 index 000000000..0aaba72a1 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_2/types/verification.go @@ -0,0 +1,71 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "crypto" + "encoding/hex" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +// HashParts will return the sum and function (in that order) of the hash stored +// in this Verification, or an error if there is an issue during parsing. +func (v Verification) HashParts() (string, string, error) { + if v.Hash == nil { + // The hash can be nil + return "", "", nil + } + parts := strings.SplitN(*v.Hash, "-", 2) + if len(parts) != 2 { + return "", "", errors.ErrHashMalformed + } + + return parts[0], parts[1], nil +} + +func (v Verification) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("hash") + if v.Hash == nil { + // The hash can be nil + return + } + + function, sum, err := v.HashParts() + if err != nil { + r.AddOnError(c, err) + return + } + var hash crypto.Hash + switch function { + case "sha512": + hash = crypto.SHA512 + case "sha256": + hash = crypto.SHA256 + default: + r.AddOnError(c, errors.ErrHashUnrecognized) + return + } + + if len(sum) != hex.EncodedLen(hash.Size()) { + r.AddOnError(c, errors.ErrHashWrongSize) + } + + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/config.go new file mode 100644 index 000000000..7a4dec23c --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/config.go @@ -0,0 +1,78 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3_3 + +import ( + "github.com/flatcar-linux/ignition/v2/config/merge" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + prev "github.com/flatcar-linux/ignition/v2/config/v3_2" + "github.com/flatcar-linux/ignition/v2/config/v3_3/translate" + "github.com/flatcar-linux/ignition/v2/config/v3_3/types" + "github.com/flatcar-linux/ignition/v2/config/validate" + + "github.com/coreos/go-semver/semver" + "github.com/coreos/vcontext/report" +) + +func Merge(parent, child types.Config) types.Config { + res, _ := merge.MergeStructTranscribe(parent, child) + return res.(types.Config) +} + +// Parse parses the raw config into a types.Config struct and generates a report of any +// errors, warnings, info, and deprecations it encountered +func Parse(rawConfig []byte) (types.Config, report.Report, error) { + if len(rawConfig) == 0 { + return types.Config{}, report.Report{}, errors.ErrEmpty + } + + var config types.Config + if rpt, err := util.HandleParseErrors(rawConfig, &config); err != nil { + return types.Config{}, rpt, err + } + + version, err := semver.NewVersion(config.Ignition.Version) + + if err != nil || *version != types.MaxVersion { + return types.Config{}, report.Report{}, errors.ErrUnknownVersion + } + + rpt := validate.ValidateWithContext(config, rawConfig) + if rpt.IsFatal() { + return types.Config{}, rpt, errors.ErrInvalid + } + + return config, rpt, nil +} + +// ParseCompatibleVersion parses the raw config of version 3.3.0 or +// lesser into a 3.3 types.Config struct and generates a report of any errors, +// warnings, info, and deprecations it encountered +func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) { + version, rpt, err := util.GetConfigVersion(raw) + if err != nil { + return types.Config{}, rpt, err + } + + if version == types.MaxVersion { + return Parse(raw) + } + prevCfg, r, err := prev.ParseCompatibleVersion(raw) + if err != nil { + return types.Config{}, r, err + } + return translate.Translate(prevCfg), r, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/translate/translate.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/translate/translate.go new file mode 100644 index 000000000..970c4db8e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/translate/translate.go @@ -0,0 +1,95 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package translate + +import ( + "github.com/flatcar-linux/ignition/v2/config/translate" + "github.com/flatcar-linux/ignition/v2/config/util" + old_types "github.com/flatcar-linux/ignition/v2/config/v3_2/types" + "github.com/flatcar-linux/ignition/v2/config/v3_3/types" +) + +func translateIgnition(old old_types.Ignition) (ret types.Ignition) { + // use a new translator so we don't recurse infinitely + translate.NewTranslator().Translate(&old, &ret) + ret.Version = types.MaxVersion.String() + return +} + +func translateRaid(old old_types.Raid) (ret types.Raid) { + tr := translate.NewTranslator() + tr.Translate(&old.Devices, &ret.Devices) + ret.Level = util.StrToPtr(old.Level) + tr.Translate(&old.Name, &ret.Name) + tr.Translate(&old.Options, &ret.Options) + tr.Translate(&old.Spares, &ret.Spares) + return +} + +func translateLuks(old old_types.Luks) (ret types.Luks) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateClevis) + if old.Clevis != nil { + tr.Translate(old.Clevis, &ret.Clevis) + } + tr.Translate(&old.Device, &ret.Device) + tr.Translate(&old.KeyFile, &ret.KeyFile) + tr.Translate(&old.Label, &ret.Label) + tr.Translate(&old.Name, &ret.Name) + tr.Translate(&old.Options, &ret.Options) + tr.Translate(&old.UUID, &ret.UUID) + tr.Translate(&old.WipeVolume, &ret.WipeVolume) + return +} + +func translateClevis(old old_types.Clevis) (ret types.Clevis) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateClevisCustom) + if old.Custom != nil { + tr.Translate(old.Custom, &ret.Custom) + } + tr.Translate(&old.Tang, &ret.Tang) + tr.Translate(&old.Threshold, &ret.Threshold) + tr.Translate(&old.Tpm2, &ret.Tpm2) + return +} + +func translateClevisCustom(old old_types.Custom) (ret types.ClevisCustom) { + tr := translate.NewTranslator() + ret.Config = util.StrToPtr(old.Config) + tr.Translate(&old.NeedsNetwork, &ret.NeedsNetwork) + ret.Pin = util.StrToPtr(old.Pin) + return +} + +func translateLinkEmbedded1(old old_types.LinkEmbedded1) (ret types.LinkEmbedded1) { + tr := translate.NewTranslator() + tr.Translate(&old.Hard, &ret.Hard) + ret.Target = util.StrToPtr(old.Target) + return +} + +func Translate(old old_types.Config) (ret types.Config) { + tr := translate.NewTranslator() + tr.AddCustomTranslator(translateIgnition) + tr.AddCustomTranslator(translateRaid) + tr.AddCustomTranslator(translateLuks) + tr.AddCustomTranslator(translateLinkEmbedded1) + tr.Translate(&old.Ignition, &ret.Ignition) + tr.Translate(&old.Passwd, &ret.Passwd) + tr.Translate(&old.Storage, &ret.Storage) + tr.Translate(&old.Systemd, &ret.Systemd) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/clevis.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/clevis.go new file mode 100644 index 000000000..6ac55ec60 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/clevis.go @@ -0,0 +1,49 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (c Clevis) IsPresent() bool { + return util.NotEmpty(c.Custom.Pin) || + len(c.Tang) > 0 || + util.IsTrue(c.Tpm2) || + c.Threshold != nil && *c.Threshold != 0 +} + +func (cu ClevisCustom) Validate(c path.ContextPath) (r report.Report) { + if util.NilOrEmpty(cu.Pin) && util.NilOrEmpty(cu.Config) && !util.IsTrue(cu.NeedsNetwork) { + return + } + if util.NotEmpty(cu.Pin) { + switch *cu.Pin { + case "tpm2", "tang", "sss": + default: + r.AddOnError(c.Append("pin"), errors.ErrUnknownClevisPin) + } + } else { + r.AddOnError(c.Append("pin"), errors.ErrClevisPinRequired) + } + if util.NilOrEmpty(cu.Config) { + r.AddOnError(c.Append("config"), errors.ErrClevisConfigRequired) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/config.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/config.go new file mode 100644 index 000000000..fdccc1949 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/config.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" +) + +var ( + MaxVersion = semver.Version{ + Major: 3, + Minor: 3, + } +) diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/device.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/device.go new file mode 100644 index 000000000..a10ce97b0 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/device.go @@ -0,0 +1,25 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Device) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c, validatePath(string(d))) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/directory.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/directory.go new file mode 100644 index 000000000..f6f068455 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/directory.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Directory) Validate(c path.ContextPath) (r report.Report) { + r.Merge(d.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(d.Mode)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/disk.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/disk.go new file mode 100644 index 000000000..24c36547d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/disk.go @@ -0,0 +1,135 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (d Disk) Key() string { + return d.Device +} + +func (n Disk) Validate(c path.ContextPath) (r report.Report) { + if len(n.Device) == 0 { + r.AddOnError(c.Append("device"), errors.ErrDiskDeviceRequired) + return + } + r.AddOnError(c.Append("device"), validatePath(n.Device)) + + if collides, p := n.partitionNumbersCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionNumbersCollide) + } + if overlaps, p := n.partitionsOverlap(); overlaps { + r.AddOnError(c.Append("partitions", p), errors.ErrPartitionsOverlap) + } + if n.partitionsMixZeroesAndNonexistence() { + r.AddOnError(c.Append("partitions"), errors.ErrZeroesWithShouldNotExist) + } + if collides, p := n.partitionLabelsCollide(); collides { + r.AddOnError(c.Append("partitions", p), errors.ErrDuplicateLabels) + } + return +} + +// partitionNumbersCollide returns true if partition numbers in n.Partitions are not unique. It also returns the +// index of the colliding partition +func (n Disk) partitionNumbersCollide() (bool, int) { + m := map[int][]int{} // from partition number to index into array + for i, p := range n.Partitions { + if p.Number != 0 { + // a number of 0 means next available number, multiple devices can specify this + m[p.Number] = append(m[p.Number], i) + } + } + for _, n := range m { + if len(n) > 1 { + // TODO(vc): return information describing the collision for logging + return true, n[1] + } + } + return false, 0 +} + +func (d Disk) partitionLabelsCollide() (bool, int) { + m := map[string]struct{}{} + for i, p := range d.Partitions { + if p.Label != nil { + // a number of 0 means next available number, multiple devices can specify this + if _, exists := m[*p.Label]; exists { + return true, i + } + m[*p.Label] = struct{}{} + } + } + return false, 0 +} + +// end returns the last sector of a partition. Only used by partitionsOverlap. Requires non-nil Start and Size. +func (p Partition) end() int { + if *p.SizeMiB == 0 { + // a size of 0 means "fill available", just return the start as the end for those. + return *p.StartMiB + } + return *p.StartMiB + *p.SizeMiB - 1 +} + +// partitionsOverlap returns true if any explicitly dimensioned partitions overlap. It also returns the index of +// the overlapping partition +func (n Disk) partitionsOverlap() (bool, int) { + for _, p := range n.Partitions { + // Starts of 0 are placed by sgdisk into the "largest available block" at that time. + // We aren't going to check those for overlap since we don't have the disk geometry. + if p.StartMiB == nil || p.SizeMiB == nil || *p.StartMiB == 0 { + continue + } + + for i, o := range n.Partitions { + if o.StartMiB == nil || o.SizeMiB == nil || p == o || *o.StartMiB == 0 { + continue + } + + // is p.StartMiB within o? + if *p.StartMiB >= *o.StartMiB && *p.StartMiB <= o.end() { + return true, i + } + + // is p.end() within o? + if p.end() >= *o.StartMiB && p.end() <= o.end() { + return true, i + } + + // do p.StartMiB and p.end() straddle o? + if *p.StartMiB < *o.StartMiB && p.end() > o.end() { + return true, i + } + } + } + return false, 0 +} + +func (n Disk) partitionsMixZeroesAndNonexistence() bool { + hasZero := false + hasShouldNotExist := false + for _, p := range n.Partitions { + hasShouldNotExist = hasShouldNotExist || util.IsFalse(p.ShouldExist) + hasZero = hasZero || (p.Number == 0) + } + return hasZero && hasShouldNotExist +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/file.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/file.go new file mode 100644 index 000000000..dafdf5afb --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/file.go @@ -0,0 +1,43 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f File) Validate(c path.ContextPath) (r report.Report) { + r.Merge(f.Node.Validate(c)) + r.AddOnError(c.Append("mode"), validateMode(f.Mode)) + r.AddOnError(c.Append("overwrite"), f.validateOverwrite()) + return +} + +func (f File) validateOverwrite() error { + if util.IsTrue(f.Overwrite) && f.Contents.Source == nil { + return errors.ErrOverwriteAndNilSource + } + return nil +} + +func (f FileEmbedded1) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Append": {}, + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/filesystem.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/filesystem.go new file mode 100644 index 000000000..d18da9e34 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/filesystem.go @@ -0,0 +1,106 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (f Filesystem) Key() string { + return f.Device +} + +func (f Filesystem) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + "MountOptions": {}, + } +} + +func (f Filesystem) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), f.validatePath()) + r.AddOnError(c.Append("device"), validatePath(f.Device)) + r.AddOnError(c.Append("format"), f.validateFormat()) + r.AddOnError(c.Append("label"), f.validateLabel()) + return +} + +func (f Filesystem) validatePath() error { + return validatePathNilOK(f.Path) +} + +func (f Filesystem) validateFormat() error { + if util.NilOrEmpty(f.Format) { + if util.NotEmpty(f.Path) || + util.NotEmpty(f.Label) || + util.NotEmpty(f.UUID) || + util.IsTrue(f.WipeFilesystem) || + len(f.MountOptions) != 0 || + len(f.Options) != 0 { + return errors.ErrFormatNilWithOthers + } + } else { + switch *f.Format { + case "ext4", "btrfs", "xfs", "swap", "vfat", "none": + default: + return errors.ErrFilesystemInvalidFormat + } + } + return nil +} + +func (f Filesystem) validateLabel() error { + if util.NilOrEmpty(f.Label) { + return nil + } + if util.NilOrEmpty(f.Format) { + return errors.ErrLabelNeedsFormat + } + + switch *f.Format { + case "ext4": + if len(*f.Label) > 16 { + // source: man mkfs.ext4 + return errors.ErrExt4LabelTooLong + } + case "btrfs": + if len(*f.Label) > 256 { + // source: man mkfs.btrfs + return errors.ErrBtrfsLabelTooLong + } + case "xfs": + if len(*f.Label) > 12 { + // source: man mkfs.xfs + return errors.ErrXfsLabelTooLong + } + case "swap": + // mkswap's man page does not state a limit on label size, but through + // experimentation it appears that mkswap will truncate long labels to + // 15 characters, so let's enforce that. + if len(*f.Label) > 15 { + return errors.ErrSwapLabelTooLong + } + case "vfat": + if len(*f.Label) > 11 { + // source: man mkfs.fat + return errors.ErrVfatLabelTooLong + } + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/headers.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/headers.go new file mode 100644 index 000000000..8bac0d636 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/headers.go @@ -0,0 +1,65 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/http" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/flatcar-linux/ignition/v2/config/shared/errors" +) + +// Parse generates standard net/http headers from the data in HTTPHeaders +func (hs HTTPHeaders) Parse() (http.Header, error) { + headers := http.Header{} + for _, header := range hs { + if header.Name == "" { + return nil, errors.ErrEmptyHTTPHeaderName + } + if header.Value == nil || string(*header.Value) == "" { + return nil, errors.ErrInvalidHTTPHeader + } + headers.Add(header.Name, string(*header.Value)) + } + return headers, nil +} + +func (h HTTPHeader) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), h.validateName()) + r.AddOnError(c.Append("value"), h.validateValue()) + return +} + +func (h HTTPHeader) validateName() error { + if h.Name == "" { + return errors.ErrEmptyHTTPHeaderName + } + return nil +} + +func (h HTTPHeader) validateValue() error { + if h.Value == nil { + return nil + } + if string(*h.Value) == "" { + return errors.ErrInvalidHTTPHeader + } + return nil +} + +func (h HTTPHeader) Key() string { + return h.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/ignition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/ignition.go new file mode 100644 index 000000000..746218a62 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/ignition.go @@ -0,0 +1,49 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/go-semver/semver" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (v Ignition) Semver() (*semver.Version, error) { + return semver.NewVersion(v.Version) +} + +func (ic IgnitionConfig) Validate(c path.ContextPath) (r report.Report) { + for i, res := range ic.Merge { + r.AddOnError(c.Append("merge", i), res.validateRequiredSource()) + } + return +} + +func (v Ignition) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("version") + tv, err := v.Semver() + if err != nil { + r.AddOnError(c, errors.ErrInvalidVersion) + return + } + + if MaxVersion != *tv { + r.AddOnError(c, errors.ErrUnknownVersion) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/kargs.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/kargs.go new file mode 100644 index 000000000..42c29408e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/kargs.go @@ -0,0 +1,22 @@ +// Copyright 2021 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +func (k KernelArguments) MergedKeys() map[string]string { + return map[string]string{ + "ShouldExist": "KernelArgument", + "ShouldNotExist": "KernelArgument", + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/luks.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/luks.go new file mode 100644 index 000000000..0d505e34f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/luks.go @@ -0,0 +1,71 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (l Luks) Key() string { + return l.Name +} + +func (l Luks) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + } +} + +func (l Luks) Validate(c path.ContextPath) (r report.Report) { + if strings.Contains(l.Name, "/") { + r.AddOnError(c.Append("name"), errors.ErrLuksNameContainsSlash) + } + r.AddOnError(c.Append("label"), l.validateLabel()) + if util.NilOrEmpty(l.Device) { + r.AddOnError(c.Append("device"), errors.ErrDiskDeviceRequired) + } else { + r.AddOnError(c.Append("device"), validatePath(*l.Device)) + } + + if util.NotEmpty(l.Clevis.Custom.Pin) && (len(l.Clevis.Tang) > 0 || util.IsTrue(l.Clevis.Tpm2) || (l.Clevis.Threshold != nil && *l.Clevis.Threshold != 0)) { + r.AddOnError(c.Append("clevis"), errors.ErrClevisCustomWithOthers) + } + + // fail if a key file is provided and is not valid + if err := validateURLNilOK(l.KeyFile.Source); err != nil { + r.AddOnError(c.Append("keys"), errors.ErrInvalidLuksKeyFile) + } + return +} + +func (l Luks) validateLabel() error { + if util.NilOrEmpty(l.Label) { + return nil + } + + if len(*l.Label) > 47 { + // LUKS2_LABEL_L has a maximum length of 48 (including the null terminator) + // https://gitlab.com/cryptsetup/cryptsetup/-/blob/1633f030e89ad2f11ae649ba9600997a41abd3fc/lib/luks2/luks2.h#L86 + return errors.ErrLuksLabelTooLong + } + + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/mode.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/mode.go new file mode 100644 index 000000000..5e57bb651 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/mode.go @@ -0,0 +1,26 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" +) + +func validateMode(m *int) error { + if m != nil && (*m < 0 || *m > 07777) { + return errors.ErrFileIllegalMode + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/node.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/node.go new file mode 100644 index 000000000..e23730f23 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/node.go @@ -0,0 +1,59 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (n Node) Key() string { + return n.Path +} + +func (n Node) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("path"), validatePath(n.Path)) + return +} + +func (n Node) Depth() int { + count := 0 + for p := path.Clean(string(n.Path)); p != "/"; count++ { + p = path.Dir(p) + } + return count +} + +func validateIDorName(id *int, name *string) error { + if id != nil && util.NotEmpty(name) { + return errors.ErrBothIDAndNameSet + } + return nil +} + +func (nu NodeUser) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(nu.ID, nu.Name)) + return +} + +func (ng NodeGroup) Validate(c vpath.ContextPath) (r report.Report) { + r.AddOnError(c, validateIDorName(ng.ID, ng.Name)) + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/partition.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/partition.go new file mode 100644 index 000000000..8363be285 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/partition.go @@ -0,0 +1,91 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "regexp" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +const ( + guidRegexStr = "^(|[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12})$" +) + +var ( + guidRegex = regexp.MustCompile(guidRegexStr) +) + +func (p Partition) Key() string { + if p.Number != 0 { + return fmt.Sprintf("number:%d", p.Number) + } else if p.Label != nil { + return fmt.Sprintf("label:%s", *p.Label) + } else { + return "" + } +} + +func (p Partition) Validate(c path.ContextPath) (r report.Report) { + if util.IsFalse(p.ShouldExist) && + (p.Label != nil || util.NotEmpty(p.TypeGUID) || util.NotEmpty(p.GUID) || p.StartMiB != nil || p.SizeMiB != nil) { + r.AddOnError(c, errors.ErrShouldNotExistWithOthers) + } + if p.Number == 0 && p.Label == nil { + r.AddOnError(c, errors.ErrNeedLabelOrNumber) + } + + r.AddOnError(c.Append("label"), p.validateLabel()) + r.AddOnError(c.Append("guid"), validateGUID(p.GUID)) + r.AddOnError(c.Append("typeGuid"), validateGUID(p.TypeGUID)) + return +} + +func (p Partition) validateLabel() error { + if p.Label == nil { + return nil + } + // http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries: + // 56 (0x38) 72 bytes Partition name (36 UTF-16LE code units) + + // XXX(vc): note GPT calls it a name, we're using label for consistency + // with udev naming /dev/disk/by-partlabel/*. + if len(*p.Label) > 36 { + return errors.ErrLabelTooLong + } + + // sgdisk uses colons for delimitting compound arguments and does not allow escaping them. + if strings.Contains(*p.Label, ":") { + return errors.ErrLabelContainsColon + } + return nil +} + +func validateGUID(guidPointer *string) error { + if guidPointer == nil { + return nil + } + guid := *guidPointer + if ok := guidRegex.MatchString(guid); !ok { + return errors.ErrDoesntMatchGUIDRegex + } + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/passwd.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/passwd.go new file mode 100644 index 000000000..4060a2a6f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/passwd.go @@ -0,0 +1,23 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +func (p PasswdUser) Key() string { + return p.Name +} + +func (g PasswdGroup) Key() string { + return g.Name +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/path.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/path.go new file mode 100644 index 000000000..d6d394a7f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/path.go @@ -0,0 +1,42 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validatePath(p string) error { + if p == "" { + return errors.ErrNoPath + } + if !path.IsAbs(p) { + return errors.ErrPathRelative + } + if path.Clean(p) != p { + return errors.ErrDirtyPath + } + return nil +} + +func validatePathNilOK(p *string) error { + if util.NilOrEmpty(p) { + return nil + } + return validatePath(*p) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/proxy.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/proxy.go new file mode 100644 index 000000000..088459d8f --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/proxy.go @@ -0,0 +1,49 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (p Proxy) Validate(c path.ContextPath) (r report.Report) { + validateProxyURL(p.HTTPProxy, c.Append("httpProxy"), &r, true) + validateProxyURL(p.HTTPSProxy, c.Append("httpsProxy"), &r, false) + return +} + +func validateProxyURL(s *string, p path.ContextPath, r *report.Report, httpOk bool) { + if s == nil { + return + } + u, err := url.Parse(*s) + if err != nil { + r.AddOnError(p, errors.ErrInvalidUrl) + return + } + + if u.Scheme != "https" && u.Scheme != "http" { + r.AddOnError(p, errors.ErrInvalidProxy) + return + } + if u.Scheme == "http" && !httpOk { + r.AddOnWarn(p, errors.ErrInsecureProxy) + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/raid.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/raid.go new file mode 100644 index 000000000..6bc733498 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/raid.go @@ -0,0 +1,62 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (r Raid) Key() string { + return r.Name +} + +func (r Raid) IgnoreDuplicates() map[string]struct{} { + return map[string]struct{}{ + "Options": {}, + } +} + +func (ra Raid) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("level"), ra.validateLevel()) + if len(ra.Devices) == 0 { + r.AddOnError(c.Append("devices"), errors.ErrRaidDevicesRequired) + } + return +} + +func (r Raid) validateLevel() error { + if util.NilOrEmpty(r.Level) { + return errors.ErrRaidLevelRequired + } + switch *r.Level { + case "linear", "raid0", "0", "stripe": + if r.Spares != nil && *r.Spares != 0 { + return errors.ErrSparesUnsupportedForLevel + } + case "raid1", "1", "mirror": + case "raid4", "4": + case "raid5", "5": + case "raid6", "6": + case "raid10", "10": + default: + return errors.ErrUnrecognizedRaidLevel + } + + return nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/resource.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/resource.go new file mode 100644 index 000000000..8c03b7f5e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/resource.go @@ -0,0 +1,91 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (res Resource) Key() string { + if res.Source == nil { + return "" + } + return *res.Source +} + +func (res Resource) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("compression"), res.validateCompression()) + r.AddOnError(c.Append("verification", "hash"), res.validateVerification()) + r.AddOnError(c.Append("source"), validateURLNilOK(res.Source)) + r.AddOnError(c.Append("httpHeaders"), res.validateSchemeForHTTPHeaders()) + return +} + +func (res Resource) validateCompression() error { + if res.Compression != nil { + switch *res.Compression { + case "", "gzip": + default: + return errors.ErrCompressionInvalid + } + } + return nil +} + +func (res Resource) validateVerification() error { + if res.Verification.Hash != nil && res.Source == nil { + return errors.ErrVerificationAndNilSource + } + return nil +} + +func (res Resource) validateSchemeForHTTPHeaders() error { + if len(res.HTTPHeaders) < 1 { + return nil + } + + if util.NilOrEmpty(res.Source) { + return errors.ErrInvalidUrl + } + + u, err := url.Parse(*res.Source) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https": + return nil + default: + return errors.ErrUnsupportedSchemeForHTTPHeaders + } +} + +// Ensure that the Source is specified and valid. This is not called by +// Resource.Validate() because some structs that embed Resource don't +// require Source to be specified. Containing structs that require Source +// should call this function from their Validate(). +func (res Resource) validateRequiredSource() error { + if util.NilOrEmpty(res.Source) { + return errors.ErrSourceRequired + } + return validateURL(*res.Source) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/schema.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/schema.go new file mode 100644 index 000000000..8722944f1 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/schema.go @@ -0,0 +1,254 @@ +package types + +// generated by "schematyper --package=types config/v3_3/schema/ignition.json -o config/v3_3/types/schema.go --root-type=Config" -- DO NOT EDIT + +type Clevis struct { + Custom ClevisCustom `json:"custom,omitempty"` + Tang []Tang `json:"tang,omitempty"` + Threshold *int `json:"threshold,omitempty"` + Tpm2 *bool `json:"tpm2,omitempty"` +} + +type ClevisCustom struct { + Config *string `json:"config,omitempty"` + NeedsNetwork *bool `json:"needsNetwork,omitempty"` + Pin *string `json:"pin,omitempty"` +} + +type Config struct { + Ignition Ignition `json:"ignition"` + KernelArguments KernelArguments `json:"kernelArguments,omitempty"` + Passwd Passwd `json:"passwd,omitempty"` + Storage Storage `json:"storage,omitempty"` + Systemd Systemd `json:"systemd,omitempty"` +} + +type Device string + +type Directory struct { + Node + DirectoryEmbedded1 +} + +type DirectoryEmbedded1 struct { + Mode *int `json:"mode,omitempty"` +} + +type Disk struct { + Device string `json:"device"` + Partitions []Partition `json:"partitions,omitempty"` + WipeTable *bool `json:"wipeTable,omitempty"` +} + +type Dropin struct { + Contents *string `json:"contents,omitempty"` + Name string `json:"name"` +} + +type File struct { + Node + FileEmbedded1 +} + +type FileEmbedded1 struct { + Append []Resource `json:"append,omitempty"` + Contents Resource `json:"contents,omitempty"` + Mode *int `json:"mode,omitempty"` +} + +type Filesystem struct { + Device string `json:"device"` + Format *string `json:"format,omitempty"` + Label *string `json:"label,omitempty"` + MountOptions []MountOption `json:"mountOptions,omitempty"` + Options []FilesystemOption `json:"options,omitempty"` + Path *string `json:"path,omitempty"` + UUID *string `json:"uuid,omitempty"` + WipeFilesystem *bool `json:"wipeFilesystem,omitempty"` +} + +type FilesystemOption string + +type Group string + +type HTTPHeader struct { + Name string `json:"name"` + Value *string `json:"value,omitempty"` +} + +type HTTPHeaders []HTTPHeader + +type Ignition struct { + Config IgnitionConfig `json:"config,omitempty"` + Proxy Proxy `json:"proxy,omitempty"` + Security Security `json:"security,omitempty"` + Timeouts Timeouts `json:"timeouts,omitempty"` + Version string `json:"version,omitempty"` +} + +type IgnitionConfig struct { + Merge []Resource `json:"merge,omitempty"` + Replace Resource `json:"replace,omitempty"` +} + +type KernelArgument string + +type KernelArguments struct { + ShouldExist []KernelArgument `json:"shouldExist,omitempty"` + ShouldNotExist []KernelArgument `json:"shouldNotExist,omitempty"` +} + +type Link struct { + Node + LinkEmbedded1 +} + +type LinkEmbedded1 struct { + Hard *bool `json:"hard,omitempty"` + Target *string `json:"target,omitempty"` +} + +type Luks struct { + Clevis Clevis `json:"clevis,omitempty"` + Device *string `json:"device,omitempty"` + KeyFile Resource `json:"keyFile,omitempty"` + Label *string `json:"label,omitempty"` + Name string `json:"name"` + Options []LuksOption `json:"options,omitempty"` + UUID *string `json:"uuid,omitempty"` + WipeVolume *bool `json:"wipeVolume,omitempty"` +} + +type LuksOption string + +type MountOption string + +type NoProxyItem string + +type Node struct { + Group NodeGroup `json:"group,omitempty"` + Overwrite *bool `json:"overwrite,omitempty"` + Path string `json:"path"` + User NodeUser `json:"user,omitempty"` +} + +type NodeGroup struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type NodeUser struct { + ID *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type Partition struct { + GUID *string `json:"guid,omitempty"` + Label *string `json:"label,omitempty"` + Number int `json:"number,omitempty"` + Resize *bool `json:"resize,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + SizeMiB *int `json:"sizeMiB,omitempty"` + StartMiB *int `json:"startMiB,omitempty"` + TypeGUID *string `json:"typeGuid,omitempty"` + WipePartitionEntry *bool `json:"wipePartitionEntry,omitempty"` +} + +type Passwd struct { + Groups []PasswdGroup `json:"groups,omitempty"` + Users []PasswdUser `json:"users,omitempty"` +} + +type PasswdGroup struct { + Gid *int `json:"gid,omitempty"` + Name string `json:"name"` + PasswordHash *string `json:"passwordHash,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + System *bool `json:"system,omitempty"` +} + +type PasswdUser struct { + Gecos *string `json:"gecos,omitempty"` + Groups []Group `json:"groups,omitempty"` + HomeDir *string `json:"homeDir,omitempty"` + Name string `json:"name"` + NoCreateHome *bool `json:"noCreateHome,omitempty"` + NoLogInit *bool `json:"noLogInit,omitempty"` + NoUserGroup *bool `json:"noUserGroup,omitempty"` + PasswordHash *string `json:"passwordHash,omitempty"` + PrimaryGroup *string `json:"primaryGroup,omitempty"` + SSHAuthorizedKeys []SSHAuthorizedKey `json:"sshAuthorizedKeys,omitempty"` + Shell *string `json:"shell,omitempty"` + ShouldExist *bool `json:"shouldExist,omitempty"` + System *bool `json:"system,omitempty"` + UID *int `json:"uid,omitempty"` +} + +type Proxy struct { + HTTPProxy *string `json:"httpProxy,omitempty"` + HTTPSProxy *string `json:"httpsProxy,omitempty"` + NoProxy []NoProxyItem `json:"noProxy,omitempty"` +} + +type Raid struct { + Devices []Device `json:"devices,omitempty"` + Level *string `json:"level,omitempty"` + Name string `json:"name"` + Options []RaidOption `json:"options,omitempty"` + Spares *int `json:"spares,omitempty"` +} + +type RaidOption string + +type Resource struct { + Compression *string `json:"compression,omitempty"` + HTTPHeaders HTTPHeaders `json:"httpHeaders,omitempty"` + Source *string `json:"source,omitempty"` + Verification Verification `json:"verification,omitempty"` +} + +type SSHAuthorizedKey string + +type Security struct { + TLS TLS `json:"tls,omitempty"` +} + +type Storage struct { + Directories []Directory `json:"directories,omitempty"` + Disks []Disk `json:"disks,omitempty"` + Files []File `json:"files,omitempty"` + Filesystems []Filesystem `json:"filesystems,omitempty"` + Links []Link `json:"links,omitempty"` + Luks []Luks `json:"luks,omitempty"` + Raid []Raid `json:"raid,omitempty"` +} + +type Systemd struct { + Units []Unit `json:"units,omitempty"` +} + +type TLS struct { + CertificateAuthorities []Resource `json:"certificateAuthorities,omitempty"` +} + +type Tang struct { + Thumbprint *string `json:"thumbprint,omitempty"` + URL string `json:"url,omitempty"` +} + +type Timeouts struct { + HTTPResponseHeaders *int `json:"httpResponseHeaders,omitempty"` + HTTPTotal *int `json:"httpTotal,omitempty"` +} + +type Unit struct { + Contents *string `json:"contents,omitempty"` + Dropins []Dropin `json:"dropins,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Mask *bool `json:"mask,omitempty"` + Name string `json:"name"` +} + +type Verification struct { + Hash *string `json:"hash,omitempty"` +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/storage.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/storage.go new file mode 100644 index 000000000..7c01d6d10 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/storage.go @@ -0,0 +1,75 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + vpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (s Storage) MergedKeys() map[string]string { + return map[string]string{ + "Directories": "Node", + "Files": "Node", + "Links": "Node", + } +} + +func (s Storage) Validate(c vpath.ContextPath) (r report.Report) { + for i, d := range s.Directories { + for _, l := range s.Links { + if strings.HasPrefix(d.Path, l.Path+"/") { + r.AddOnError(c.Append("directories", i), errors.ErrDirectoryUsedSymlink) + } + } + } + for i, f := range s.Files { + for _, l := range s.Links { + if strings.HasPrefix(f.Path, l.Path+"/") { + r.AddOnError(c.Append("files", i), errors.ErrFileUsedSymlink) + } + } + } + for i, l1 := range s.Links { + for _, l2 := range s.Links { + if strings.HasPrefix(l1.Path, l2.Path+"/") { + r.AddOnError(c.Append("links", i), errors.ErrLinkUsedSymlink) + } + } + if util.NilOrEmpty(l1.Target) { + r.AddOnError(c.Append("links", i, "target"), errors.ErrLinkTargetRequired) + continue + } + if !util.IsTrue(l1.Hard) { + continue + } + target := path.Clean(*l1.Target) + if !path.IsAbs(target) { + target = path.Join(l1.Path, *l1.Target) + } + for _, d := range s.Directories { + if target == d.Path { + r.AddOnError(c.Append("links", i), errors.ErrHardLinkToDirectory) + } + } + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tang.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tang.go new file mode 100644 index 000000000..d6df1d986 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tang.go @@ -0,0 +1,51 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (t Tang) Key() string { + return t.URL +} + +func (t Tang) Validate(c path.ContextPath) (r report.Report) { + r.AddOnError(c.Append("url"), validateTangURL(t.URL)) + if util.NilOrEmpty(t.Thumbprint) { + r.AddOnError(c.Append("thumbprint"), errors.ErrTangThumbprintRequired) + } + return +} + +func validateTangURL(s string) error { + u, err := url.Parse(s) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https": + return nil + default: + return errors.ErrInvalidScheme + } +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tls.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tls.go new file mode 100644 index 000000000..8890e397e --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/tls.go @@ -0,0 +1,27 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (tls TLS) Validate(c path.ContextPath) (r report.Report) { + for i, ca := range tls.CertificateAuthorities { + r.AddOnError(c.Append("certificateAuthorities", i), ca.validateRequiredSource()) + } + return +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/unit.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/unit.go new file mode 100644 index 000000000..933163a75 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/unit.go @@ -0,0 +1,82 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "fmt" + "path" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/shared/validations" + "github.com/flatcar-linux/ignition/v2/config/util" + + "github.com/coreos/go-systemd/v22/unit" + cpath "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (u Unit) Key() string { + return u.Name +} + +func (d Dropin) Key() string { + return d.Name +} + +func (u Unit) Validate(c cpath.ContextPath) (r report.Report) { + r.AddOnError(c.Append("name"), validateName(u.Name)) + c = c.Append("contents") + opts, err := validateUnitContent(u.Contents) + r.AddOnError(c, err) + + r.AddOnWarn(c, validations.ValidateInstallSection(u.Name, util.IsTrue(u.Enabled), util.NilOrEmpty(u.Contents), opts)) + + return +} + +func validateName(name string) error { + switch path.Ext(name) { + case ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".snapshot", ".slice", ".scope": + default: + return errors.ErrInvalidSystemdExt + } + return nil +} + +func (d Dropin) Validate(c cpath.ContextPath) (r report.Report) { + _, err := validateUnitContent(d.Contents) + r.AddOnError(c.Append("contents"), err) + + switch path.Ext(d.Name) { + case ".conf": + default: + r.AddOnError(c.Append("name"), errors.ErrInvalidSystemdDropinExt) + } + + return +} + +func validateUnitContent(content *string) ([]*unit.UnitOption, error) { + if content == nil { + return []*unit.UnitOption{}, nil + } + c := strings.NewReader(*content) + opts, err := unit.Deserialize(c) + if err != nil { + return nil, fmt.Errorf("invalid unit content: %s", err) + } + return opts, nil +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/url.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/url.go new file mode 100644 index 000000000..8f3da4d9d --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/url.go @@ -0,0 +1,57 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "net/url" + + "github.com/vincent-petithory/dataurl" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + "github.com/flatcar-linux/ignition/v2/config/util" +) + +func validateURL(s string) error { + u, err := url.Parse(s) + if err != nil { + return errors.ErrInvalidUrl + } + + switch u.Scheme { + case "http", "https", "tftp", "gs", "oem": + return nil + case "s3": + if v, ok := u.Query()["versionId"]; ok { + if len(v) == 0 || v[0] == "" { + return errors.ErrInvalidS3ObjectVersionId + } + } + return nil + case "data": + if _, err := dataurl.DecodeString(s); err != nil { + return err + } + return nil + default: + return errors.ErrInvalidScheme + } +} + +func validateURLNilOK(s *string) error { + if util.NilOrEmpty(s) { + return nil + } + return validateURL(*s) +} diff --git a/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/verification.go b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/verification.go new file mode 100644 index 000000000..0aaba72a1 --- /dev/null +++ b/vendor/github.com/flatcar-linux/ignition/v2/config/v3_3/types/verification.go @@ -0,0 +1,71 @@ +// Copyright 2020 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "crypto" + "encoding/hex" + "strings" + + "github.com/flatcar-linux/ignition/v2/config/shared/errors" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +// HashParts will return the sum and function (in that order) of the hash stored +// in this Verification, or an error if there is an issue during parsing. +func (v Verification) HashParts() (string, string, error) { + if v.Hash == nil { + // The hash can be nil + return "", "", nil + } + parts := strings.SplitN(*v.Hash, "-", 2) + if len(parts) != 2 { + return "", "", errors.ErrHashMalformed + } + + return parts[0], parts[1], nil +} + +func (v Verification) Validate(c path.ContextPath) (r report.Report) { + c = c.Append("hash") + if v.Hash == nil { + // The hash can be nil + return + } + + function, sum, err := v.HashParts() + if err != nil { + r.AddOnError(c, err) + return + } + var hash crypto.Hash + switch function { + case "sha512": + hash = crypto.SHA512 + case "sha256": + hash = crypto.SHA256 + default: + r.AddOnError(c, errors.ErrHashUnrecognized) + return + } + + if len(sum) != hex.EncodedLen(hash.Size()) { + r.AddOnError(c, errors.ErrHashWrongSize) + } + + return +} diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index 24a5036e9..7c058de37 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -160,7 +160,7 @@ type FlagSet struct { args []string // arguments after flags argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no -- errorHandling ErrorHandling - output io.Writer // nil means stderr; use out() accessor + output io.Writer // nil means stderr; use Output() accessor interspersed bool // allow interspersed option/non-option args normalizeNameFunc func(f *FlagSet, name string) NormalizedName @@ -255,13 +255,20 @@ func (f *FlagSet) normalizeFlagName(name string) NormalizedName { return n(f, name) } -func (f *FlagSet) out() io.Writer { +// Output returns the destination for usage and error messages. os.Stderr is returned if +// output was not set or was set to nil. +func (f *FlagSet) Output() io.Writer { if f.output == nil { return os.Stderr } return f.output } +// Name returns the name of the flag set. +func (f *FlagSet) Name() string { + return f.name +} + // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (f *FlagSet) SetOutput(output io.Writer) { @@ -358,7 +365,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag { } if len(name) > 1 { msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } c := name[0] @@ -482,7 +489,7 @@ func (f *FlagSet) Set(name, value string) error { } if flag.Deprecated != "" { - fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) } return nil } @@ -523,7 +530,7 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { usages := f.FlagUsages() - fmt.Fprint(f.out(), usages) + fmt.Fprint(f.Output(), usages) } // defaultIsZeroValue returns true if the default value for this flag represents @@ -758,7 +765,7 @@ func PrintDefaults() { // defaultUsage is the default function to print a usage message. func defaultUsage(f *FlagSet) { - fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) + fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) f.PrintDefaults() } @@ -844,7 +851,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { _, alreadyThere := f.formal[normalizedFlagName] if alreadyThere { msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) - fmt.Fprintln(f.out(), msg) + fmt.Fprintln(f.Output(), msg) panic(msg) // Happens only if flags are declared with identical names } if f.formal == nil { @@ -860,7 +867,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { } if len(flag.Shorthand) > 1 { msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } if f.shorthands == nil { @@ -870,7 +877,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { used, alreadyThere := f.shorthands[c] if alreadyThere { msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) - fmt.Fprintf(f.out(), msg) + fmt.Fprintf(f.Output(), msg) panic(msg) } f.shorthands[c] = flag @@ -909,7 +916,7 @@ func VarP(value Value, name, shorthand, usage string) { func (f *FlagSet) failf(format string, a ...interface{}) error { err := fmt.Errorf(format, a...) if f.errorHandling != ContinueOnError { - fmt.Fprintln(f.out(), err) + fmt.Fprintln(f.Output(), err) f.usage() } return err @@ -1060,7 +1067,7 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse } if flag.ShorthandDeprecated != "" { - fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) + fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) } err = fn(flag, value) diff --git a/vendor/github.com/spf13/pflag/ip.go b/vendor/github.com/spf13/pflag/ip.go index 3d414ba69..06b8bcb57 100644 --- a/vendor/github.com/spf13/pflag/ip.go +++ b/vendor/github.com/spf13/pflag/ip.go @@ -16,6 +16,9 @@ func newIPValue(val net.IP, p *net.IP) *ipValue { func (i *ipValue) String() string { return net.IP(*i).String() } func (i *ipValue) Set(s string) error { + if s == "" { + return nil + } ip := net.ParseIP(strings.TrimSpace(s)) if ip == nil { return fmt.Errorf("failed to parse IP: %q", s) diff --git a/vendor/github.com/spf13/pflag/ipnet_slice.go b/vendor/github.com/spf13/pflag/ipnet_slice.go new file mode 100644 index 000000000..6b541aa87 --- /dev/null +++ b/vendor/github.com/spf13/pflag/ipnet_slice.go @@ -0,0 +1,147 @@ +package pflag + +import ( + "fmt" + "io" + "net" + "strings" +) + +// -- ipNetSlice Value +type ipNetSliceValue struct { + value *[]net.IPNet + changed bool +} + +func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { + ipnsv := new(ipNetSliceValue) + ipnsv.value = p + *ipnsv.value = val + return ipnsv +} + +// Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag. +// If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended. +func (s *ipNetSliceValue) Set(val string) error { + + // remove all quote characters + rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") + + // read flag arguments with CSV parser + ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val)) + if err != nil && err != io.EOF { + return err + } + + // parse ip values into slice + out := make([]net.IPNet, 0, len(ipNetStrSlice)) + for _, ipNetStr := range ipNetStrSlice { + _, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr)) + if err != nil { + return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr) + } + out = append(out, *n) + } + + if !s.changed { + *s.value = out + } else { + *s.value = append(*s.value, out...) + } + + s.changed = true + + return nil +} + +// Type returns a string that uniquely represents this flag's type. +func (s *ipNetSliceValue) Type() string { + return "ipNetSlice" +} + +// String defines a "native" format for this net.IPNet slice flag value. +func (s *ipNetSliceValue) String() string { + + ipNetStrSlice := make([]string, len(*s.value)) + for i, n := range *s.value { + ipNetStrSlice[i] = n.String() + } + + out, _ := writeAsCSV(ipNetStrSlice) + return "[" + out + "]" +} + +func ipNetSliceConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // Emtpy string would cause a slice with one (empty) entry + if len(val) == 0 { + return []net.IPNet{}, nil + } + ss := strings.Split(val, ",") + out := make([]net.IPNet, len(ss)) + for i, sval := range ss { + _, n, err := net.ParseCIDR(strings.TrimSpace(sval)) + if err != nil { + return nil, fmt.Errorf("invalid string being converted to CIDR: %s", sval) + } + out[i] = *n + } + return out, nil +} + +// GetIPNetSlice returns the []net.IPNet value of a flag with the given name +func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error) { + val, err := f.getFlagType(name, "ipNetSlice", ipNetSliceConv) + if err != nil { + return []net.IPNet{}, err + } + return val.([]net.IPNet), nil +} + +// IPNetSliceVar defines a ipNetSlice flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func (f *FlagSet) IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { + f.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { + f.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSliceVar defines a []net.IPNet flag with specified name, default value, and usage string. +// The argument p points to a []net.IPNet variable in which to store the value of the flag. +func IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { + CommandLine.VarP(newIPNetSliceValue(value, p), name, "", usage) +} + +// IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { + CommandLine.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IPNet variable that stores the value of that flag. +func (f *FlagSet) IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { + p := []net.IPNet{} + f.IPNetSliceVarP(&p, name, "", value, usage) + return &p +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { + p := []net.IPNet{} + f.IPNetSliceVarP(&p, name, shorthand, value, usage) + return &p +} + +// IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. +// The return value is the address of a []net.IP variable that stores the value of the flag. +func IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { + return CommandLine.IPNetSliceP(name, "", value, usage) +} + +// IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. +func IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { + return CommandLine.IPNetSliceP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go index 4894af818..d1ff0a96b 100644 --- a/vendor/github.com/spf13/pflag/string_array.go +++ b/vendor/github.com/spf13/pflag/string_array.go @@ -31,11 +31,7 @@ func (s *stringArrayValue) Append(val string) error { func (s *stringArrayValue) Replace(val []string) error { out := make([]string, len(val)) for i, d := range val { - var err error out[i] = d - if err != nil { - return err - } } *s.value = out return nil diff --git a/vendor/modules.txt b/vendor/modules.txt index e14e05a0b..a466c8c22 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -184,7 +184,7 @@ github.com/flatcar-linux/container-linux-config-transpiler/config/templating github.com/flatcar-linux/container-linux-config-transpiler/config/types github.com/flatcar-linux/container-linux-config-transpiler/config/types/util github.com/flatcar-linux/container-linux-config-transpiler/internal/util -# github.com/flatcar-linux/ignition v0.36.1 +# github.com/flatcar-linux/ignition v0.36.2-0.20220221101037-de4e6cc9bbba ## explicit github.com/flatcar-linux/ignition/config/shared/errors github.com/flatcar-linux/ignition/config/shared/validations @@ -199,19 +199,29 @@ github.com/flatcar-linux/ignition/config/v2_2 github.com/flatcar-linux/ignition/config/v2_2/types github.com/flatcar-linux/ignition/config/v2_3 github.com/flatcar-linux/ignition/config/v2_3/types -github.com/flatcar-linux/ignition/config/v2_4_experimental/types +github.com/flatcar-linux/ignition/config/v2_4/types github.com/flatcar-linux/ignition/config/validate github.com/flatcar-linux/ignition/config/validate/astjson github.com/flatcar-linux/ignition/config/validate/astnode github.com/flatcar-linux/ignition/config/validate/report -# github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220107090316-32908ec8bade +# github.com/flatcar-linux/ignition/v2 v2.2.1-0.20220311122140-cb95c51122f5 ## explicit github.com/flatcar-linux/ignition/v2/config/merge github.com/flatcar-linux/ignition/v2/config/shared/errors github.com/flatcar-linux/ignition/v2/config/shared/validations +github.com/flatcar-linux/ignition/v2/config/translate github.com/flatcar-linux/ignition/v2/config/util github.com/flatcar-linux/ignition/v2/config/v3_0 github.com/flatcar-linux/ignition/v2/config/v3_0/types +github.com/flatcar-linux/ignition/v2/config/v3_1 +github.com/flatcar-linux/ignition/v2/config/v3_1/translate +github.com/flatcar-linux/ignition/v2/config/v3_1/types +github.com/flatcar-linux/ignition/v2/config/v3_2 +github.com/flatcar-linux/ignition/v2/config/v3_2/translate +github.com/flatcar-linux/ignition/v2/config/v3_2/types +github.com/flatcar-linux/ignition/v2/config/v3_3 +github.com/flatcar-linux/ignition/v2/config/v3_3/translate +github.com/flatcar-linux/ignition/v2/config/v3_3/types github.com/flatcar-linux/ignition/v2/config/validate # github.com/form3tech-oss/jwt-go v3.2.5+incompatible ## explicit @@ -320,7 +330,7 @@ github.com/prometheus/procfs/internal/util # github.com/spf13/cobra v1.1.3 ## explicit github.com/spf13/cobra -# github.com/spf13/pflag v1.0.5 +# github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace ## explicit github.com/spf13/pflag # github.com/stretchr/testify v1.7.0 From 29dc5e0eb3ffebb717ba60b7949da0d9c5ab2661 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 16:13:15 +0100 Subject: [PATCH 7/9] platform/conf: support ignition 3.1, 3.2 and 3.3 Signed-off-by: Mathieu Tortuyaux --- platform/conf/conf.go | 351 ++++++++++++++++++++++++++++++++++++- platform/conf/conf_test.go | 4 + 2 files changed, 353 insertions(+), 2 deletions(-) diff --git a/platform/conf/conf.go b/platform/conf/conf.go index 818b432aa..4423265e7 100644 --- a/platform/conf/conf.go +++ b/platform/conf/conf.go @@ -41,6 +41,12 @@ import ( ign3err "github.com/flatcar-linux/ignition/v2/config/shared/errors" v3 "github.com/flatcar-linux/ignition/v2/config/v3_0" v3types "github.com/flatcar-linux/ignition/v2/config/v3_0/types" + v31 "github.com/flatcar-linux/ignition/v2/config/v3_1" + v31types "github.com/flatcar-linux/ignition/v2/config/v3_1/types" + v32 "github.com/flatcar-linux/ignition/v2/config/v3_2" + v32types "github.com/flatcar-linux/ignition/v2/config/v3_2/types" + v33 "github.com/flatcar-linux/ignition/v2/config/v3_3" + v33types "github.com/flatcar-linux/ignition/v2/config/v3_3/types" ign3validate "github.com/flatcar-linux/ignition/v2/config/validate" "github.com/vincent-petithory/dataurl" "golang.org/x/crypto/ssh/agent" @@ -75,6 +81,9 @@ type Conf struct { ignitionV22 *v22types.Config ignitionV23 *v23types.Config ignitionV3 *v3types.Config + ignitionV31 *v31types.Config + ignitionV32 *v32types.Config + ignitionV33 *v33types.Config cloudconfig *cci.CloudConfig script string } @@ -226,6 +235,33 @@ func (u *UserData) Render(ctPlatform string) (*Conf, error) { return err } + ignc31, report31, err := v31.Parse([]byte(u.data)) + if err == nil { + c.ignitionV31 = &ignc31 + return nil + } else if err != ign3err.ErrUnknownVersion { + plog.Errorf("invalid userdata: %v", report31) + return err + } + + ignc32, report32, err := v32.Parse([]byte(u.data)) + if err == nil { + c.ignitionV32 = &ignc32 + return nil + } else if err != ign3err.ErrUnknownVersion { + plog.Errorf("invalid userdata: %v", report32) + return err + } + + ignc33, report33, err := v33.Parse([]byte(u.data)) + if err == nil { + c.ignitionV33 = &ignc33 + return nil + } else if err != ign3err.ErrUnknownVersion { + plog.Errorf("invalid userdata: %v", report33) + return err + } + // give up return err } @@ -295,6 +331,15 @@ func (c *Conf) String() string { } else if c.ignitionV3 != nil { buf, _ := json.Marshal(c.ignitionV3) return string(buf) + } else if c.ignitionV31 != nil { + buf, _ := json.Marshal(c.ignitionV31) + return string(buf) + } else if c.ignitionV32 != nil { + buf, _ := json.Marshal(c.ignitionV32) + return string(buf) + } else if c.ignitionV33 != nil { + buf, _ := json.Marshal(c.ignitionV33) + return string(buf) } else if c.cloudconfig != nil { return c.cloudconfig.String() } else if c.script != "" { @@ -310,6 +355,21 @@ func (c *Conf) MergeV3(newConfig v3types.Config) { c.ignitionV3 = &mergeConfig } +func (c *Conf) MergeV31(newConfig v31types.Config) { + mergeConfig := v31.Merge(*c.ignitionV31, newConfig) + c.ignitionV31 = &mergeConfig +} + +func (c *Conf) MergeV32(newConfig v32types.Config) { + mergeConfig := v32.Merge(*c.ignitionV32, newConfig) + c.ignitionV32 = &mergeConfig +} + +func (c *Conf) MergeV33(newConfig v33types.Config) { + mergeConfig := v33.Merge(*c.ignitionV33, newConfig) + c.ignitionV33 = &mergeConfig +} + func (c *Conf) ValidConfig() bool { if !c.IsIgnition() { return false @@ -337,6 +397,12 @@ func (c *Conf) getIgnitionValidateValue() reflect.Value { return reflect.ValueOf(c.ignitionV23) } else if c.ignitionV3 != nil { return reflect.ValueOf(c.ignitionV3) + } else if c.ignitionV31 != nil { + return reflect.ValueOf(c.ignitionV31) + } else if c.ignitionV32 != nil { + return reflect.ValueOf(c.ignitionV32) + } else if c.ignitionV33 != nil { + return reflect.ValueOf(c.ignitionV33) } return reflect.ValueOf(nil) } @@ -437,6 +503,80 @@ func (c *Conf) addFileV3(path, filesystem, contents string, mode int) { c.MergeV3(newConfig) } +func (c *Conf) addFileV31(path, filesystem, contents string, mode int) { + source := dataurl.EncodeBytes([]byte(contents)) + newConfig := v31types.Config{ + Ignition: v31types.Ignition{ + Version: "3.1.0", + }, + Storage: v31types.Storage{ + Files: []v31types.File{ + { + Node: v31types.Node{ + Path: path, + }, + FileEmbedded1: v31types.FileEmbedded1{ + Contents: v31types.Resource{ + Source: &source, + }, + Mode: &mode, + }, + }, + }, + }, + } + c.MergeV31(newConfig) +} + +func (c *Conf) addFileV32(path, filesystem, contents string, mode int) { + source := dataurl.EncodeBytes([]byte(contents)) + newConfig := v32types.Config{ + Ignition: v32types.Ignition{ + Version: "3.2.0", + }, + Storage: v32types.Storage{ + Files: []v32types.File{ + { + Node: v32types.Node{ + Path: path, + }, + FileEmbedded1: v32types.FileEmbedded1{ + Contents: v32types.Resource{ + Source: &source, + }, + Mode: &mode, + }, + }, + }, + }, + } + c.MergeV32(newConfig) +} + +func (c *Conf) addFileV33(path, filesystem, contents string, mode int) { + source := dataurl.EncodeBytes([]byte(contents)) + newConfig := v33types.Config{ + Ignition: v33types.Ignition{ + Version: "3.3.0", + }, + Storage: v33types.Storage{ + Files: []v33types.File{ + { + Node: v33types.Node{ + Path: path, + }, + FileEmbedded1: v33types.FileEmbedded1{ + Contents: v33types.Resource{ + Source: &source, + }, + Mode: &mode, + }, + }, + }, + }, + } + c.MergeV33(newConfig) +} func (c *Conf) addFileV1(path, filesystem, contents string, mode int) { file := v1types.File{ Path: v1types.Path(path), @@ -471,7 +611,13 @@ func (c *Conf) addFileCloudConfig(path, filesystem, contents string, mode int) { } func (c *Conf) AddFile(path, filesystem, contents string, mode int) { - if c.ignitionV3 != nil { + if c.ignitionV33 != nil { + c.addFileV33(path, filesystem, contents, mode) + } else if c.ignitionV32 != nil { + c.addFileV32(path, filesystem, contents, mode) + } else if c.ignitionV31 != nil { + c.addFileV31(path, filesystem, contents, mode) + } else if c.ignitionV3 != nil { c.addFileV3(path, filesystem, contents, mode) } else if c.ignitionV2 != nil { c.addFileV2(path, filesystem, contents, mode) @@ -548,6 +694,60 @@ func (c *Conf) addSystemdUnitV3(name, contents string, enable bool) { c.MergeV3(newConfig) } +func (c *Conf) addSystemdUnitV31(name, contents string, enable bool) { + newConfig := v31types.Config{ + Ignition: v31types.Ignition{ + Version: "3.1.0", + }, + Systemd: v31types.Systemd{ + Units: []v31types.Unit{ + { + Name: name, + Contents: &contents, + Enabled: &enable, + }, + }, + }, + } + c.MergeV31(newConfig) +} + +func (c *Conf) addSystemdUnitV32(name, contents string, enable bool) { + newConfig := v32types.Config{ + Ignition: v32types.Ignition{ + Version: "3.2.0", + }, + Systemd: v32types.Systemd{ + Units: []v32types.Unit{ + { + Name: name, + Contents: &contents, + Enabled: &enable, + }, + }, + }, + } + c.MergeV32(newConfig) +} + +func (c *Conf) addSystemdUnitV33(name, contents string, enable bool) { + newConfig := v33types.Config{ + Ignition: v33types.Ignition{ + Version: "3.3.0", + }, + Systemd: v33types.Systemd{ + Units: []v33types.Unit{ + { + Name: name, + Contents: &contents, + Enabled: &enable, + }, + }, + }, + } + c.MergeV33(newConfig) +} + func (c *Conf) addSystemdUnitCloudConfig(name, contents string, enable bool) { c.cloudconfig.CoreOS.Units = append(c.cloudconfig.CoreOS.Units, cci.Unit{ Name: name, @@ -569,6 +769,12 @@ func (c *Conf) AddSystemdUnit(name, contents string, enable bool) { c.addSystemdUnitV23(name, contents, enable) } else if c.ignitionV3 != nil { c.addSystemdUnitV3(name, contents, enable) + } else if c.ignitionV31 != nil { + c.addSystemdUnitV31(name, contents, enable) + } else if c.ignitionV32 != nil { + c.addSystemdUnitV32(name, contents, enable) + } else if c.ignitionV33 != nil { + c.addSystemdUnitV33(name, contents, enable) } else if c.cloudconfig != nil { c.addSystemdUnitCloudConfig(name, contents, enable) } @@ -706,6 +912,72 @@ func (c *Conf) addSystemdDropinV3(service, name, contents string) { c.MergeV3(newConfig) } +func (c *Conf) addSystemdDropinV31(service, name, contents string) { + newConfig := v31types.Config{ + Ignition: v31types.Ignition{ + Version: "3.1.0", + }, + Systemd: v31types.Systemd{ + Units: []v31types.Unit{ + { + Name: service, + Dropins: []v31types.Dropin{ + { + Name: name, + Contents: &contents, + }, + }, + }, + }, + }, + } + c.MergeV31(newConfig) +} + +func (c *Conf) addSystemdDropinV32(service, name, contents string) { + newConfig := v32types.Config{ + Ignition: v32types.Ignition{ + Version: "3.2.0", + }, + Systemd: v32types.Systemd{ + Units: []v32types.Unit{ + { + Name: service, + Dropins: []v32types.Dropin{ + { + Name: name, + Contents: &contents, + }, + }, + }, + }, + }, + } + c.MergeV32(newConfig) +} + +func (c *Conf) addSystemdDropinV33(service, name, contents string) { + newConfig := v33types.Config{ + Ignition: v33types.Ignition{ + Version: "3.3.0", + }, + Systemd: v33types.Systemd{ + Units: []v33types.Unit{ + { + Name: service, + Dropins: []v33types.Dropin{ + { + Name: name, + Contents: &contents, + }, + }, + }, + }, + }, + } + c.MergeV33(newConfig) +} + func (c *Conf) addSystemdDropinCloudConfig(service, name, contents string) { for i, unit := range c.cloudconfig.CoreOS.Units { if unit.Name == service { @@ -741,6 +1013,12 @@ func (c *Conf) AddSystemdUnitDropin(service, name, contents string) { c.addSystemdDropinV23(service, name, contents) } else if c.ignitionV3 != nil { c.addSystemdDropinV3(service, name, contents) + } else if c.ignitionV31 != nil { + c.addSystemdDropinV3(service, name, contents) + } else if c.ignitionV32 != nil { + c.addSystemdDropinV32(service, name, contents) + } else if c.ignitionV33 != nil { + c.addSystemdDropinV33(service, name, contents) } else if c.cloudconfig != nil { c.addSystemdDropinCloudConfig(service, name, contents) } @@ -851,6 +1129,69 @@ func (c *Conf) copyKeysIgnitionV3(keys []*agent.Key) { c.MergeV3(newConfig) } +func (c *Conf) copyKeysIgnitionV31(keys []*agent.Key) { + var keyObjs []v31types.SSHAuthorizedKey + for _, key := range keys { + keyObjs = append(keyObjs, v31types.SSHAuthorizedKey(key.String())) + } + newConfig := v31types.Config{ + Ignition: v31types.Ignition{ + Version: "3.1.0", + }, + Passwd: v31types.Passwd{ + Users: []v31types.PasswdUser{ + { + Name: "core", + SSHAuthorizedKeys: keyObjs, + }, + }, + }, + } + c.MergeV31(newConfig) +} + +func (c *Conf) copyKeysIgnitionV32(keys []*agent.Key) { + var keyObjs []v32types.SSHAuthorizedKey + for _, key := range keys { + keyObjs = append(keyObjs, v32types.SSHAuthorizedKey(key.String())) + } + newConfig := v32types.Config{ + Ignition: v32types.Ignition{ + Version: "3.2.0", + }, + Passwd: v32types.Passwd{ + Users: []v32types.PasswdUser{ + { + Name: "core", + SSHAuthorizedKeys: keyObjs, + }, + }, + }, + } + c.MergeV32(newConfig) +} + +func (c *Conf) copyKeysIgnitionV33(keys []*agent.Key) { + var keyObjs []v33types.SSHAuthorizedKey + for _, key := range keys { + keyObjs = append(keyObjs, v33types.SSHAuthorizedKey(key.String())) + } + newConfig := v33types.Config{ + Ignition: v33types.Ignition{ + Version: "3.3.0", + }, + Passwd: v33types.Passwd{ + Users: []v33types.PasswdUser{ + { + Name: "core", + SSHAuthorizedKeys: keyObjs, + }, + }, + }, + } + c.MergeV33(newConfig) +} + func (c *Conf) copyKeysCloudConfig(keys []*agent.Key) { c.cloudconfig.SSHAuthorizedKeys = append(c.cloudconfig.SSHAuthorizedKeys, keysToStrings(keys)...) } @@ -875,6 +1216,12 @@ func (c *Conf) CopyKeys(keys []*agent.Key) { c.copyKeysIgnitionV23(keys) } else if c.ignitionV3 != nil { c.copyKeysIgnitionV3(keys) + } else if c.ignitionV31 != nil { + c.copyKeysIgnitionV31(keys) + } else if c.ignitionV32 != nil { + c.copyKeysIgnitionV32(keys) + } else if c.ignitionV33 != nil { + c.copyKeysIgnitionV33(keys) } else if c.cloudconfig != nil { c.copyKeysCloudConfig(keys) } else if c.script != "" { @@ -893,7 +1240,7 @@ func keysToStrings(keys []*agent.Key) (keyStrs []string) { // Returns false in the case of empty configs as on most platforms, // this will default back to cloudconfig func (c *Conf) IsIgnition() bool { - return c.ignitionV1 != nil || c.ignitionV2 != nil || c.ignitionV21 != nil || c.ignitionV22 != nil || c.ignitionV23 != nil || c.ignitionV3 != nil + return c.ignitionV1 != nil || c.ignitionV2 != nil || c.ignitionV21 != nil || c.ignitionV22 != nil || c.ignitionV23 != nil || c.ignitionV3 != nil || c.ignitionV31 != nil || c.ignitionV32 != nil || c.ignitionV33 != nil } func (c *Conf) IsEmpty() bool { diff --git a/platform/conf/conf_test.go b/platform/conf/conf_test.go index 10e57287b..2a9037663 100644 --- a/platform/conf/conf_test.go +++ b/platform/conf/conf_test.go @@ -38,6 +38,10 @@ func TestConfCopyKey(t *testing.T) { Ignition(`{ "ignition": { "version": "2.2.0" } }`), Ignition(`{ "ignition": { "version": "2.1.0" } }`), Ignition(`{ "ignition": { "version": "2.0.0" } }`), + Ignition(`{ "ignition": { "version": "3.0.0" } }`), + Ignition(`{ "ignition": { "version": "3.1.0" } }`), + Ignition(`{ "ignition": { "version": "3.2.0" } }`), + Ignition(`{ "ignition": { "version": "3.3.0" } }`), Ignition(`{ "ignitionVersion": 1 }`), CloudConfig("#cloud-config"), } From 615778afd98e147eb1242b6e8db6e730f5741f09 Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Thu, 3 Mar 2022 16:15:56 +0100 Subject: [PATCH 8/9] test/ignition: add kargs test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathieu Tortuyaux Co-authored-by: Kai Lüke --- kola/tests/ignition/kernel.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 kola/tests/ignition/kernel.go diff --git a/kola/tests/ignition/kernel.go b/kola/tests/ignition/kernel.go new file mode 100644 index 000000000..66d287b3a --- /dev/null +++ b/kola/tests/ignition/kernel.go @@ -0,0 +1,33 @@ +// Copyright The Mantle Authors +// SPDX-License-Identifier: Apache-2.0 +package ignition + +import ( + "github.com/coreos/go-semver/semver" + "github.com/flatcar-linux/mantle/kola/cluster" + "github.com/flatcar-linux/mantle/kola/register" + "github.com/flatcar-linux/mantle/platform/conf" +) + +func init() { + register.Register(®ister.Test{ + Name: "cl.ignition.kargs", + Run: check, + ClusterSize: 1, + UserData: conf.Ignition(`{ + "ignition": { + "version": "3.3.0" + }, + "kernelArguments": { + "shouldExist": ["quiet"] + } + }`), + MinVersion: semver.Version{Major: 3185}, + }) +} + +func check(c cluster.TestCluster) { + m := c.Machines()[0] + + c.AssertCmdOutputContains(m, "cat /proc/cmdline", " quiet") // assuming space for word separation +} From 69b6d943497522357deb3237976eeacafd7efdbe Mon Sep 17 00:00:00 2001 From: Mathieu Tortuyaux Date: Mon, 7 Mar 2022 10:53:38 +0100 Subject: [PATCH 9/9] changelog: add entry Signed-off-by: Mathieu Tortuyaux --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfdcbf487..4a61a0cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Azure: support for running Kola within an existing vnet and with private addressing ([#295](https://github.com/flatcar-linux/mantle/pull/295)) - kola tests `cl.cgroupv1` and `kubeadm.*.*.cgroupv1.base` that test functionality with cgroupv1 ([#298](https://github.com/flatcar-linux/mantle/pull/298)) - Added private network support to qemu-unpriv platform ([#307](https://github.com/flatcar-linux/mantle/pull/307)) +- Ignition v3 support and tests ([#301](https://github.com/flatcar-linux/mantle/pull/301)) ### Changed - removed `packet` occurrences in favor of `equinixmetal` ([#277](https://github.com/flatcar-linux/mantle/pull/277))