1 Star 0 Fork 1

mysnapcore/mysnapd

forked from tupelo-shen/mysnapd 
Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
handlers.go 5.68 KB
Copy Edit Raw Blame History
tupelo-shen authored 2022-11-08 15:12 +08:00 . fix: overlord commit
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2016-2020 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package devicestate
import (
"errors"
"fmt"
"os/exec"
"time"
"gopkg.in/tomb.v2"
"gitee.com/mysnapcore/mysnapd/interfaces"
"gitee.com/mysnapcore/mysnapd/logger"
"gitee.com/mysnapcore/mysnapd/overlord/restart"
"gitee.com/mysnapcore/mysnapd/overlord/snapstate"
"gitee.com/mysnapcore/mysnapd/overlord/state"
)
func (m *DeviceManager) doMarkPreseeded(t *state.Task, _ *tomb.Tomb) error {
st := t.State()
st.Lock()
defer st.Unlock()
snaps, err := snapstate.All(st)
if err != nil {
return err
}
systemKey, err := interfaces.RecordedSystemKey()
if err != nil {
return fmt.Errorf("cannot get recorded system key: %v", err)
}
if m.preseed {
var preseeded bool
// the "preseeded" flag on this task is set to allow skipping the logic
// below in case this handler is retried in preseeding mode due to an
// EnsureBefore(0) done somewhere else.
// XXX: we should probably drop the flag from the task now that we have
// one on the state.
if err := t.Get("preseeded", &preseeded); err != nil && !errors.Is(err, state.ErrNoState) {
return err
}
if !preseeded {
preseeded = true
t.Set("preseeded", preseeded)
// unmount all snaps
// TODO: move to snapstate.UnmountAllSnaps.
for _, snapSt := range snaps {
info, err := snapSt.CurrentInfo()
if err != nil {
return err
}
logger.Debugf("unmounting snap %s at %s", info.InstanceName(), info.MountDir())
if _, err := exec.Command("umount", "-d", "-l", info.MountDir()).CombinedOutput(); err != nil {
return err
}
}
st.Set("preseeded", preseeded)
st.Set("preseed-system-key", systemKey)
st.Set("preseed-time", timeNow())
// do not mark this task done as this makes it racy against taskrunner tear down (the next task
// could start). Let this task finish after snapd restart when preseed mode is off.
restart.Request(st, restart.StopDaemon, nil)
}
return &state.Retry{Reason: "mark-preseeded will be marked done when snapd is executed in normal mode"}
}
// normal snapd run after snapd restart (not in preseed mode anymore)
st.Set("seed-restart-system-key", systemKey)
if err := m.setTimeOnce("seed-restart-time", startTime); err != nil {
return err
}
return nil
}
type seededSystem struct {
// System carries the recovery system label that was used to seed the
// current system
System string `json:"system"`
Model string `json:"model"`
// BrandID is the brand account ID
BrandID string `json:"brand-id"`
// Revision of the model assertion
Revision int `json:"revision"`
// Timestamp of model assertion
Timestamp time.Time `json:"timestamp"`
// SeedTime holds the timestamp when the system was seeded
SeedTime time.Time `json:"seed-time"`
}
func (s *seededSystem) sameAs(other *seededSystem) bool {
// in theory the system labels are unique, however be extra paranoid and
// check all model related fields too
return s.System == other.System &&
s.Model == other.Model &&
s.BrandID == other.BrandID &&
s.Revision == other.Revision
}
func (m *DeviceManager) recordSeededSystem(st *state.State, whatSeeded *seededSystem) error {
var seeded []seededSystem
if err := st.Get("seeded-systems", &seeded); err != nil && !errors.Is(err, state.ErrNoState) {
return err
}
for _, sys := range seeded {
if sys.sameAs(whatSeeded) {
return nil
}
}
// contrary to the usual approach of appending new entries to the list
// like we do with modeenv, the recently seeded system is added at the
// front, as it is not considered candidate like for the other entries,
// but rather it describes the currently existing
seeded = append([]seededSystem{*whatSeeded}, seeded...)
st.Set("seeded-systems", seeded)
return nil
}
func (m *DeviceManager) doMarkSeeded(t *state.Task, _ *tomb.Tomb) error {
st := t.State()
st.Lock()
defer st.Unlock()
if m.preseed {
return fmt.Errorf("internal error: mark-seeded task not expected in pre-seeding mode")
}
deviceCtx, err := DeviceCtx(st, t, nil)
if err != nil {
return fmt.Errorf("cannot get device context: %v", err)
}
if deviceCtx.HasModeenv() && deviceCtx.RunMode() {
modeEnv, err := maybeReadModeenv()
if err != nil {
return err
}
if modeEnv == nil {
return fmt.Errorf("missing modeenv, cannot proceed")
}
// unset recovery_system because that is only needed during install mode
modeEnv.RecoverySystem = ""
err = modeEnv.Write()
if err != nil {
return err
}
}
now := time.Now()
var whatSeeded *seededSystem
if err := t.Get("seed-system", &whatSeeded); err != nil && !errors.Is(err, state.ErrNoState) {
return err
}
if whatSeeded != nil && deviceCtx.RunMode() {
// record what seeded in the state only when in run mode
whatSeeded.SeedTime = now
if err := m.recordSeededSystem(st, whatSeeded); err != nil {
return fmt.Errorf("cannot record the seeded system: %v", err)
}
}
st.Set("seed-time", now)
st.Set("seeded", true)
// avoid possibly recording the same system multiple times etc.
t.SetStatus(state.DoneStatus)
// make sure we setup a fallback model/consider the next phase
// (registration) timely
st.EnsureBefore(0)
return nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mysnapcore/mysnapd.git
git@gitee.com:mysnapcore/mysnapd.git
mysnapcore
mysnapd
mysnapd
v0.1.0

Search