Skip to content

Commit

Permalink
cmd/snap-repair/runner.go: save the device's base and mode
Browse files Browse the repository at this point in the history
This information will be used to filter applicable repair assertions later on.

Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
  • Loading branch information
anonymouse64 committed Jan 13, 2021
1 parent c3ea6a5 commit b2b2046
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 22 deletions.
69 changes: 50 additions & 19 deletions cmd/snap-repair/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
"github.com/snapcore/snapd/logger"
"github.com/snapcore/snapd/osutil"
"github.com/snapcore/snapd/release"
"github.com/snapcore/snapd/snap"
"github.com/snapcore/snapd/snapdenv"
"github.com/snapcore/snapd/strutil"
)
Expand Down Expand Up @@ -495,6 +496,8 @@ func (run *Runner) Peek(brandID string, repairID int) (headers map[string]interf
type deviceInfo struct {
Brand string `json:"brand"`
Model string `json:"model"`
Base string `json:"base"`
Mode string `json:"mode"`
}

// RepairStatus represents the possible statuses of a repair.
Expand Down Expand Up @@ -688,37 +691,57 @@ func (run *Runner) findTimeLowerBound() error {
return nil
}

func findBrandAndModel() (string, string, error) {
func findBrandAndModel() (*deviceInfo, error) {
if osutil.FileExists(dirs.SnapModeenvFile) {
return findBrandAndModel20()
return findDevInfo20()
}
return findBrandAndModel16()
return findDevInfo16()
}

func findBrandAndModel20() (brand, model string, err error) {
func findDevInfo20() (*deviceInfo, error) {
cfg := goconfigparser.New()
cfg.AllowNoSectionHeader = true
if err := cfg.ReadFile(dirs.SnapModeenvFile); err != nil {
return "", "", err
return nil, err
}
brandAndModel, err := cfg.Get("", "model")
if err != nil {
return "", "", err
return nil, err
}
l := strings.SplitN(brandAndModel, "/", 2)
if len(l) != 2 {
return "", "", fmt.Errorf("cannot find brand/model in modeenv model string %q", brandAndModel)
return nil, fmt.Errorf("cannot find brand/model in modeenv model string %q", brandAndModel)
}

mode, err := cfg.Get("", "mode")
if err != nil {
return nil, err
}

baseName, err := cfg.Get("", "base")
if err != nil {
return nil, err
}

return l[0], l[1], nil
baseSn, err := snap.ParsePlaceInfoFromSnapFileName(baseName)
if err != nil {
return nil, err
}

return &deviceInfo{
Brand: l[0],
Model: l[1],
Base: baseSn.SnapName(),
Mode: mode,
}, nil
}

func findBrandAndModel16() (brand, model string, err error) {
func findDevInfo16() (*deviceInfo, error) {
workBS := asserts.NewMemoryBackstore()
assertSeedDir := filepath.Join(dirs.SnapSeedDir, "assertions")
dc, err := ioutil.ReadDir(assertSeedDir)
if err != nil {
return "", "", err
return nil, err
}
var modelAs *asserts.Model
for _, fi := range dc {
Expand All @@ -738,7 +761,7 @@ func findBrandAndModel16() (brand, model string, err error) {
switch a.Type() {
case asserts.ModelType:
if modelAs != nil {
return "", "", fmt.Errorf("multiple models in seed assertions")
return nil, fmt.Errorf("multiple models in seed assertions")
}
modelAs = a.(*asserts.Model)
case asserts.AccountType, asserts.AccountKeyType:
Expand All @@ -747,11 +770,11 @@ func findBrandAndModel16() (brand, model string, err error) {
}
}
if modelAs == nil {
return "", "", fmt.Errorf("no model assertion in seed data")
return nil, fmt.Errorf("no model assertion in seed data")
}
trustedBS := trustedBackstore(sysdb.Trusted())
if err := verifySignatures(modelAs, workBS, trustedBS); err != nil {
return "", "", err
return nil, err
}
acctPK := []string{modelAs.BrandID()}
acctMaxSupFormat := asserts.AccountType.MaxSupportedFormat()
Expand All @@ -760,22 +783,30 @@ func findBrandAndModel16() (brand, model string, err error) {
var err error
acct, err = workBS.Get(asserts.AccountType, acctPK, acctMaxSupFormat)
if err != nil {
return "", "", fmt.Errorf("no brand account assertion in seed data")
return nil, fmt.Errorf("no brand account assertion in seed data")
}
}
if err := verifySignatures(acct, workBS, trustedBS); err != nil {
return "", "", err
return nil, err
}
return modelAs.BrandID(), modelAs.Model(), nil

// get the base snap as well

return &deviceInfo{
Brand: modelAs.BrandID(),
Model: modelAs.Model(),
Base: modelAs.Base(),
// Mode is unset on uc16/uc18
}, nil
}

func (run *Runner) initDeviceInfo() error {
brandID, model, err := findBrandAndModel()
dev, err := findBrandAndModel()
if err != nil {
return fmt.Errorf("cannot set device information: %v", err)
}
run.state.Device.Brand = brandID
run.state.Device.Model = model
run.state.Device = *dev

return nil
}

Expand Down
7 changes: 4 additions & 3 deletions cmd/snap-repair/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (s *baseRunnerSuite) signSeqRepairs(c *C, repairs []string) []string {
return seq
}

const freshStateJSON = `{"device":{"brand":"my-brand","model":"my-model"},"time-lower-bound":"2017-08-11T15:49:49Z"}`
const freshStateJSON = `{"device":{"brand":"my-brand","model":"my-model","base":"","mode":""},"time-lower-bound":"2017-08-11T15:49:49Z"}`

func (s *baseRunnerSuite) freshState(c *C) {
err := os.MkdirAll(dirs.SnapRepairDir, 0775)
Expand Down Expand Up @@ -660,7 +660,7 @@ func (s *runnerSuite) TestSaveState(c *C) {
err = runner.SaveState()
c.Assert(err, IsNil)

c.Check(dirs.SnapRepairStateFile, testutil.FileEquals, `{"device":{"brand":"my-brand","model":"my-model"},"sequences":{"canonical":[{"sequence":1,"revision":3,"status":0}]},"time-lower-bound":"2017-08-11T15:49:49Z"}`)
c.Check(dirs.SnapRepairStateFile, testutil.FileEquals, `{"device":{"brand":"my-brand","model":"my-model","base":"","mode":""},"sequences":{"canonical":[{"sequence":1,"revision":3,"status":0}]},"time-lower-bound":"2017-08-11T15:49:49Z"}`)
}

func (s *runnerSuite) TestApplicable(c *C) {
Expand Down Expand Up @@ -1364,7 +1364,7 @@ AXNpZw==`, len(script), script)
}

func verifyRepairStatus(c *C, status repair.RepairStatus) {
c.Check(dirs.SnapRepairStateFile, testutil.FileContains, fmt.Sprintf(`{"device":{"brand":"","model":""},"sequences":{"canonical":[{"sequence":1,"revision":0,"status":%d}`, status))
c.Check(dirs.SnapRepairStateFile, testutil.FileContains, fmt.Sprintf(`{"device":{"brand":"","model":"","base":"","mode":""},"sequences":{"canonical":[{"sequence":1,"revision":0,"status":%d}`, status))
}

// tests related to correct execution of script
Expand Down Expand Up @@ -1786,6 +1786,7 @@ var _ = Suite(&runner20Suite{})
var mockModeenv = []byte(`
mode=run
model=my-brand/my-model-2
base=core20_1.snap
`)

func (s *runner20Suite) SetUpTest(c *C) {
Expand Down

0 comments on commit b2b2046

Please sign in to comment.