// FirstBoot will do some initial boot setup and then sync the // state func FirstBoot() error { // Disable firstboot on classic for now. In the long run we want // classic to have a firstboot as well so that we can install // snaps in a classic environment (LP: #1609903). However right // now firstboot is under heavy development so until the dust // settles we disable it. if release.OnClassic { return nil } if firstboot.HasRun() { return ErrNotFirstBoot } // FIXME: the netplan config is static, we do not need to generate // it from snapd, we can just set it in e.g. ubuntu-core-config if err := firstbootInitialNetworkConfig(); err != nil { logger.Noticef("Failed during inital network configuration: %s", err) } // snappy will be in a very unhappy state if this happens, // because populateStateFromSeed will error if there // is a state file already if err := populateStateFromSeed(); err != nil { return err } return firstboot.StampFirstBoot() }
// checkSnap ensures that the snap can be installed. func checkSnap(st *state.State, snapFilePath string, curInfo *snap.Info, flags Flags) error { // This assumes that the snap was already verified or --dangerous was used. s, _, err := openSnapFile(snapFilePath, nil) if err != nil { return err } if s.NeedsDevMode() && !flags.DevModeAllowed() { return fmt.Errorf("snap %q requires devmode or confinement override", s.Name()) } // verify we have a valid architecture if !arch.IsSupportedArchitecture(s.Architectures) { return fmt.Errorf("snap %q supported architectures (%s) are incompatible with this system (%s)", s.Name(), strings.Join(s.Architectures, ", "), arch.UbuntuArchitecture()) } // check assumes err = checkAssumes(s) if err != nil { return err } if s.Type != snap.TypeGadget { return nil } // gadget specific checks if release.OnClassic { // for the time being return fmt.Errorf("cannot install a gadget snap on classic") } st.Lock() defer st.Unlock() currentGadget, err := GadgetInfo(st) // in firstboot we have no gadget yet - that is ok if err == state.ErrNoState && !firstboot.HasRun() { return nil } if err != nil { return fmt.Errorf("cannot find original gadget snap") } // TODO: actually compare snap ids, from current gadget and candidate if currentGadget.Name() != s.Name() { return fmt.Errorf("cannot replace gadget snap with a different one") } return nil }