diff --git a/go.mod b/go.mod index a1723ff..a8580ef 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,12 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/jaypipes/ghw v0.9.0 github.com/mudler/go-pluggable v0.0.0-20220716112424-189d463e3ff3 + github.com/onsi/ginkgo/v2 v2.5.0 + github.com/onsi/gomega v1.24.0 github.com/otiai10/copy v1.7.0 + github.com/pkg/errors v0.9.1 github.com/urfave/cli v1.22.9 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -17,16 +21,18 @@ require ( github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/jaypipes/pcidb v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/net v0.1.0 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/text v0.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 975385d..193c695 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -26,9 +28,12 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -57,10 +62,13 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -90,7 +98,8 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -103,15 +112,14 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4= -golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -119,6 +127,7 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -132,5 +141,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/pkg/partition_info/partition_info.go b/pkg/partition_info/partition_info.go new file mode 100644 index 0000000..212ddc8 --- /dev/null +++ b/pkg/partition_info/partition_info.go @@ -0,0 +1,59 @@ +package partition_info + +import ( + "io/ioutil" + "strings" + + "github.com/pkg/errors" + "gopkg.in/yaml.v3" +) + +// PartitionInfo maps a partition label to a partition UUID. +// It's used in order to be able to ask the kcrypt-challenger for the passphrase +// using the partition label, even when the label is not accessible (e.g. before +// decrypting the partition). The UUID can be used to lookup the partition label +// and make the request. +type PartitionInfo map[string]string + +// UpdatePartitionLabelMapping takes partition information as a string argument +// the the form: `label:name:uuid` (that's what the `kcrypt encrypt` command returns +// on success. This function stores it in the PartitionInfoFile yaml file for +// later use. +func UpdatePartitionLabelMapping(partitionData, file string) error { + partitionInfo, err := ParsePartitionInfoFile(file) + if err != nil { + return err + } + + parts := strings.Split(partitionData, ":") + partitionInfo[parts[0]] = parts[2] + + return UpdatePartitionInfoFile(partitionInfo, file) +} + +func ParsePartitionInfoFile(file string) (PartitionInfo, error) { + var result PartitionInfo + + yamlFile, err := ioutil.ReadFile(file) + if err != nil { + return result, errors.Wrap(err, "reading the partition info file") + } + err = yaml.Unmarshal(yamlFile, &result) + if err != nil { + return result, errors.Wrap(err, "unmarshalling partition info file") + } + + return result, nil +} + +func UpdatePartitionInfoFile(partitionInfo PartitionInfo, file string) error { + data, err := yaml.Marshal(&partitionInfo) + if err != nil { + return errors.Wrap(err, "marshalling the new partition info to yaml") + } + err = ioutil.WriteFile(file, data, 0) + if err != nil { + return errors.Wrap(err, "writing back the partition info file") + } + return nil +} diff --git a/pkg/partition_info/partition_info_test.go b/pkg/partition_info/partition_info_test.go new file mode 100644 index 0000000..bd213ff --- /dev/null +++ b/pkg/partition_info/partition_info_test.go @@ -0,0 +1,102 @@ +package partition_info_test + +import ( + "io/ioutil" + "os" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + pi "github.com/kairos-io/kcrypt/pkg/partition_info" +) + +var _ = Describe("Partition Info file parsing", func() { + Describe("ParsePartitionInfoFile", func() { + var file string + + BeforeEach(func() { + file = "../../tests/assets/partition_info.yaml" + }) + + It("parses the file correctly", func() { + info, err := pi.ParsePartitionInfoFile(file) + Expect(err).ToNot(HaveOccurred()) + Expect(len(info)).To(Equal(2)) + Expect(info["COS_PERSISTENT"]).To(Equal("some_uuid_1")) + Expect(info["COS_OTHER"]).To(Equal("some_uuid_2")) + }) + }) + + Describe("UpdatePartitionInfoFile", func() { + var file *os.File + var err error + + BeforeEach(func() { + file, err = ioutil.TempFile("", "parition-info.*.yaml") + Expect(err).ToNot(HaveOccurred()) + + fileContents := ` +- label: TO_DELETE + uuid: old_uuid_1 +- label: TO_BE_UPDATED + uuid: old_uuid_2 +` + _, err = file.Write([]byte(fileContents)) + Expect(err).ToNot(HaveOccurred()) + }) + + AfterEach(func() { + os.Remove(file.Name()) + }) + + It("Updates the partition file correctly", func() { + partitionInfo := pi.PartitionInfo{ + "TO_BE_UPDATED": "new_uuid_1", + "NEW_PARTITION": "new_uuid_2", + } + + err = pi.UpdatePartitionInfoFile(partitionInfo, file.Name()) + Expect(err).ToNot(HaveOccurred()) + + dat, err := os.ReadFile(file.Name()) + Expect(err).ToNot(HaveOccurred()) + + expectedContent := `NEW_PARTITION: new_uuid_2 +TO_BE_UPDATED: new_uuid_1 +` + Expect(string(dat)).To(Equal(expectedContent)) + }) + }) + + Describe("UpdatePartitionLabelMapping", func() { + var file *os.File + var err error + + BeforeEach(func() { + file, err = ioutil.TempFile("", "parition-info.*.yaml") + Expect(err).ToNot(HaveOccurred()) + + _, err = file.Write([]byte("TO_KEEP: old_uuid_1")) + Expect(err).ToNot(HaveOccurred()) + }) + + AfterEach(func() { + os.Remove(file.Name()) + }) + + It("Updates the file correctly from a `kcrypt encrypt` return value", func() { + partitionData := "TO_BE_ADDED:some_name:new_uuid" + + err = pi.UpdatePartitionLabelMapping(partitionData, file.Name()) + Expect(err).ToNot(HaveOccurred()) + + dat, err := os.ReadFile(file.Name()) + Expect(err).ToNot(HaveOccurred()) + + expectedContent := `TO_BE_ADDED: new_uuid +TO_KEEP: old_uuid_1 +` + Expect(string(dat)).To(Equal(expectedContent)) + }) + }) +}) diff --git a/pkg/partition_info/suite_test.go b/pkg/partition_info/suite_test.go new file mode 100644 index 0000000..e3e910b --- /dev/null +++ b/pkg/partition_info/suite_test.go @@ -0,0 +1,13 @@ +package partition_info + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestPartitionINfo(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "PartitionInfo file parser test suite") +} diff --git a/tests/assets/partition_info.yaml b/tests/assets/partition_info.yaml new file mode 100644 index 0000000..4f630ab --- /dev/null +++ b/tests/assets/partition_info.yaml @@ -0,0 +1,2 @@ +COS_PERSISTENT: some_uuid_1 +COS_OTHER: some_uuid_2