Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

o/snapstate: install components and snaps from file #14095

Merged
6 changes: 4 additions & 2 deletions overlord/devicestate/firstboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ func installSeedSnap(st *state.State, sn *seed.Snap, flags snapstate.Flags, prqt
flags.DevMode = true
}

t := snapstate.PathInstallGoal("", sn.Path, sn.SideInfo, snapstate.RevisionOptions{
// TODO: this will need to account for components in the future

goal := snapstate.PathInstallGoal("", sn.Path, sn.SideInfo, nil, snapstate.RevisionOptions{
Channel: sn.Channel,
})
info, ts, err := snapstate.InstallOne(context.Background(), st, t, snapstate.Options{
info, ts, err := snapstate.InstallOne(context.Background(), st, goal, snapstate.Options{
Flags: flags,
PrereqTracker: prqt,
Seed: true,
Expand Down
19 changes: 10 additions & 9 deletions overlord/snapstate/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,23 @@ func InstallComponentPath(st *state.State, csi *snap.ComponentSideInfo, info *sn
CompSideInfo: csi,
CompType: compInfo.Type,
CompPath: path,
componentInstallFlags: componentInstallFlags{
// The file passed around is temporary, make sure it gets removed.
RemoveComponentPath: true,
},
}

return doInstallComponent(st, &snapst, compSetup, snapsup, componentInstallFlags{
// The file passed around is temporary, make sure it gets removed.
RemoveComponentPath: true,
}, "")
return doInstallComponent(st, &snapst, compSetup, snapsup, "")
}

type componentInstallFlags struct {
RemoveComponentPath bool
SkipProfiles bool
RemoveComponentPath bool `json:"remove-component-path,omitempty"`
SkipProfiles bool `json:"skip-profiles,omitempty"`
}

// doInstallComponent might be called with the owner snap installed or not.
func doInstallComponent(st *state.State, snapst *SnapState, compSetup *ComponentSetup,
snapsup *SnapSetup, flags componentInstallFlags, fromChange string) (*state.TaskSet, error) {
snapsup *SnapSetup, fromChange string) (*state.TaskSet, error) {

// TODO check for experimental flag that will hide temporarily components

Expand Down Expand Up @@ -146,7 +147,7 @@ func doInstallComponent(st *state.State, snapst *SnapState, compSetup *Component
compSi.Component, revisionStr))
addTask(mount)
} else {
if flags.RemoveComponentPath {
if compSetup.RemoveComponentPath {
// If the revision is local, we will not need the
// temporary snap. This can happen when e.g.
// side-loading a local revision again. The path is
Expand Down Expand Up @@ -177,7 +178,7 @@ func doInstallComponent(st *state.State, snapst *SnapState, compSetup *Component
}

// security
if !flags.SkipProfiles {
if !compSetup.SkipProfiles {
setupSecurity := st.NewTask("setup-profiles", fmt.Sprintf(i18n.G("Setup component %q%s security profiles"), compSi.Component, revisionStr))
addTask(setupSecurity)
}
Expand Down
10 changes: 10 additions & 0 deletions overlord/snapstate/handlers_components.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package snapstate
import (
"errors"
"fmt"
"os"
"time"

"github.com/snapcore/snapd/logger"
Expand Down Expand Up @@ -291,6 +292,15 @@ func (m *SnapManager) doMountComponent(t *state.Task, _ *tomb.Tomb) (err error)
perfTimings.Save(st)
st.Unlock()

// if we're removing the snap file and we are mounting a component for the
// first time, then we know that the component also must be coming from an
// emphemeral file. in that case, remove it.
if compSetup.RemoveComponentPath {
if err := os.Remove(compSetup.CompPath); err != nil {
return err
}
}

return nil
}

Expand Down
3 changes: 3 additions & 0 deletions overlord/snapstate/snapmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ type ComponentSetup struct {
// DownloadInfo contains information about how to download this component.
// Will be nil if the component should be sourced from a local file.
DownloadInfo *snap.DownloadInfo `json:"download-info,omitempty"`
// componentInstallFlags is a set of flags that control the behavior of the
// component's installation/update.
componentInstallFlags
}

func NewComponentSetup(csi *snap.ComponentSideInfo, compType snap.ComponentType, compPath string) *ComponentSetup {
Expand Down
14 changes: 3 additions & 11 deletions overlord/snapstate/snapstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,14 +627,7 @@ func doInstall(st *state.State, snapst *SnapState, snapsup SnapSetup, compsups [

tasksAfterLinkSnap := make([]*state.Task, 0, len(compsups))
for _, compsup := range compsups {
compTaskSet, err := doInstallComponent(st, snapst, &compsup, &snapsup, componentInstallFlags{
// if we are removing the snap, we can assume that we should remove
// the component too
RemoveComponentPath: snapsup.RemoveSnapPath,
// the setup-profiles task that is created for the snap itself
// generates the security profiles for the snap and its new components
SkipProfiles: true,
}, "")
compTaskSet, err := doInstallComponent(st, snapst, &compsup, &snapsup, fromChange)
if err != nil {
return nil, fmt.Errorf("cannot install component %q: %v", compsup.CompSideInfo.Component, err)
}
Expand Down Expand Up @@ -1367,7 +1360,7 @@ func addPrereq(prqt PrereqTracker, info *snap.Info) {
// local revision and sideloading, or full metadata in which case it
// the snap will appear as installed from the store.
func InstallPath(st *state.State, si *snap.SideInfo, path, instanceName, channel string, flags Flags, prqt PrereqTracker) (*state.TaskSet, *snap.Info, error) {
target := PathInstallGoal(instanceName, path, si, RevisionOptions{
target := PathInstallGoal(instanceName, path, si, nil, RevisionOptions{
Channel: channel,
})
info, ts, err := InstallOne(context.Background(), st, target, Options{
Expand Down Expand Up @@ -1446,8 +1439,7 @@ func InstallPathWithDeviceContext(st *state.State, si *snap.SideInfo, path, name
opts = &RevisionOptions{}
}

target := PathInstallGoal(name, path, si, *opts)

target := PathInstallGoal(name, path, si, nil, *opts)
_, ts, err := InstallOne(context.Background(), st, target, Options{
Flags: flags,
UserID: userID,
Expand Down
Loading
Loading