summaryrefslogtreecommitdiff
path: root/kernel
diff options
authorMichael Vogt <mvo@ubuntu.com>2020-08-13 12:32:15 +0200
committerMichael Vogt <mvo@ubuntu.com>2020-08-13 12:47:27 +0200
commit23715d465acafcebdc7b5b26415f215c6f7469b2 (patch)
tree6a4acd903aae074aae8ac1cc2d353e5f573f0c0f /kernel
parent61e7981d3b01635d1bff7a4401562d73ed979268 (diff)
gadget,kernel: add new "kernel" and "gadget/edition" packages
This commit moves the kernel.yaml parsing into the kernel package and extracts the gadget:editionNumber" helper into it's own gadget/editon packages so that it can be shared between the kernel and the gadget packages. Because meta/kernel.yaml is optional it is not an error if it is missing. Extra tests are also added.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kernel.go67
-rw-r--r--kernel/kernel_test.go110
2 files changed, 177 insertions, 0 deletions
diff --git a/kernel/kernel.go b/kernel/kernel.go
new file mode 100644
index 0000000000..0a9a9f95f5
--- /dev/null
+++ b/kernel/kernel.go
@@ -0,0 +1,67 @@
+// -*- Mode: Go; indent-tabs-mode: t -*-
+
+/*
+ * Copyright (C) 2020 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package kernel
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ "gopkg.in/yaml.v2"
+
+ "github.com/snapcore/snapd/gadget/edition"
+)
+
+type Asset struct {
+ Edition edition.Number `yaml:"edition,omitempty"`
+ Content []string `yaml:"content,omitempty"`
+}
+
+type Info struct {
+ Assets map[string]*Asset `yaml:"assets,omitempty"`
+}
+
+// InfoFromKernelYaml reads the provided kernel metadata.
+func InfoFromKernelYaml(kernelYaml []byte) (*Info, error) {
+ var ki Info
+
+ if err := yaml.Unmarshal(kernelYaml, &ki); err != nil {
+ return nil, fmt.Errorf("cannot parse kernel metadata: %v", err)
+ }
+
+ return &ki, nil
+}
+
+// ReadInfo reads the kernel specific metadata from meta/kernel.yaml
+// in the snap root directory.
+func ReadInfo(kernelSnapRootDir string) (*Info, error) {
+ p := filepath.Join(kernelSnapRootDir, "meta", "kernel.yaml")
+ content, err := ioutil.ReadFile(p)
+ // meta/kernel.yaml is optional so we should not error here if
+ // it is missing
+ if os.IsNotExist(err) {
+ return &Info{}, nil
+ }
+ if err != nil {
+ return nil, fmt.Errorf("cannot read kernel info: %v", err)
+ }
+ return InfoFromKernelYaml(content)
+}
diff --git a/kernel/kernel_test.go b/kernel/kernel_test.go
new file mode 100644
index 0000000000..aef51ee600
--- /dev/null
+++ b/kernel/kernel_test.go
@@ -0,0 +1,110 @@
+// -*- Mode: Go; indent-tabs-mode: t -*-
+
+/*
+ * Copyright (C) 2020 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package kernel_test
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+
+ . "gopkg.in/check.v1"
+
+ "github.com/snapcore/snapd/kernel"
+)
+
+type kernelYamlTestSuite struct{}
+
+var _ = Suite(&kernelYamlTestSuite{})
+
+func TestCommand(t *testing.T) { TestingT(t) }
+
+var mockKernelYaml = []byte(`
+assets:
+ dtbs:
+ edition: 1
+ content:
+ - dtbs/bcm2711-rpi-4-b.dtb
+ - dtbs/bcm2836-rpi-2-b.dtb
+`)
+
+func (s *kernelYamlTestSuite) TestInfoFromKernelYamlSad(c *C) {
+ ki, err := kernel.InfoFromKernelYaml([]byte("foo"))
+ c.Check(err, ErrorMatches, "(?m)cannot parse kernel metadata: .*")
+ c.Check(ki, IsNil)
+}
+
+func (s *kernelYamlTestSuite) TestInfoFromKernelYamlHappy(c *C) {
+ ki, err := kernel.InfoFromKernelYaml(mockKernelYaml)
+ c.Check(err, IsNil)
+ c.Check(ki, DeepEquals, &kernel.Info{
+ Assets: map[string]*kernel.Asset{
+ "dtbs": &kernel.Asset{
+ Edition: 1,
+ Content: []string{
+ "dtbs/bcm2711-rpi-4-b.dtb",
+ "dtbs/bcm2836-rpi-2-b.dtb",
+ },
+ },
+ },
+ })
+}
+
+func (s *kernelYamlTestSuite) TestReadKernelYamlOptional(c *C) {
+ ki, err := kernel.ReadInfo("this-path-does-not-exist")
+ c.Check(err, IsNil)
+ c.Check(ki, DeepEquals, &kernel.Info{})
+}
+
+func (s *kernelYamlTestSuite) TestReadKernelYamlSad(c *C) {
+ mockKernelSnapRoot := c.MkDir()
+ kernelYamlPath := filepath.Join(mockKernelSnapRoot, "meta/kernel.yaml")
+ err := os.MkdirAll(filepath.Dir(kernelYamlPath), 0755)
+ c.Assert(err, IsNil)
+ err = ioutil.WriteFile(kernelYamlPath, []byte(`invalid-kernel-yaml`), 0644)
+ c.Assert(err, IsNil)
+
+ ki, err := kernel.ReadInfo(mockKernelSnapRoot)
+ c.Check(err, ErrorMatches, `(?m)cannot parse kernel metadata: yaml: unmarshal errors:.*`)
+ c.Check(ki, IsNil)
+}
+
+func (s *kernelYamlTestSuite) TestReadKernelYamlHappy(c *C) {
+ mockKernelSnapRoot := c.MkDir()
+ kernelYamlPath := filepath.Join(mockKernelSnapRoot, "meta/kernel.yaml")
+ err := os.MkdirAll(filepath.Dir(kernelYamlPath), 0755)
+ c.Assert(err, IsNil)
+ err = ioutil.WriteFile(kernelYamlPath, mockKernelYaml, 0644)
+ c.Assert(err, IsNil)
+
+ ki, err := kernel.ReadInfo(mockKernelSnapRoot)
+ c.Assert(err, IsNil)
+ c.Check(ki, DeepEquals, &kernel.Info{
+ Assets: map[string]*kernel.Asset{
+ "dtbs": &kernel.Asset{
+ Edition: 1,
+ Content: []string{
+ "dtbs/bcm2711-rpi-4-b.dtb",
+ "dtbs/bcm2836-rpi-2-b.dtb",
+ },
+ },
+ },
+ })
+}