代码拉取完成,页面将自动刷新
同步操作将从 tupelo-shen/mysnapd 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2017 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 asserts
import (
"fmt"
"strings"
"time"
"gitee.com/mysnapcore/mysnapd/snap/naming"
"gitee.com/mysnapcore/mysnapd/strutil"
)
// Repair holds an repair assertion which allows running repair
// code to fixup broken systems. It can be limited by series and models, as well
// as by bases and modes.
type Repair struct {
assertionBase
series []string
architectures []string
models []string
modes []string
bases []string
id int
disabled bool
timestamp time.Time
}
// BrandID returns the brand identifier that signed this assertion.
func (r *Repair) BrandID() string {
return r.HeaderString("brand-id")
}
// RepairID returns the sequential id of the repair. There
// should be a public place to look up details about the repair
// by brand-id and repair-id.
// (e.g. the snapcraft forum).
func (r *Repair) RepairID() int {
return r.id
}
// Sequence implements SequenceMember, it returns the same as RepairID.
func (r *Repair) Sequence() int {
return r.RepairID()
}
// Summary returns the mandatory summary description of the repair.
func (r *Repair) Summary() string {
return r.HeaderString("summary")
}
// Architectures returns the architectures that this assertions applies to.
func (r *Repair) Architectures() []string {
return r.architectures
}
// Series returns the series that this assertion is valid for.
func (r *Repair) Series() []string {
return r.series
}
// Modes returns the modes that this assertion is valid for. It is either a list
// of "run", "recover", or "install", or it is the empty list. The empty list
// is interpreted to mean only "run" mode.
func (r *Repair) Modes() []string {
return r.modes
}
// Bases returns the bases that this assertion is valid for. It is either a list
// of valid base snaps that Ubuntu Core systems can have or it is the empty
// list. The empty list effectively means all Ubuntu Core systems while "core"
// means Ubuntu Core 16, "core18" means Ubuntu Core 18, etc.
func (r *Repair) Bases() []string {
return r.bases
}
// Models returns the models that this assertion is valid for.
// It is a list of "brand-id/model-name" strings.
func (r *Repair) Models() []string {
return r.models
}
// Disabled returns true if the repair has been disabled.
func (r *Repair) Disabled() bool {
return r.disabled
}
// Timestamp returns the time when the repair was issued.
func (r *Repair) Timestamp() time.Time {
return r.timestamp
}
// Implement further consistency checks.
func (r *Repair) checkConsistency(db RODatabase, acck *AccountKey) error {
// Do the cross-checks when this assertion is actually used,
// i.e. in the future repair code
return nil
}
// expected interface is implemented
var _ consistencyChecker = (*Repair)(nil)
func assembleRepair(assert assertionBase) (Assertion, error) {
err := checkAuthorityMatchesBrand(&assert)
if err != nil {
return nil, err
}
repairID, err := checkSequence(assert.headers, "repair-id")
if err != nil {
return nil, err
}
summary, err := checkNotEmptyString(assert.headers, "summary")
if err != nil {
return nil, err
}
if strings.ContainsAny(summary, "\n\r") {
return nil, fmt.Errorf(`"summary" header cannot have newlines`)
}
series, err := checkStringList(assert.headers, "series")
if err != nil {
return nil, err
}
models, err := checkStringList(assert.headers, "models")
if err != nil {
return nil, err
}
architectures, err := checkStringList(assert.headers, "architectures")
if err != nil {
return nil, err
}
modes, err := checkStringList(assert.headers, "modes")
if err != nil {
return nil, err
}
bases, err := checkStringList(assert.headers, "bases")
if err != nil {
return nil, err
}
// validate that all base snap names are valid snap names
for _, b := range bases {
if err := naming.ValidateSnap(b); err != nil {
return nil, fmt.Errorf("invalid snap name %q in \"bases\"", b)
}
}
// verify that modes is a list of only "run" and "recover"
if len(modes) != 0 {
for _, m := range modes {
// note that we could import boot here to use i.e. boot.ModeRun, but
// that is rather a heavy package considering that this package is
// used in many places, so instead just use the values directly,
// they're unlikely to change now
if !strutil.ListContains([]string{"run", "recover"}, m) {
return nil, fmt.Errorf("header \"modes\" contains an invalid element: %q (valid values are run and recover)", m)
}
}
// if modes is non-empty, then bases must be core2X, i.e. core20+
// however, we don't know what future bases could be UC20-like and named
// differently yet, so we just fail on bases that we know as of today
// are _not_ UC20: core and core18
for _, b := range bases {
// fail on uc16 and uc18 base snaps
if b == "core" || b == "core18" || b == "core16" {
return nil, fmt.Errorf("in the presence of a non-empty \"modes\" header, \"bases\" must only contain base snaps supporting recovery modes")
}
}
}
disabled, err := checkOptionalBool(assert.headers, "disabled")
if err != nil {
return nil, err
}
timestamp, err := checkRFC3339Date(assert.headers, "timestamp")
if err != nil {
return nil, err
}
return &Repair{
assertionBase: assert,
series: series,
architectures: architectures,
models: models,
modes: modes,
bases: bases,
id: repairID,
disabled: disabled,
timestamp: timestamp,
}, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。