Example #1
0
// 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()
}
Example #2
0
// 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
}