1 Star 0 Fork 1

mysnapcore/mysnapd

forked from tupelo-shen/mysnapd 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cookies.go 4.73 KB
一键复制 编辑 原始数据 按行查看 历史
tupelo-shen 提交于 2022-11-08 15:12 . fix: overlord commit
// -*- 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 snapstate
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"gitee.com/mysnapcore/mysnapd/dirs"
"gitee.com/mysnapcore/mysnapd/osutil"
"gitee.com/mysnapcore/mysnapd/overlord/state"
"gitee.com/mysnapcore/mysnapd/randutil"
)
func cookies(st *state.State) (map[string]string, error) {
var snapCookies map[string]string
if err := st.Get("snap-cookies", &snapCookies); err != nil {
if !errors.Is(err, state.ErrNoState) {
return nil, fmt.Errorf("cannot get snap cookies: %v", err)
}
snapCookies = make(map[string]string)
}
return snapCookies, nil
}
// SyncCookies creates snap cookies for snaps that are missing them (may be the case for snaps installed
// before the feature of running snapctl outside of hooks was introduced, leading to a warning
// from snap-confine).
// It is the caller's responsibility to lock state before calling this function.
func (m *SnapManager) SyncCookies(st *state.State) error {
var instanceNames map[string]*json.RawMessage
if err := st.Get("snaps", &instanceNames); err != nil && !errors.Is(err, state.ErrNoState) {
return err
}
snapCookies, err := cookies(st)
if err != nil {
return err
}
snapsWithCookies := make(map[string]bool)
for _, snap := range snapCookies {
// check if we have a cookie for non-installed snap or if we have a duplicated cookie
if _, ok := instanceNames[snap]; !ok || snapsWithCookies[snap] {
// there is no point in checking all cookies if we found a bad one - recreate them all
snapCookies = make(map[string]string)
snapsWithCookies = make(map[string]bool)
break
}
snapsWithCookies[snap] = true
}
var changed bool
// make sure every snap has a cookie, generate one if necessary
for snap := range instanceNames {
if _, ok := snapsWithCookies[snap]; !ok {
cookie, err := makeCookie()
if err != nil {
return err
}
snapCookies[cookie] = snap
changed = true
}
}
content := make(map[string]osutil.FileState)
for cookie, snap := range snapCookies {
content[fmt.Sprintf("snap.%s", snap)] = &osutil.MemoryFileState{
Content: []byte(cookie),
Mode: 0600,
}
}
if _, _, err := osutil.EnsureDirState(dirs.SnapCookieDir, "snap.*", content); err != nil {
return fmt.Errorf("Failed to synchronize snap cookies: %s", err)
}
if changed {
st.Set("snap-cookies", &snapCookies)
}
return nil
}
func (m *SnapManager) createSnapCookie(st *state.State, instanceName string) error {
snapCookies, err := cookies(st)
if err != nil {
return err
}
// make sure we don't create cookie if it already exists
for _, snap := range snapCookies {
if instanceName == snap {
return nil
}
}
cookieID, err := createCookieFile(instanceName)
if err != nil {
return err
}
snapCookies[cookieID] = instanceName
st.Set("snap-cookies", &snapCookies)
return nil
}
func (m *SnapManager) removeSnapCookie(st *state.State, instanceName string) error {
if err := removeCookieFile(instanceName); err != nil {
return err
}
var snapCookies map[string]string
err := st.Get("snap-cookies", &snapCookies)
if err != nil {
if !errors.Is(err, state.ErrNoState) {
return fmt.Errorf("cannot get snap cookies: %v", err)
}
// no cookies in the state
return nil
}
for cookieID, snap := range snapCookies {
if instanceName == snap {
delete(snapCookies, cookieID)
st.Set("snap-cookies", snapCookies)
return nil
}
}
return nil
}
func makeCookie() (string, error) {
return randutil.CryptoToken(39)
}
func createCookieFile(instanceName string) (cookieID string, err error) {
cookieID, err = makeCookie()
if err != nil {
return "", err
}
path := filepath.Join(dirs.SnapCookieDir, fmt.Sprintf("snap.%s", instanceName))
err = osutil.AtomicWriteFile(path, []byte(cookieID), 0600, 0)
if err != nil {
return "", fmt.Errorf("Failed to create cookie file %q: %s", path, err)
}
return cookieID, nil
}
func removeCookieFile(instanceName string) error {
path := filepath.Join(dirs.SnapCookieDir, fmt.Sprintf("snap.%s", instanceName))
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("Failed to remove cookie file %q: %s", path, err)
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/mysnapcore/mysnapd.git
git@gitee.com:mysnapcore/mysnapd.git
mysnapcore
mysnapd
mysnapd
v0.0.1

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385