Skip to content

Commit

Permalink
t/l/f/store: make the fake store aware of components (#14882)
Browse files Browse the repository at this point in the history
* daemon, s/snaptest: remove errant .comp suffix that was resulting in files being named <name>.comp.comp

* t/l/f/store: make the fake store aware of components

* t/l/f/store: remove some dead code

* tests: add new store-state make-component-installable command

* t/l/f/c/fakestore: make help text on command args more clear

* t/l/f/store: remove superfluous .String() call
  • Loading branch information
andrewphelpsj authored Jan 6, 2025
1 parent d2e08bc commit 192ed07
Show file tree
Hide file tree
Showing 10 changed files with 699 additions and 68 deletions.
2 changes: 1 addition & 1 deletion daemon/api_sideload_n_try_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2026,7 +2026,7 @@ func (s *sideloadSuite) TestSideloadManyOnlyComponents(c *check.C) {
st.Lock()
defer st.Unlock()

expectedFileNames := []string{"one+comp-one.comp.comp", "one+comp-two.comp.comp", "one+comp-three.comp.comp", "one+comp-four.comp.comp"}
expectedFileNames := []string{"one+comp-one.comp", "one+comp-two.comp", "one+comp-three.comp", "one+comp-four.comp"}

fullComponentNames := make([]string, len(components))
for i, c := range components {
Expand Down
2 changes: 1 addition & 1 deletion snap/snaptest/snaptest.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ func MakeTestComponentWithFiles(c *check.C, componentName, componentYaml string,
func MakeTestComponent(c *check.C, compYaml string) string {
compInfo, err := snap.InfoFromComponentYaml([]byte(compYaml))
c.Assert(err, check.IsNil)
return MakeTestComponentWithFiles(c, compInfo.FullName()+".comp", compYaml, nil)
return MakeTestComponentWithFiles(c, compInfo.FullName(), compYaml, nil)
}

func populateContainer(c *check.C, yamlFile, yamlContent string, files [][]string) string {
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/fakestore/cmd/fakestore/cmd_new_snap_decl.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

type cmdNewSnapDeclaration struct {
Positional struct {
Snap string `description:"Snap file"`
Snap string `description:"Path to a snap file"`
} `positional-args:"yes"`

TopDir string `long:"dir" description:"Directory to be used by the store to keep and serve snaps, <dir>/asserts is used for assertions"`
Expand Down
51 changes: 51 additions & 0 deletions tests/lib/fakestore/cmd/fakestore/cmd_new_snap_resource_pair.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"encoding/json"
"fmt"
"os"

"github.com/snapcore/snapd/tests/lib/fakestore/refresh"
)

type cmdNewSnapResourcePair struct {
Positional struct {
Component string `description:"Path to a component blob file"`
SnapResourcePairJSONPath string `description:"Path to a json encoded snap resource pair revision subset"`
} `positional-args:"yes" required:"yes"`

TopDir string `long:"dir" description:"Directory to be used by the store to keep and serve snaps, <dir>/asserts is used for assertions"`
}

func (x *cmdNewSnapResourcePair) Execute(args []string) error {
content, err := os.ReadFile(x.Positional.SnapResourcePairJSONPath)
if err != nil {
return err
}

headers := make(map[string]interface{})
if err := json.Unmarshal(content, &headers); err != nil {
return err
}

p, err := refresh.NewSnapResourcePair(x.TopDir, x.Positional.Component, headers)
if err != nil {
return err
}
fmt.Println(p)
return nil
}

var shortNewSnapResourcePairHelp = "Make a new snap resource pair"

var longNewSnapResourcePairHelp = `
Generate a new snap resource pair signed with test keys. Snap ID, snap revision,
and component revision must be provided in the given JSON file. All other
headers are either derived from the component file or optional, but can be
overridden via the given JSON file.
`

func init() {
parser.AddCommand("new-snap-resource-pair", shortNewSnapResourcePairHelp, longNewSnapResourcePairHelp,
&cmdNewSnapResourcePair{})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"encoding/json"
"fmt"
"os"

"github.com/snapcore/snapd/tests/lib/fakestore/refresh"
)

type cmdNewSnapResourceRevision struct {
Positional struct {
Component string `description:"Path to a component blob file"`
SnapResourceRevJsonPath string `description:"Path to a json encoded snap resource revision subset"`
} `positional-args:"yes" required:"yes"`

TopDir string `long:"dir" description:"Directory to be used by the store to keep and serve snaps, <dir>/asserts is used for assertions"`
}

func (x *cmdNewSnapResourceRevision) Execute(args []string) error {
content, err := os.ReadFile(x.Positional.SnapResourceRevJsonPath)
if err != nil {
return err
}

headers := make(map[string]interface{})
if err := json.Unmarshal(content, &headers); err != nil {
return err
}

p, err := refresh.NewSnapResourceRevision(x.TopDir, x.Positional.Component, headers)
if err != nil {
return err
}
fmt.Println(p)
return nil
}

var shortNewSnapResourceRevisionHelp = "Make a new snap resource revision"

var longNewSnapResourceRevisionHelp = `
Generate a new snap resource revision signed with test keys. Snap ID and
revision must be provided in the given JSON file. All other headers are either
derived from the component file or optional, but can be overridden via the given
JSON file.
`

func init() {
parser.AddCommand("new-snap-resource-revision", shortNewSnapResourceRevisionHelp, longNewSnapResourceRevisionHelp,
&cmdNewSnapResourceRevision{})
}
2 changes: 1 addition & 1 deletion tests/lib/fakestore/cmd/fakestore/cmd_new_snap_rev.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

type cmdNewSnapRevision struct {
Positional struct {
Snap string `description:"Snap file"`
Snap string `description:"Path to a snap file"`
} `positional-args:"yes"`

TopDir string `long:"dir" description:"Directory to be used by the store to keep and serve snaps, <dir>/asserts is used for assertions"`
Expand Down
98 changes: 98 additions & 0 deletions tests/lib/fakestore/refresh/snap_asserts.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (

"github.com/snapcore/snapd/asserts"
"github.com/snapcore/snapd/asserts/systestkeys"
"github.com/snapcore/snapd/snap"
"github.com/snapcore/snapd/snap/snapfile"
)

func snapNameFromPath(snapPath string) string {
Expand Down Expand Up @@ -68,6 +70,102 @@ func NewSnapRevision(targetDir string, snap string, headers map[string]interface
return writeAssert(a, targetDir)
}

func NewSnapResourceRevision(targetDir string, compPath string, headers map[string]interface{}) (string, error) {
db, err := newAssertsDB(systestkeys.TestStorePrivKey)
if err != nil {
return "", err
}
digest, size, err := asserts.SnapFileSHA3_384(compPath)
if err != nil {
return "", err
}

container, err := snapfile.Open(compPath)
if err != nil {
return "", err
}

ci, err := snap.ReadComponentInfoFromContainer(container, nil, nil)
if err != nil {
return "", err
}

required := []string{"snap-id", "resource-revision"}
for _, r := range required {
if _, ok := headers[r]; !ok {
return "", fmt.Errorf("missing required header %q", r)
}
}

defaults := map[string]interface{}{
"type": "snap-resource-revision",
"authority-id": "testrootorg",
"developer-id": "testrootorg",
"resource-name": ci.Component.ComponentName,
"timestamp": time.Now().Format(time.RFC3339),
"resource-size": fmt.Sprintf("%d", size),
"resource-sha3-384": digest,
}
for k, v := range defaults {
if _, ok := headers[k]; !ok {
headers[k] = v
}
}
headers["authority-id"] = "testrootorg"
headers["snap-sha3-384"] = digest
headers["snap-size"] = fmt.Sprintf("%d", size)
headers["timestamp"] = time.Now().Format(time.RFC3339)

a, err := db.Sign(asserts.SnapResourceRevisionType, headers, nil, systestkeys.TestStoreKeyID)
if err != nil {
return "", err
}
return writeAssert(a, targetDir)
}

func NewSnapResourcePair(targetDir string, compPath string, headers map[string]interface{}) (string, error) {
db, err := newAssertsDB(systestkeys.TestStorePrivKey)
if err != nil {
return "", err
}

container, err := snapfile.Open(compPath)
if err != nil {
return "", err
}

ci, err := snap.ReadComponentInfoFromContainer(container, nil, nil)
if err != nil {
return "", err
}

required := []string{"snap-id", "resource-revision", "snap-revision"}
for _, r := range required {
if _, ok := headers[r]; !ok {
return "", fmt.Errorf("missing required header %q", r)
}
}

defaults := map[string]interface{}{
"type": "snap-resource-pair",
"authority-id": "testrootorg",
"developer-id": "testrootorg",
"resource-name": ci.Component.ComponentName,
"timestamp": time.Now().Format(time.RFC3339),
}
for k, v := range defaults {
if _, ok := headers[k]; !ok {
headers[k] = v
}
}

a, err := db.Sign(asserts.SnapResourcePairType, headers, nil, systestkeys.TestStoreKeyID)
if err != nil {
return "", err
}
return writeAssert(a, targetDir)
}

func NewSnapDeclaration(targetDir string, snap string, headers map[string]interface{}) (string, error) {
db, err := newAssertsDB(systestkeys.TestStorePrivKey)
if err != nil {
Expand Down
Loading

0 comments on commit 192ed07

Please sign in to comment.