github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/podspec.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/mgo/v3" 9 "github.com/juju/mgo/v3/txn" 10 "github.com/juju/names/v5" 11 12 "github.com/juju/juju/core/leadership" 13 ) 14 15 type containerSpecDoc struct { 16 // Id holds container spec document key. 17 // It is the global key of the application represented 18 // by this container. 19 Id string `bson:"_id"` 20 21 Spec string `bson:"spec"` 22 // RawSpec is the raw format of k8s spec. 23 RawSpec string `bson:"raw-spec"` 24 25 UpgradeCounter int `bson:"upgrade-counter"` 26 } 27 28 // SetPodSpec sets the pod spec for the given application tag while making sure 29 // that the caller is the leader by validating the provided token. For cases 30 // where leadership checks are not important (e.g. migrations), a nil Token can 31 // be provided to bypass the leadership checks. 32 // 33 // An error will be returned if the specified application is not alive or the 34 // leadership check fails. 35 func (m *CAASModel) SetPodSpec(token leadership.Token, appTag names.ApplicationTag, spec *string) error { 36 modelOp := m.SetPodSpecOperation(token, appTag, spec) 37 return m.st.ApplyOperation(modelOp) 38 } 39 40 // SetPodSpecOperation returns a ModelOperation for updating a PodSpec. For 41 // cases where leadership checks are not important (e.g. migrations), a nil 42 // Token can be provided to bypass the leadership checks. 43 func (m *CAASModel) SetPodSpecOperation(token leadership.Token, appTag names.ApplicationTag, spec *string) ModelOperation { 44 return newSetPodSpecOperation(m, token, appTag, spec) 45 } 46 47 // SetRawK8sSpecOperation returns a ModelOperation for updating a raw k8s spec. For 48 // cases where leadership checks are not important (e.g. migrations), a nil 49 // Token can be provided to bypass the leadership checks. 50 func (m *CAASModel) SetRawK8sSpecOperation(token leadership.Token, appTag names.ApplicationTag, spec *string) ModelOperation { 51 return newSetRawK8sSpecOperation(m, token, appTag, spec) 52 } 53 54 // RawK8sSpec returns the raw k8s spec for the given application tag. 55 func (m *CAASModel) RawK8sSpec(appTag names.ApplicationTag) (string, error) { 56 info, err := m.podInfo(appTag) 57 if err != nil { 58 return "", errors.Trace(err) 59 } 60 return info.RawSpec, nil 61 } 62 63 // PodSpec returns the pod spec for the given application tag. 64 func (m *CAASModel) PodSpec(appTag names.ApplicationTag) (string, error) { 65 info, err := m.podInfo(appTag) 66 if err != nil { 67 return "", errors.Trace(err) 68 } 69 return info.Spec, nil 70 } 71 72 func (m *CAASModel) podInfo(appTag names.ApplicationTag) (*containerSpecDoc, error) { 73 var doc containerSpecDoc 74 if err := readPodInfo(m.mb.db(), appTag.Id(), &doc); err != nil { 75 return nil, err 76 } 77 return &doc, nil 78 } 79 80 func readPodInfo(db Database, appName string, doc interface{}) error { 81 coll, cleanup := db.GetCollection(podSpecsC) 82 defer cleanup() 83 if err := coll.FindId(applicationGlobalKey(appName)).One(doc); err != nil { 84 if err == mgo.ErrNotFound { 85 return errors.NotFoundf("k8s spec for application %s", appName) 86 } 87 return errors.Trace(err) 88 } 89 return nil 90 } 91 92 func removePodSpecOp(appTag names.ApplicationTag) txn.Op { 93 return txn.Op{ 94 C: podSpecsC, 95 Id: applicationGlobalKey(appTag.Id()), 96 Remove: true, 97 } 98 }