github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/daemon/api_console_conf.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package daemon 21 22 import ( 23 "encoding/json" 24 "io" 25 "net/http" 26 "time" 27 28 "github.com/snapcore/snapd/logger" 29 "github.com/snapcore/snapd/overlord/auth" 30 ) 31 32 var ( 33 routineConsoleConfStartCmd = &Command{ 34 Path: "/v2/internal/console-conf-start", 35 POST: consoleConfStartRoutine, 36 } 37 ) 38 39 var delayTime = 20 * time.Minute 40 41 type consoleConfRoutine struct{} 42 43 // ConsoleConfStartRoutineResult is the result of running the console-conf start 44 // routine.. 45 type ConsoleConfStartRoutineResult struct { 46 ActiveAutoRefreshChanges []string `json:"active-auto-refreshes,omitempty"` 47 ActiveAutoRefreshSnaps []string `json:"active-auto-refresh-snaps,omitempty"` 48 } 49 50 func consoleConfStartRoutine(c *Command, r *http.Request, _ *auth.UserState) Response { 51 // no body expected, error if we were provided anything 52 defer r.Body.Close() 53 var routineBody struct{} 54 decoder := json.NewDecoder(r.Body) 55 if err := decoder.Decode(&routineBody); err != nil && err != io.EOF { 56 return BadRequest("cannot decode request body into console-conf operation: %v", err) 57 } 58 59 // now run the start routine first by trying to grab a lock on the refreshes 60 // for all snaps, which fails if there are any active changes refreshing 61 // snaps 62 st := c.d.overlord.State() 63 st.Lock() 64 defer st.Unlock() 65 66 snapAutoRefreshChanges, err := c.d.overlord.SnapManager().EnsureAutoRefreshesAreDelayed(delayTime) 67 if err != nil { 68 return InternalError(err.Error()) 69 } 70 71 logger.Debugf("Ensured that new auto refreshes are delayed by %s to allow console-conf to run", delayTime) 72 73 if len(snapAutoRefreshChanges) == 0 { 74 // no changes yet, and we delayed the refresh successfully so 75 // console-conf is okay to run normally 76 return SyncResponse(&ConsoleConfStartRoutineResult{}, nil) 77 } 78 79 chgIds := make([]string, 0, len(snapAutoRefreshChanges)) 80 snapNames := make([]string, 0) 81 for _, chg := range snapAutoRefreshChanges { 82 chgIds = append(chgIds, chg.ID()) 83 var updatedSnaps []string 84 err := chg.Get("snap-names", &updatedSnaps) 85 if err != nil { 86 return InternalError(err.Error()) 87 } 88 snapNames = append(snapNames, updatedSnaps...) 89 } 90 91 // we have changes that the client should wait for before being ready 92 return SyncResponse(&ConsoleConfStartRoutineResult{ 93 ActiveAutoRefreshChanges: chgIds, 94 ActiveAutoRefreshSnaps: snapNames, 95 }, nil) 96 }