[snapd-seed-glue] Fix installation of snaps in Calamares Full Installation due to a missing account key, and add an autopkgtest to ensure we catch this ahead of time in the future.
This commit is contained in:
parent
85a6d759fd
commit
cfa44c39d5
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,6 +1,8 @@
|
|||||||
snapd-extra-utils (1.1.0) UNRELEASED; urgency=medium
|
snapd-extra-utils (1.1.0) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* Slightly clean up tests, add new amd64 autopkgtest which checks a livefs.
|
* [snapd-seed-glue] Fix installation of snaps in Calamares Full Installation
|
||||||
|
due to a missing account key, and add an autopkgtest to ensure we catch
|
||||||
|
this ahead of time in the future (LP: #2096649).
|
||||||
|
|
||||||
-- Simon Quigley <tsimonq2@ubuntu.com> Sun, 16 Feb 2025 13:36:41 -0600
|
-- Simon Quigley <tsimonq2@ubuntu.com> Sun, 16 Feb 2025 13:36:41 -0600
|
||||||
|
|
||||||
|
2
debian/tests/control
vendored
2
debian/tests/control
vendored
@ -1,3 +1,3 @@
|
|||||||
Test-Command: snapd-seed-glue/tests/snapd_seed_glue_test
|
Test-Command: snapd-seed-glue/tests/snapd_seed_glue_test
|
||||||
Depends: snapd-seed-glue, tree, livecd-rootfs [amd64]
|
Depends: snapd-seed-glue, livecd-rootfs [amd64], squashfs-tools [amd64]
|
||||||
Restrictions: needs-internet, build-needed, isolation-machine, needs-sudo
|
Restrictions: needs-internet, build-needed, isolation-machine, needs-sudo
|
||||||
|
@ -73,25 +73,45 @@ func downloadAssertions(storeClient *store.Store, snapInfo *snap.Info, downloadD
|
|||||||
return fmt.Errorf("failed to fetch account-key assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
return fmt.Errorf("failed to fetch account-key assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Fetch account assertion using publisher-id
|
// Step 4: Fetch snap-revision assertion
|
||||||
accountAssertion, err := storeClient.Assertion(assertionTypes["account"], []string{publisherID}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to fetch account assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5: Fetch snap-revision assertion
|
|
||||||
snapSHA384Bytes, err := hex.DecodeString(snapSHA)
|
snapSHA384Bytes, err := hex.DecodeString(snapSHA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error decoding SHA3-384 hex string for snap %s: %w", snapInfo.SuggestedName, err)
|
return fmt.Errorf("error decoding SHA3-384 hex string for snap %s: %w", snapInfo.SuggestedName, err)
|
||||||
}
|
}
|
||||||
snapSHA384Base64 := base64.RawURLEncoding.EncodeToString(snapSHA384Bytes)
|
snapSHA384Base64 := base64.RawURLEncoding.EncodeToString(snapSHA384Bytes)
|
||||||
//revisionKey := fmt.Sprintf("%s/global-upload", snapSHA384Base64)
|
|
||||||
revisionKey := fmt.Sprintf("%s/", snapSHA384Base64)
|
revisionKey := fmt.Sprintf("%s/", snapSHA384Base64)
|
||||||
|
|
||||||
snapRevisionAssertion, err := storeClient.Assertion(assertionTypes["snap-revision"], []string{revisionKey}, nil)
|
snapRevisionAssertion, err := storeClient.Assertion(assertionTypes["snap-revision"], []string{revisionKey}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
verboseLog("Failed to fetch snap-revision assertion for snap %s: %v", snapInfo.SuggestedName, err)
|
verboseLog("Failed to fetch snap-revision assertion for snap %s: %v", snapInfo.SuggestedName, err)
|
||||||
// Proceeding without snap-revision might be acceptable based on your use-case
|
}
|
||||||
|
|
||||||
|
// Step 5: Fetch account assertions
|
||||||
|
publisherAccountAssertion, err := storeClient.Assertion(assertionTypes["account"], []string{publisherID}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch developer account assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5.1: Determine authority account from snap-declaration
|
||||||
|
authorityID, ok := snapDecl.Header("authority-id").(string)
|
||||||
|
if !ok || authorityID == "" {
|
||||||
|
return fmt.Errorf("snap-declaration assertion missing 'authority-id' header for snap %s", snapInfo.SuggestedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5.2: Fetch authority account assertion
|
||||||
|
authorityAccountAssertion, err := storeClient.Assertion(assertionTypes["account"], []string{authorityID}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch authority account assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5.3: Fetch developer account assertion
|
||||||
|
developerID, ok := snapRevisionAssertion.Header("developer-id").(string)
|
||||||
|
developerAccountAssertion := authorityAccountAssertion
|
||||||
|
if ok && authorityID != "" {
|
||||||
|
developerAccountAssertion, err = storeClient.Assertion(assertionTypes["account"], []string{developerID}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch developer account assertion for snap %s: %w", snapInfo.SuggestedName, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Write assertions in the desired order
|
// Step 6: Write assertions in the desired order
|
||||||
@ -99,12 +119,20 @@ func downloadAssertions(storeClient *store.Store, snapInfo *snap.Info, downloadD
|
|||||||
writeAssertion("account-key", accountKeyAssertion, assertionsFile)
|
writeAssertion("account-key", accountKeyAssertion, assertionsFile)
|
||||||
|
|
||||||
// 2. account
|
// 2. account
|
||||||
writeAssertion("account", accountAssertion, assertionsFile)
|
writeAssertion("account", publisherAccountAssertion, assertionsFile)
|
||||||
|
if authorityID != publisherID {
|
||||||
|
writeAssertion("account", authorityAccountAssertion, assertionsFile)
|
||||||
|
}
|
||||||
|
|
||||||
// 3. snap-declaration
|
// 3. snap-declaration
|
||||||
writeAssertion("snap-declaration", snapDecl, assertionsFile)
|
writeAssertion("snap-declaration", snapDecl, assertionsFile)
|
||||||
|
|
||||||
// 4. snap-revision (if fetched successfully)
|
// 4. developer account if present
|
||||||
|
if developerAccountAssertion != authorityAccountAssertion {
|
||||||
|
writeAssertion("account", developerAccountAssertion, assertionsFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. snap-revision (if fetched successfully)
|
||||||
if snapRevisionAssertion != nil {
|
if snapRevisionAssertion != nil {
|
||||||
writeAssertion("snap-revision", snapRevisionAssertion, assertionsFile)
|
writeAssertion("snap-revision", snapRevisionAssertion, assertionsFile)
|
||||||
}
|
}
|
||||||
@ -138,11 +166,13 @@ func writeAssertion(assertionType string, assertion asserts.Assertion, file *os.
|
|||||||
body := assertion.Body()
|
body := assertion.Body()
|
||||||
bodyLength := len(body)
|
bodyLength := len(body)
|
||||||
headers := assertion.Headers()
|
headers := assertion.Headers()
|
||||||
|
verboseLog("Assertion headers: %v", headers)
|
||||||
|
|
||||||
// Only write the account assertion if it is not Canonical
|
// Only write the account assertion if it is not Canonical
|
||||||
if assertionType == "account" {
|
if assertionType == "account" {
|
||||||
value, exists := headers["username"]
|
value, exists := headers["username"]
|
||||||
if exists && value == "canonical" {
|
if exists && value == "canonical" {
|
||||||
|
verboseLog("Skipping assertion due to duplication in account file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user