From 494d741f40f45adcdc73d5b02ad5f98d24501a76 Mon Sep 17 00:00:00 2001 From: Guillaume Boutry Date: Mon, 23 Sep 2024 18:04:32 +0200 Subject: [PATCH] Upgrade microcluster to LTS version Signed-off-by: Guillaume Boutry --- .github/workflows/build-snap.yml | 2 +- sunbeam-microcluster/access/handler.go | 41 +++++----- sunbeam-microcluster/api/certificates.go | 6 +- sunbeam-microcluster/api/config.go | 16 ++-- sunbeam-microcluster/api/jujuuser.go | 20 ++--- sunbeam-microcluster/api/manifests.go | 20 ++--- sunbeam-microcluster/api/nodes.go | 24 +++--- sunbeam-microcluster/api/servers.go | 9 ++- sunbeam-microcluster/api/status.go | 10 +-- sunbeam-microcluster/api/terraform.go | 36 ++++----- .../api/types/endpoint_prefix.go | 2 +- sunbeam-microcluster/client/config.go | 2 +- sunbeam-microcluster/cmd/sunbeamd/main.go | 40 ++++++---- sunbeam-microcluster/database/config.go | 26 +++---- .../database/config.mapper.go | 2 +- sunbeam-microcluster/database/jujuuser.go | 26 +++---- .../database/jujuuser.mapper.go | 2 +- sunbeam-microcluster/database/manifest.go | 20 ++--- .../database/manifest.mapper.go | 2 +- sunbeam-microcluster/database/node.go | 36 ++++----- sunbeam-microcluster/database/node.mapper.go | 28 +++---- sunbeam-microcluster/database/schema.go | 2 +- sunbeam-microcluster/go.mod | 35 ++++----- sunbeam-microcluster/go.sum | 76 +++++++++---------- sunbeam-microcluster/sunbeam/config.go | 22 +++--- sunbeam-microcluster/sunbeam/jujuuser.go | 18 ++--- sunbeam-microcluster/sunbeam/manifests.go | 18 ++--- sunbeam-microcluster/sunbeam/nodes.go | 22 +++--- sunbeam-microcluster/sunbeam/terraform.go | 41 +++++----- sunbeam-python/sunbeam/clusterd/cluster.py | 14 ++-- sunbeam-python/sunbeam/clusterd/service.py | 14 +++- .../sunbeam/provider/local/deployment.py | 7 ++ sunbeam-python/sunbeam/steps/clusterd.py | 3 +- .../tests/unit/sunbeam/test_clusterd.py | 2 +- 34 files changed, 338 insertions(+), 306 deletions(-) diff --git a/.github/workflows/build-snap.yml b/.github/workflows/build-snap.yml index ac59e94a..06ebcc37 100644 --- a/.github/workflows/build-snap.yml +++ b/.github/workflows/build-snap.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v3 - name: Build snap locally - uses: snapcore/action-build@v1 + uses: canonical/action-build@v1.3.0 id: snapcraft - name: Upload locally built snap artifact diff --git a/sunbeam-microcluster/access/handler.go b/sunbeam-microcluster/access/handler.go index 50f443b0..6ef0edba 100644 --- a/sunbeam-microcluster/access/handler.go +++ b/sunbeam-microcluster/access/handler.go @@ -9,9 +9,9 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/rest/access" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/rest/access" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/client" ) @@ -20,49 +20,48 @@ import ( // It checks if the request is trusted and verifies the client certificate against the cluster CA. // If the request is trusted or the client certificate is successfully verified, it allows the request. // Otherwise, it returns a forbidden response. -func AuthenticateClusterCAHandler(state *state.State, r *http.Request) response.Response { +func AuthenticateClusterCAHandler(state state.State, r *http.Request) (bool, response.Response) { - resp := access.AllowAuthenticated(state, r) + trusted, resp := access.AllowAuthenticated(state, r) - // AllowAuthenticated returns EmptySyncResponse if the request is trusted. - if resp == response.EmptySyncResponse { - return resp + if trusted { + return trusted, resp } leader, err := state.Leader() if err != nil { logger.Errorf("Failed to get leader client: %v", err) - return response.InternalError(err) + return false, response.InternalError(err) } // If this takes too long, we should look into caching the cluster CA. - clusterCA, err := client.ConfigClusterCAGet(state.Context, leader) + clusterCA, err := client.ConfigClusterCAGet(r.Context(), leader) if err != nil { // If no CA is configured, simply reject the request if strings.Contains(err.Error(), "not found") { logger.Debug("No cluster CA configured, rejecting request") - return response.Forbidden(nil) + return false, response.Forbidden(nil) } logger.Errorf("Failed to get cluster CA: %v", err) - return response.InternalError(nil) + return false, response.InternalError(nil) } roots := x509.NewCertPool() ok := roots.AppendCertsFromPEM([]byte(clusterCA)) if !ok { logger.Error("Failed to parse cluster CA") - return response.InternalError(nil) + return false, response.InternalError(nil) } if r.TLS == nil { logger.Error("Rejecting request without TLS") - return response.Forbidden(nil) + return false, response.Forbidden(nil) } if len(r.TLS.PeerCertificates) > 10 { logger.Error("Rejecting request with too many certificates") - return response.Forbidden(nil) + return false, response.Forbidden(nil) } opts := x509.VerifyOptions{ @@ -75,23 +74,23 @@ func AuthenticateClusterCAHandler(state *state.State, r *http.Request) response. _, err := cert.Verify(opts) if err == nil { logger.Debug("Allowing request authenticated using cluster CA") - return response.EmptySyncResponse + return true, nil } } - return response.Forbidden(nil) + return false, response.Forbidden(nil) } // AuthenticateUnixHandler only allow requests coming from the unix socket. -func AuthenticateUnixHandler(_ *state.State, r *http.Request) response.Response { +func AuthenticateUnixHandler(_ state.State, r *http.Request) (bool, response.Response) { if r.RemoteAddr == "@" { - return response.EmptySyncResponse + return true, nil } - return response.Forbidden(nil) + return false, response.Forbidden(nil) } // ClusterCATrustedEndpoint is a helper to simplify the creation of a cluster peer endpoint. -func ClusterCATrustedEndpoint(handler func(state *state.State, r *http.Request) response.Response, proxyTarget bool) rest.EndpointAction { +func ClusterCATrustedEndpoint(handler func(state state.State, r *http.Request) response.Response, proxyTarget bool) rest.EndpointAction { return rest.EndpointAction{ Handler: handler, AccessHandler: AuthenticateClusterCAHandler, diff --git a/sunbeam-microcluster/api/certificates.go b/sunbeam-microcluster/api/certificates.go index 197a0405..45bf82de 100644 --- a/sunbeam-microcluster/api/certificates.go +++ b/sunbeam-microcluster/api/certificates.go @@ -5,8 +5,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" ) @@ -22,7 +22,7 @@ var certPair = rest.Endpoint{ } // Return the member server certpair, should only be allowed over the Unix socket. -func cmdGetMemberServerCertPair(s *state.State, _ *http.Request) response.Response { +func cmdGetMemberServerCertPair(s state.State, _ *http.Request) response.Response { certs := s.ServerCert() if certs == nil { diff --git a/sunbeam-microcluster/api/config.go b/sunbeam-microcluster/api/config.go index 60ee7f1a..d1c6e495 100644 --- a/sunbeam-microcluster/api/config.go +++ b/sunbeam-microcluster/api/config.go @@ -7,8 +7,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/gorilla/mux" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" @@ -24,13 +24,13 @@ var configCmd = rest.Endpoint{ Delete: access.ClusterCATrustedEndpoint(cmdConfigDelete, true), } -func cmdConfigGet(s *state.State, r *http.Request) response.Response { +func cmdConfigGet(s state.State, r *http.Request) response.Response { var key string key, err := url.PathUnescape(mux.Vars(r)["key"]) if err != nil { return response.InternalError(err) } - config, err := sunbeam.GetConfig(s, key) + config, err := sunbeam.GetConfig(r.Context(), s, key) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -43,7 +43,7 @@ func cmdConfigGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, config) } -func cmdConfigPut(s *state.State, r *http.Request) response.Response { +func cmdConfigPut(s state.State, r *http.Request) response.Response { key, err := url.PathUnescape(mux.Vars(r)["key"]) if err != nil { return response.InternalError(err) @@ -55,7 +55,7 @@ func cmdConfigPut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.UpdateConfig(s, key, body.String()) + err = sunbeam.UpdateConfig(r.Context(), s, key, body.String()) if err != nil { return response.InternalError(err) } @@ -63,13 +63,13 @@ func cmdConfigPut(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdConfigDelete(s *state.State, r *http.Request) response.Response { +func cmdConfigDelete(s state.State, r *http.Request) response.Response { key, err := url.PathUnescape(mux.Vars(r)["key"]) if err != nil { return response.InternalError(err) } - err = sunbeam.DeleteConfig(s, key) + err = sunbeam.DeleteConfig(r.Context(), s, key) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { diff --git a/sunbeam-microcluster/api/jujuuser.go b/sunbeam-microcluster/api/jujuuser.go index 2a401f25..863819dd 100644 --- a/sunbeam-microcluster/api/jujuuser.go +++ b/sunbeam-microcluster/api/jujuuser.go @@ -7,8 +7,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/gorilla/mux" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" @@ -32,8 +32,8 @@ var jujuuserCmd = rest.Endpoint{ Delete: access.ClusterCATrustedEndpoint(cmdJujuUsersDelete, true), } -func cmdJujuUsersGetAll(s *state.State, _ *http.Request) response.Response { - users, err := sunbeam.ListJujuUsers(s) +func cmdJujuUsersGetAll(s state.State, r *http.Request) response.Response { + users, err := sunbeam.ListJujuUsers(r.Context(), s) if err != nil { return response.InternalError(err) } @@ -41,13 +41,13 @@ func cmdJujuUsersGetAll(s *state.State, _ *http.Request) response.Response { return response.SyncResponse(true, users) } -func cmdJujuUsersGet(s *state.State, r *http.Request) response.Response { +func cmdJujuUsersGet(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) if err != nil { return response.InternalError(err) } - jujuUser, err := sunbeam.GetJujuUser(s, name) + jujuUser, err := sunbeam.GetJujuUser(r.Context(), s, name) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -60,7 +60,7 @@ func cmdJujuUsersGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, jujuUser) } -func cmdJujuUsersPost(s *state.State, r *http.Request) response.Response { +func cmdJujuUsersPost(s state.State, r *http.Request) response.Response { var req types.JujuUser err := json.NewDecoder(r.Body).Decode(&req) @@ -68,7 +68,7 @@ func cmdJujuUsersPost(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.AddJujuUser(s, req.Username, req.Token) + err = sunbeam.AddJujuUser(r.Context(), s, req.Username, req.Token) if err != nil { return response.InternalError(err) } @@ -76,12 +76,12 @@ func cmdJujuUsersPost(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdJujuUsersDelete(s *state.State, r *http.Request) response.Response { +func cmdJujuUsersDelete(s state.State, r *http.Request) response.Response { name, err := url.PathUnescape(mux.Vars(r)["name"]) if err != nil { return response.SmartError(err) } - err = sunbeam.DeleteJujuUser(s, name) + err = sunbeam.DeleteJujuUser(r.Context(), s, name) if err != nil { return response.InternalError(err) } diff --git a/sunbeam-microcluster/api/manifests.go b/sunbeam-microcluster/api/manifests.go index 684ce996..65eba038 100644 --- a/sunbeam-microcluster/api/manifests.go +++ b/sunbeam-microcluster/api/manifests.go @@ -7,8 +7,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/gorilla/mux" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" @@ -33,9 +33,9 @@ var manifestCmd = rest.Endpoint{ Delete: access.ClusterCATrustedEndpoint(cmdManifestDelete, true), } -func cmdManifestsGetAll(s *state.State, _ *http.Request) response.Response { +func cmdManifestsGetAll(s state.State, r *http.Request) response.Response { - manifests, err := sunbeam.ListManifests(s) + manifests, err := sunbeam.ListManifests(r.Context(), s) if err != nil { return response.InternalError(err) } @@ -43,13 +43,13 @@ func cmdManifestsGetAll(s *state.State, _ *http.Request) response.Response { return response.SyncResponse(true, manifests) } -func cmdManifestGet(s *state.State, r *http.Request) response.Response { +func cmdManifestGet(s state.State, r *http.Request) response.Response { var manifestid string manifestid, err := url.PathUnescape(mux.Vars(r)["manifestid"]) if err != nil { return response.InternalError(err) } - manifest, err := sunbeam.GetManifest(s, manifestid) + manifest, err := sunbeam.GetManifest(r.Context(), s, manifestid) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -62,7 +62,7 @@ func cmdManifestGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, manifest) } -func cmdManifestsPost(s *state.State, r *http.Request) response.Response { +func cmdManifestsPost(s state.State, r *http.Request) response.Response { var req types.Manifest err := json.NewDecoder(r.Body).Decode(&req) @@ -70,7 +70,7 @@ func cmdManifestsPost(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.AddManifest(s, req.ManifestID, req.Data) + err = sunbeam.AddManifest(r.Context(), s, req.ManifestID, req.Data) if err != nil { return response.InternalError(err) } @@ -78,12 +78,12 @@ func cmdManifestsPost(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdManifestDelete(s *state.State, r *http.Request) response.Response { +func cmdManifestDelete(s state.State, r *http.Request) response.Response { manifestid, err := url.PathUnescape(mux.Vars(r)["manifestid"]) if err != nil { return response.SmartError(err) } - err = sunbeam.DeleteManifest(s, manifestid) + err = sunbeam.DeleteManifest(r.Context(), s, manifestid) if err != nil { return response.InternalError(err) } diff --git a/sunbeam-microcluster/api/nodes.go b/sunbeam-microcluster/api/nodes.go index 3bfb2e1e..d7c54952 100644 --- a/sunbeam-microcluster/api/nodes.go +++ b/sunbeam-microcluster/api/nodes.go @@ -7,8 +7,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/gorilla/mux" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" @@ -33,10 +33,10 @@ var nodeCmd = rest.Endpoint{ Delete: access.ClusterCATrustedEndpoint(cmdNodesDelete, true), } -func cmdNodesGetAll(s *state.State, r *http.Request) response.Response { +func cmdNodesGetAll(s state.State, r *http.Request) response.Response { roles := r.URL.Query()["role"] - nodes, err := sunbeam.ListNodes(s, roles) + nodes, err := sunbeam.ListNodes(r.Context(), s, roles) if err != nil { return response.InternalError(err) } @@ -44,13 +44,13 @@ func cmdNodesGetAll(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, nodes) } -func cmdNodesGet(s *state.State, r *http.Request) response.Response { +func cmdNodesGet(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) if err != nil { return response.InternalError(err) } - node, err := sunbeam.GetNode(s, name) + node, err := sunbeam.GetNode(r.Context(), s, name) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -63,7 +63,7 @@ func cmdNodesGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, node) } -func cmdNodesPost(s *state.State, r *http.Request) response.Response { +func cmdNodesPost(s state.State, r *http.Request) response.Response { req := types.Node{MachineID: -1} err := json.NewDecoder(r.Body).Decode(&req) @@ -71,7 +71,7 @@ func cmdNodesPost(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.AddNode(s, req.Name, req.Role, req.MachineID, req.SystemID) + err = sunbeam.AddNode(r.Context(), s, req.Name, req.Role, req.MachineID, req.SystemID) if err != nil { return response.InternalError(err) } @@ -79,7 +79,7 @@ func cmdNodesPost(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdNodesPut(s *state.State, r *http.Request) response.Response { +func cmdNodesPut(s state.State, r *http.Request) response.Response { req := types.Node{MachineID: -1} name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -92,7 +92,7 @@ func cmdNodesPut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.UpdateNode(s, name, req.Role, req.MachineID, req.SystemID) + err = sunbeam.UpdateNode(r.Context(), s, name, req.Role, req.MachineID, req.SystemID) if err != nil { return response.InternalError(err) } @@ -100,12 +100,12 @@ func cmdNodesPut(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdNodesDelete(s *state.State, r *http.Request) response.Response { +func cmdNodesDelete(s state.State, r *http.Request) response.Response { name, err := url.PathUnescape(mux.Vars(r)["name"]) if err != nil { return response.SmartError(err) } - err = sunbeam.DeleteNode(s, name) + err = sunbeam.DeleteNode(r.Context(), s, name) if err != nil { return response.InternalError(err) } diff --git a/sunbeam-microcluster/api/servers.go b/sunbeam-microcluster/api/servers.go index 48af0a00..bc3fd9b5 100644 --- a/sunbeam-microcluster/api/servers.go +++ b/sunbeam-microcluster/api/servers.go @@ -2,15 +2,16 @@ package api import ( - "github.com/canonical/microcluster/rest" + "github.com/canonical/microcluster/v2/rest" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" ) // Servers is a global list of all API servers on the /1.0 endpoint of // microcluster. -var Servers = []rest.Server{ - { - CoreAPI: true, +var Servers = map[string]rest.Server{ + "sunbeam": { + CoreAPI: true, + ServeUnix: true, Resources: []rest.Resources{ { PathPrefix: types.ExtendedPathPrefix, diff --git a/sunbeam-microcluster/api/status.go b/sunbeam-microcluster/api/status.go index 9bcc542c..250704ef 100644 --- a/sunbeam-microcluster/api/status.go +++ b/sunbeam-microcluster/api/status.go @@ -7,8 +7,8 @@ import ( "time" "github.com/canonical/lxd/lxd/response" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/logger" @@ -22,7 +22,7 @@ var statusCmd = rest.Endpoint{ Get: access.ClusterCATrustedEndpoint(cmdGetStatus, false), } -func cmdGetStatus(s *state.State, _ *http.Request) response.Response { +func cmdGetStatus(s state.State, r *http.Request) response.Response { leader, err := s.Leader() if err != nil { @@ -30,11 +30,11 @@ func cmdGetStatus(s *state.State, _ *http.Request) response.Response { return response.InternalError(err) } - queryCtx, cancel := context.WithTimeout(s.Context, time.Second*30) + queryCtx, cancel := context.WithTimeout(r.Context(), time.Second*30) defer cancel() var data []map[string]interface{} - err = leader.Query(queryCtx, "GET", "cluster/1.0", api.NewURL().Path("cluster"), nil, &data) + err = leader.Query(queryCtx, "GET", "core/1.0", api.NewURL().Path("cluster"), nil, &data) if err != nil { logger.Errorf("Failed to get cluster status: %v", err) return response.InternalError(err) diff --git a/sunbeam-microcluster/api/terraform.go b/sunbeam-microcluster/api/terraform.go index dd6ef998..659413c5 100644 --- a/sunbeam-microcluster/api/terraform.go +++ b/sunbeam-microcluster/api/terraform.go @@ -9,8 +9,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/lxd/util" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" "github.com/gorilla/mux" "github.com/canonical/snap-openstack/sunbeam-microcluster/access" @@ -64,8 +64,8 @@ var terraformUnlockCmd = rest.Endpoint{ Put: access.ClusterCATrustedEndpoint(cmdUnlockPut, false), } -func cmdStateList(s *state.State, _ *http.Request) response.Response { - plans, err := sunbeam.GetTerraformStates(s) +func cmdStateList(s state.State, r *http.Request) response.Response { + plans, err := sunbeam.GetTerraformStates(r.Context(), s) if err != nil { return response.InternalError(err) @@ -74,7 +74,7 @@ func cmdStateList(s *state.State, _ *http.Request) response.Response { return response.SyncResponse(true, plans) } -func cmdStateGet(s *state.State, r *http.Request) response.Response { +func cmdStateGet(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -82,7 +82,7 @@ func cmdStateGet(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - state, err := sunbeam.GetTerraformState(s, name) + state, err := sunbeam.GetTerraformState(r.Context(), s, name) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -105,7 +105,7 @@ func cmdStateGet(s *state.State, r *http.Request) response.Response { }) } -func cmdStatePut(s *state.State, r *http.Request) response.Response { +func cmdStatePut(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -121,7 +121,7 @@ func cmdStatePut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - dbLock, err := sunbeam.UpdateTerraformState(s, name, lockID, body.String()) + dbLock, err := sunbeam.UpdateTerraformState(r.Context(), s, name, lockID, body.String()) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusConflict { @@ -142,7 +142,7 @@ func cmdStatePut(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdStateDelete(s *state.State, r *http.Request) response.Response { +func cmdStateDelete(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -150,7 +150,7 @@ func cmdStateDelete(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = sunbeam.DeleteTerraformState(s, name) + err = sunbeam.DeleteTerraformState(r.Context(), s, name) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -163,8 +163,8 @@ func cmdStateDelete(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdLockList(s *state.State, _ *http.Request) response.Response { - plans, err := sunbeam.GetTerraformLocks(s) +func cmdLockList(s state.State, r *http.Request) response.Response { + plans, err := sunbeam.GetTerraformLocks(r.Context(), s) if err != nil { return response.InternalError(err) @@ -173,7 +173,7 @@ func cmdLockList(s *state.State, _ *http.Request) response.Response { return response.SyncResponse(true, plans) } -func cmdLockGet(s *state.State, r *http.Request) response.Response { +func cmdLockGet(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -181,7 +181,7 @@ func cmdLockGet(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - lock, err := sunbeam.GetTerraformLock(s, name) + lock, err := sunbeam.GetTerraformLock(r.Context(), s, name) if err != nil { if err, ok := err.(api.StatusError); ok { if err.Status() == http.StatusNotFound { @@ -198,7 +198,7 @@ func cmdLockGet(s *state.State, r *http.Request) response.Response { }) } -func cmdLockPut(s *state.State, r *http.Request) response.Response { +func cmdLockPut(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -212,7 +212,7 @@ func cmdLockPut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - dbLock, err := sunbeam.UpdateTerraformLock(s, name, body.String()) + dbLock, err := sunbeam.UpdateTerraformLock(r.Context(), s, name, body.String()) if err != nil { if err, ok := err.(api.StatusError); ok { jsonDBLock, err1 := json.Marshal(dbLock) @@ -237,7 +237,7 @@ func cmdLockPut(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func cmdUnlockPut(s *state.State, r *http.Request) response.Response { +func cmdUnlockPut(s state.State, r *http.Request) response.Response { var name string name, err := url.PathUnescape(mux.Vars(r)["name"]) @@ -251,7 +251,7 @@ func cmdUnlockPut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - dbLock, err := sunbeam.DeleteTerraformLock(s, name, body.String()) + dbLock, err := sunbeam.DeleteTerraformLock(r.Context(), s, name, body.String()) if err != nil { if err, ok := err.(api.StatusError); ok { jsonDBLock, err1 := json.Marshal(dbLock) diff --git a/sunbeam-microcluster/api/types/endpoint_prefix.go b/sunbeam-microcluster/api/types/endpoint_prefix.go index 90497b83..432a9d4f 100644 --- a/sunbeam-microcluster/api/types/endpoint_prefix.go +++ b/sunbeam-microcluster/api/types/endpoint_prefix.go @@ -1,7 +1,7 @@ package types import ( - "github.com/canonical/microcluster/rest/types" + "github.com/canonical/microcluster/v2/rest/types" ) const ( diff --git a/sunbeam-microcluster/client/config.go b/sunbeam-microcluster/client/config.go index 551da32a..8e578d64 100644 --- a/sunbeam-microcluster/client/config.go +++ b/sunbeam-microcluster/client/config.go @@ -6,7 +6,7 @@ import ( "time" "github.com/canonical/lxd/shared/api" - microCli "github.com/canonical/microcluster/client" + microCli "github.com/canonical/microcluster/v2/client" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" ) diff --git a/sunbeam-microcluster/cmd/sunbeamd/main.go b/sunbeam-microcluster/cmd/sunbeamd/main.go index 53168a69..9c119dfe 100644 --- a/sunbeam-microcluster/cmd/sunbeamd/main.go +++ b/sunbeam-microcluster/cmd/sunbeamd/main.go @@ -8,9 +8,9 @@ import ( "time" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/config" - "github.com/canonical/microcluster/microcluster" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/microcluster" + "github.com/canonical/microcluster/v2/rest/types" + "github.com/canonical/microcluster/v2/state" "github.com/spf13/cobra" "github.com/canonical/snap-openstack/sunbeam-microcluster/api" @@ -61,78 +61,88 @@ func (c *cmdDaemon) Command() *cobra.Command { } func (c *cmdDaemon) Run(_ *cobra.Command, _ []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.flagStateDir, SocketGroup: c.flagSocketGroup, Verbose: c.global.flagLogVerbose, Debug: c.global.flagLogDebug, ExtensionServers: api.Servers}) + m, err := microcluster.App(microcluster.Args{StateDir: c.flagStateDir}) if err != nil { return err } // Placeholder for post-action hooks that can be run by MicroCluster. - h := &config.Hooks{ + h := &state.Hooks{ // PreBootstrap is before after the daemon is initialized and bootstrapped. - PreBootstrap: func(_ *state.State, _ map[string]string) error { + PreBootstrap: func(_ context.Context, _ state.State, _ map[string]string) error { logger.Info("This is a hook that runs before the daemon is initialized and bootstrapped") return nil }, // PostBootstrap is run after the daemon is initialized and bootstrapped. - PostBootstrap: func(_ *state.State, _ map[string]string) error { + PostBootstrap: func(_ context.Context, _ state.State, _ map[string]string) error { logger.Info("This is a hook that runs after the daemon is initialized and bootstrapped") return nil }, // OnStart is run after the daemon is started. - OnStart: func(_ *state.State) error { + OnStart: func(_ context.Context, _ state.State) error { logger.Info("This is a hook that runs after the daemon first starts") return nil }, // PostJoin is run after the daemon is initialized and joins a cluster. - PostJoin: func(_ *state.State, _ map[string]string) error { + PostJoin: func(_ context.Context, _ state.State, _ map[string]string) error { logger.Info("This is a hook that runs after the daemon is initialized and joins an existing cluster, after OnNewMember runs on all peers") return nil }, // PreJoin is run after the daemon is initialized and joins a cluster. - PreJoin: func(_ *state.State, _ map[string]string) error { + PreJoin: func(_ context.Context, _ state.State, _ map[string]string) error { logger.Info("This is a hook that runs after the daemon is initialized and joins an existing cluster, before OnNewMember runs on all peers") return nil }, // PostRemove is run after the daemon is removed from a cluster. - PostRemove: func(s *state.State, _ bool) error { + PostRemove: func(_ context.Context, s state.State, _ bool) error { logger.Infof("This is a hook that is run on peer %q after a cluster member is removed", s.Name()) return nil }, // PreRemove is run before the daemon is removed from the cluster. - PreRemove: func(s *state.State, _ bool) error { + PreRemove: func(_ context.Context, s state.State, _ bool) error { logger.Infof("This is a hook that is run on peer %q just before it is removed", s.Name()) return nil }, // OnHeartbeat is run after a successful heartbeat round. - OnHeartbeat: func(_ *state.State) error { + OnHeartbeat: func(_ context.Context, _ state.State) error { logger.Info("This is a hook that is run on the dqlite leader after a successful heartbeat") return nil }, // OnNewMember is run after a new member has joined. - OnNewMember: func(s *state.State) error { + OnNewMember: func(_ context.Context, s state.State, _ types.ClusterMemberLocal) error { logger.Infof("This is a hook that is run on peer %q when a new cluster member has joined", s.Name()) return nil }, } + daemonArgs := microcluster.DaemonArgs{ + Verbose: c.global.flagLogVerbose, + Debug: c.global.flagLogDebug, + Version: "UNKNOWN", // FIXME: Add an explicit version to Sunbeam. + ExtensionServers: api.Servers, + ExtensionsSchema: database.SchemaExtensions, + APIExtensions: nil, + Hooks: h, + SocketGroup: c.flagSocketGroup, + } - return m.Start(context.Background(), database.SchemaExtensions, nil, h) + return m.Start(context.Background(), daemonArgs) } func init() { diff --git a/sunbeam-microcluster/database/config.go b/sunbeam-microcluster/database/config.go index 641b5653..e5ff0015 100644 --- a/sunbeam-microcluster/database/config.go +++ b/sunbeam-microcluster/database/config.go @@ -11,21 +11,21 @@ import ( //go:generate -command mapper lxd-generate db mapper -t config.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem objects table=config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem objects-by-Key table=config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem id table=config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem create table=config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem delete-by-Key table=config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ConfigItem update table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem objects table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem objects-by-Key table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem id table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem create table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem delete-by-Key table=config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ConfigItem update table=config // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem GetMany table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem GetOne table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem ID table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem Exists table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem Create table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem DeleteOne-by-Key table=config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ConfigItem Update table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem GetMany table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem GetOne table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem ID table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem Exists table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem Create table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem DeleteOne-by-Key table=config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ConfigItem Update table=config // ConfigItem is used to track the Ceph configuration. type ConfigItem struct { diff --git a/sunbeam-microcluster/database/config.mapper.go b/sunbeam-microcluster/database/config.mapper.go index f887c476..a428f038 100644 --- a/sunbeam-microcluster/database/config.mapper.go +++ b/sunbeam-microcluster/database/config.mapper.go @@ -12,7 +12,7 @@ import ( "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) var _ = api.ServerEnvironment{} diff --git a/sunbeam-microcluster/database/jujuuser.go b/sunbeam-microcluster/database/jujuuser.go index bdca4782..bed8de4d 100644 --- a/sunbeam-microcluster/database/jujuuser.go +++ b/sunbeam-microcluster/database/jujuuser.go @@ -3,20 +3,20 @@ package database //go:generate -command mapper lxd-generate db mapper -t jujuuser.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser objects table=jujuuser -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser objects-by-Username table=jujuuser -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser id table=jujuuser -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser create table=jujuuser -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser delete-by-Username table=jujuuser -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e JujuUser update table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser objects table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser objects-by-Username table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser id table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser create table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser delete-by-Username table=jujuuser +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e JujuUser update table=jujuuser // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser GetMany table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser GetOne table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser ID table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser Exists table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser Create table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser DeleteOne-by-Username table=jujuuser -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e JujuUser Update table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser GetMany table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser GetOne table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser ID table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser Exists table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser Create table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser DeleteOne-by-Username table=jujuuser +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e JujuUser Update table=jujuuser // JujuUser is used to track User and registration token information. type JujuUser struct { diff --git a/sunbeam-microcluster/database/jujuuser.mapper.go b/sunbeam-microcluster/database/jujuuser.mapper.go index fd62ce8d..91bf6dd6 100644 --- a/sunbeam-microcluster/database/jujuuser.mapper.go +++ b/sunbeam-microcluster/database/jujuuser.mapper.go @@ -12,7 +12,7 @@ import ( "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) var _ = api.ServerEnvironment{} diff --git a/sunbeam-microcluster/database/manifest.go b/sunbeam-microcluster/database/manifest.go index 185de493..9c41de86 100644 --- a/sunbeam-microcluster/database/manifest.go +++ b/sunbeam-microcluster/database/manifest.go @@ -7,23 +7,23 @@ import ( "net/http" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) //go:generate -command mapper lxd-generate db mapper -t manifest.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ManifestItem objects table=manifest -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ManifestItem objects-by-ManifestID table=manifest -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ManifestItem id table=manifest -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ManifestItem delete-by-ManifestID table=manifest +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ManifestItem objects table=manifest +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ManifestItem objects-by-ManifestID table=manifest +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ManifestItem id table=manifest +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ManifestItem delete-by-ManifestID table=manifest // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ManifestItem GetMany table=manifest -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ManifestItem GetOne table=manifest -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ManifestItem ID table=manifest -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ManifestItem Exists table=manifest -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ManifestItem DeleteOne-by-ManifestID table=manifest +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ManifestItem GetMany table=manifest +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ManifestItem GetOne table=manifest +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ManifestItem ID table=manifest +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ManifestItem Exists table=manifest +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ManifestItem DeleteOne-by-ManifestID table=manifest // ManifestItem is used to save the Sunbeam manifests provided by user. // AppliedDate is saved as Timestamp in database but retreived as string diff --git a/sunbeam-microcluster/database/manifest.mapper.go b/sunbeam-microcluster/database/manifest.mapper.go index d372d88f..9b230f18 100644 --- a/sunbeam-microcluster/database/manifest.mapper.go +++ b/sunbeam-microcluster/database/manifest.mapper.go @@ -12,7 +12,7 @@ import ( "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) var _ = api.ServerEnvironment{} diff --git a/sunbeam-microcluster/database/node.go b/sunbeam-microcluster/database/node.go index dd77a3bf..7ed84f88 100644 --- a/sunbeam-microcluster/database/node.go +++ b/sunbeam-microcluster/database/node.go @@ -6,34 +6,34 @@ import ( "fmt" "strings" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) //go:generate -command mapper lxd-generate db mapper -t node.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node objects table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node objects-by-Member table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node objects-by-Name table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node objects-by-Role table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node objects-by-MachineID table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node id table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node create table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node delete-by-Name table=nodes -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e node update table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node objects table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node objects-by-Member table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node objects-by-Name table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node objects-by-Role table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node objects-by-MachineID table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node id table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node create table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node delete-by-Name table=nodes +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e node update table=nodes // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node GetMany -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node GetOne -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node ID -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node Exists -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node Create -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node DeleteOne-by-Name -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e node Update +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node GetMany +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node GetOne +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node ID +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node Exists +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node Create +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node DeleteOne-by-Name +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e node Update // Node is used to track Node information. type Node struct { ID int - Member string `db:"join=internal_cluster_members.name&joinon=nodes.member_id"` + Member string `db:"join=core_cluster_members.name&joinon=nodes.member_id"` Name string `db:"primary=yes"` Role string MachineID int diff --git a/sunbeam-microcluster/database/node.mapper.go b/sunbeam-microcluster/database/node.mapper.go index 84c2d072..345d227f 100644 --- a/sunbeam-microcluster/database/node.mapper.go +++ b/sunbeam-microcluster/database/node.mapper.go @@ -12,46 +12,46 @@ import ( "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" + "github.com/canonical/microcluster/v2/cluster" ) var _ = api.ServerEnvironment{} var nodeObjects = cluster.RegisterStmt(` -SELECT nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id +SELECT nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id FROM nodes - JOIN internal_cluster_members ON nodes.member_id = internal_cluster_members.id + JOIN core_cluster_members ON nodes.member_id = core_cluster_members.id ORDER BY nodes.name `) var nodeObjectsByMember = cluster.RegisterStmt(` -SELECT nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id +SELECT nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id FROM nodes - JOIN internal_cluster_members ON nodes.member_id = internal_cluster_members.id + JOIN core_cluster_members ON nodes.member_id = core_cluster_members.id WHERE ( member = ? ) ORDER BY nodes.name `) var nodeObjectsByName = cluster.RegisterStmt(` -SELECT nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id +SELECT nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id FROM nodes - JOIN internal_cluster_members ON nodes.member_id = internal_cluster_members.id + JOIN core_cluster_members ON nodes.member_id = core_cluster_members.id WHERE ( nodes.name = ? ) ORDER BY nodes.name `) var nodeObjectsByRole = cluster.RegisterStmt(` -SELECT nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id +SELECT nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id FROM nodes - JOIN internal_cluster_members ON nodes.member_id = internal_cluster_members.id + JOIN core_cluster_members ON nodes.member_id = core_cluster_members.id WHERE ( nodes.role = ? ) ORDER BY nodes.name `) var nodeObjectsByMachineID = cluster.RegisterStmt(` -SELECT nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id +SELECT nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id FROM nodes - JOIN internal_cluster_members ON nodes.member_id = internal_cluster_members.id + JOIN core_cluster_members ON nodes.member_id = core_cluster_members.id WHERE ( nodes.machine_id = ? ) ORDER BY nodes.name `) @@ -63,7 +63,7 @@ SELECT nodes.id FROM nodes var nodeCreate = cluster.RegisterStmt(` INSERT INTO nodes (member_id, name, role, machine_id, system_id) - VALUES ((SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?), ?, ?, ?, ?) + VALUES ((SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?), ?, ?, ?, ?) `) var nodeDeleteByName = cluster.RegisterStmt(` @@ -72,14 +72,14 @@ DELETE FROM nodes WHERE name = ? var nodeUpdate = cluster.RegisterStmt(` UPDATE nodes - SET member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?), name = ?, role = ?, machine_id = ?, system_id = ? + SET member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?), name = ?, role = ?, machine_id = ?, system_id = ? WHERE id = ? `) // nodeColumns returns a string of column names to be used with a SELECT statement for the entity. // Use this function when building statements to retrieve database entries matching the Node entity. func nodeColumns() string { - return "nodes.id, internal_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id" + return "nodes.id, core_cluster_members.name AS member, nodes.name, nodes.role, nodes.machine_id, nodes.system_id" } // getNodes can be used to run handwritten sql.Stmts to return a slice of objects. diff --git a/sunbeam-microcluster/database/schema.go b/sunbeam-microcluster/database/schema.go index 4fedc56a..75235b59 100644 --- a/sunbeam-microcluster/database/schema.go +++ b/sunbeam-microcluster/database/schema.go @@ -27,7 +27,7 @@ CREATE TABLE nodes ( name TEXT NOT NULL, role TEXT, machine_id INTEGER, - FOREIGN KEY (member_id) REFERENCES "internal_cluster_members" (id) + FOREIGN KEY (member_id) REFERENCES "core_cluster_members" (id) UNIQUE(name) ); ` diff --git a/sunbeam-microcluster/go.mod b/sunbeam-microcluster/go.mod index 31a63707..1ea6ba86 100644 --- a/sunbeam-microcluster/go.mod +++ b/sunbeam-microcluster/go.mod @@ -1,10 +1,10 @@ module github.com/canonical/snap-openstack/sunbeam-microcluster -go 1.22.4 +go 1.22.5 require ( - github.com/canonical/lxd v0.0.0-20240620053341-f9f88f4e77ae - github.com/canonical/microcluster v0.0.0-20240620074518-efdde3f746b9 + github.com/canonical/lxd v0.0.0-20240730172021-8e39e5d4f55f + github.com/canonical/microcluster/v2 v2.0.2 github.com/gorilla/mux v1.8.1 github.com/spf13/cobra v1.8.1 ) @@ -12,10 +12,10 @@ require ( require ( github.com/Rican7/retry v0.3.1 // indirect github.com/armon/go-proxyproto v0.1.0 // indirect - github.com/canonical/go-dqlite v1.21.0 // indirect + github.com/canonical/go-dqlite v1.22.0 // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/renameio v1.0.1 // indirect @@ -26,25 +26,26 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kr/fs v0.1.0 // indirect github.com/kr/text v0.2.0 // indirect - github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/mattn/go-sqlite3 v1.14.23 // indirect github.com/muhlemmer/gu v0.3.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.6 // indirect - github.com/pkg/xattr v0.4.9 // indirect + github.com/pkg/xattr v0.4.10 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/zitadel/logging v0.6.0 // indirect - github.com/zitadel/oidc/v3 v3.25.1 // indirect + github.com/zitadel/oidc/v3 v3.30.0 // indirect github.com/zitadel/schema v1.3.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + go.opentelemetry.io/otel v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/sunbeam-microcluster/go.sum b/sunbeam-microcluster/go.sum index a50b3965..a96fe3d5 100644 --- a/sunbeam-microcluster/go.sum +++ b/sunbeam-microcluster/go.sum @@ -52,12 +52,12 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/canonical/go-dqlite v1.21.0 h1:4gLDdV2GF+vg0yv9Ff+mfZZNQ1JGhnQ3GnS2GeZPHfA= -github.com/canonical/go-dqlite v1.21.0/go.mod h1:Uvy943N8R4CFUAs59A1NVaziWY9nJ686lScY7ywurfg= -github.com/canonical/lxd v0.0.0-20240620053341-f9f88f4e77ae h1:hGqmOkL92DGFd0nxz7WaH2cTRyZ5zLtR6fUO2hSII5M= -github.com/canonical/lxd v0.0.0-20240620053341-f9f88f4e77ae/go.mod h1:no3pt2T1PrTq/FME3rZ5N/JH4GtLClSEThhOtOUb1X8= -github.com/canonical/microcluster v0.0.0-20240620074518-efdde3f746b9 h1:ogzDv0S33LI3DG44gRdRwtKb2ozV+SkPLp2/cBR3ksE= -github.com/canonical/microcluster v0.0.0-20240620074518-efdde3f746b9/go.mod h1:hQyeUVMU2XaiXy5InYE8YkbNtyJdZp8BPXRTNL9G950= +github.com/canonical/go-dqlite v1.22.0 h1:DuJmfcREl4gkQJyvZzjl2GHFZROhbPyfdjDRQXpkOyw= +github.com/canonical/go-dqlite v1.22.0/go.mod h1:Uvy943N8R4CFUAs59A1NVaziWY9nJ686lScY7ywurfg= +github.com/canonical/lxd v0.0.0-20240730172021-8e39e5d4f55f h1:bTaF5FmQk66wI8ILr+pzelTY6iNLXE9c2Ks2HG4Sp5U= +github.com/canonical/lxd v0.0.0-20240730172021-8e39e5d4f55f/go.mod h1:BVyKLSsJLTLX3o6WW0f5YDOO+J5HE3Np2WwYVrug0sY= +github.com/canonical/microcluster/v2 v2.0.2 h1:T0Bc3EQTdR17nAhKlAmGORL4y7FPcgAR09fWj/WlQck= +github.com/canonical/microcluster/v2 v2.0.2/go.mod h1:09N/J8tuijpAJdOER+e8IVWpn9cjzw9KzZvIunii/pA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -89,13 +89,13 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-chi/chi/v5 v5.0.13 h1:JlH2F2M8qnwl0N1+JFFzlX9TlKJYas3aPXdiuTmJL+w= -github.com/go-chi/chi/v5 v5.0.13/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -230,8 +230,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= +github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -258,8 +258,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= -github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= -github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= +github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA= +github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -272,8 +272,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -313,8 +313,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/logging v0.6.0 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank= github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= -github.com/zitadel/oidc/v3 v3.25.1 h1:mkGimTWzbb8wARUewIqr6LhTPZnZeL6WOeXWy+iz1aI= -github.com/zitadel/oidc/v3 v3.25.1/go.mod h1:UDwD+PRFbUBzabyPd9JORrakty3/wec7VpKZYi9Ahh0= +github.com/zitadel/oidc/v3 v3.30.0 h1:1IuZlK+X+JLExEA2PYgRlVvWHBhz/cMwT7VL/YrQabw= +github.com/zitadel/oidc/v3 v3.30.0/go.mod h1:+I5BgvGO5C2ZJrQRjV34EjkyA7P3GXyYGZgXI8Sdw18= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -327,12 +327,12 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= @@ -345,8 +345,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -421,8 +421,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -435,8 +435,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -449,8 +449,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -499,13 +499,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -515,8 +515,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/sunbeam-microcluster/sunbeam/config.go b/sunbeam-microcluster/sunbeam/config.go index b9a162dc..07103a5a 100644 --- a/sunbeam-microcluster/sunbeam/config.go +++ b/sunbeam-microcluster/sunbeam/config.go @@ -7,16 +7,16 @@ import ( "fmt" "strings" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/database" ) // GetConfig returns the ConfigItem based on key from the database -func GetConfig(s *state.State, key string) (string, error) { +func GetConfig(ctx context.Context, s state.State, key string) (string, error) { var value string - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { record, err := database.GetConfigItem(ctx, tx, key) if err != nil { return err @@ -33,10 +33,10 @@ func GetConfig(s *state.State, key string) (string, error) { } // GetConfigItemKeys returns the list of ConfigItem keys from the database -func GetConfigItemKeys(s *state.State, prefix *string) ([]string, error) { +func GetConfigItemKeys(ctx context.Context, s state.State, prefix *string) ([]string, error) { var keys []string - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { var err error keys, err = database.GetConfigItemKeys(ctx, tx, prefix) if err != nil { @@ -53,9 +53,9 @@ func GetConfigItemKeys(s *state.State, prefix *string) ([]string, error) { } // CreateConfig adds a new ConfigItem to the database -func CreateConfig(s *state.State, key string, value string) error { +func CreateConfig(ctx context.Context, s state.State, key string, value string) error { - return s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + return s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { _, err := database.CreateConfigItem(ctx, tx, database.ConfigItem{Key: key, Value: value}) if err != nil { return fmt.Errorf("Failed to record config item: %w", err) @@ -65,10 +65,10 @@ func CreateConfig(s *state.State, key string, value string) error { } // UpdateConfig updates a ConfigItem in the database -func UpdateConfig(s *state.State, key string, value string) error { +func UpdateConfig(ctx context.Context, s state.State, key string, value string) error { configItem := database.ConfigItem{Key: key, Value: value} - return s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + return s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := database.UpdateConfigItem(ctx, tx, key, configItem) if err != nil && strings.Contains(err.Error(), "ConfigItem not found") { _, err = database.CreateConfigItem(ctx, tx, configItem) @@ -82,8 +82,8 @@ func UpdateConfig(s *state.State, key string, value string) error { } // DeleteConfig deletes a ConfigItem from the database -func DeleteConfig(s *state.State, key string) error { - return s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { +func DeleteConfig(ctx context.Context, s state.State, key string) error { + return s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { return database.DeleteConfigItem(ctx, tx, key) }) } diff --git a/sunbeam-microcluster/sunbeam/jujuuser.go b/sunbeam-microcluster/sunbeam/jujuuser.go index 45e5b444..abef372c 100644 --- a/sunbeam-microcluster/sunbeam/jujuuser.go +++ b/sunbeam-microcluster/sunbeam/jujuuser.go @@ -5,18 +5,18 @@ import ( "database/sql" "fmt" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" "github.com/canonical/snap-openstack/sunbeam-microcluster/database" ) // ListJujuUsers returns the jujuusers from the database -func ListJujuUsers(s *state.State) (types.JujuUsers, error) { +func ListJujuUsers(ctx context.Context, s state.State) (types.JujuUsers, error) { users := types.JujuUsers{} // Get the juju users from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { records, err := database.GetJujuUsers(ctx, tx) if err != nil { return fmt.Errorf("Failed to fetch juju user: %w", err) @@ -39,9 +39,9 @@ func ListJujuUsers(s *state.State) (types.JujuUsers, error) { } // GetJujuUser returns a JujuUser with the given name -func GetJujuUser(s *state.State, name string) (types.JujuUser, error) { +func GetJujuUser(ctx context.Context, s state.State, name string) (types.JujuUser, error) { jujuUser := types.JujuUser{} - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { record, err := database.GetJujuUser(ctx, tx, name) if err != nil { return err @@ -57,9 +57,9 @@ func GetJujuUser(s *state.State, name string) (types.JujuUser, error) { } // AddJujuUser adds a Jujuuser to the database -func AddJujuUser(s *state.State, name string, token string) error { +func AddJujuUser(ctx context.Context, s state.State, name string, token string) error { // Add juju user to the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { _, err := database.CreateJujuUser(ctx, tx, database.JujuUser{Username: name, Token: token}) if err != nil { return fmt.Errorf("Failed to record juju user: %w", err) @@ -75,9 +75,9 @@ func AddJujuUser(s *state.State, name string, token string) error { } // DeleteJujuUser deletes the juju user record from the database -func DeleteJujuUser(s *state.State, name string) error { +func DeleteJujuUser(ctx context.Context, s state.State, name string) error { // Delete juju user from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := database.DeleteJujuUser(ctx, tx, name) if err != nil { return fmt.Errorf("Failed to delete juju user: %w", err) diff --git a/sunbeam-microcluster/sunbeam/manifests.go b/sunbeam-microcluster/sunbeam/manifests.go index 1831ad79..2fbaab3a 100644 --- a/sunbeam-microcluster/sunbeam/manifests.go +++ b/sunbeam-microcluster/sunbeam/manifests.go @@ -5,18 +5,18 @@ import ( "database/sql" "fmt" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" "github.com/canonical/snap-openstack/sunbeam-microcluster/database" ) // ListManifests return all the manifests -func ListManifests(s *state.State) (types.Manifests, error) { +func ListManifests(ctx context.Context, s state.State) (types.Manifests, error) { manifests := types.Manifests{} // Get the manifests from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { records, err := database.GetManifestItems(ctx, tx) if err != nil { return fmt.Errorf("Failed to fetch manifests: %w", err) @@ -40,10 +40,10 @@ func ListManifests(s *state.State) (types.Manifests, error) { } // GetManifest returns a Manifest with the given id -func GetManifest(s *state.State, manifestid string) (types.Manifest, error) { +func GetManifest(ctx context.Context, s state.State, manifestid string) (types.Manifest, error) { manifest := types.Manifest{} - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { var record *database.ManifestItem var err error // If manifest id is latest, retrieve the latest inserted record. @@ -67,9 +67,9 @@ func GetManifest(s *state.State, manifestid string) (types.Manifest, error) { } // AddManifest adds a manifest to the database -func AddManifest(s *state.State, manifestid string, data string) error { +func AddManifest(ctx context.Context, s state.State, manifestid string, data string) error { // Add manifest to the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { _, err := database.CreateManifestItem(ctx, tx, database.ManifestItem{ManifestID: manifestid, Data: data}) if err != nil { return fmt.Errorf("Failed to record manifest: %w", err) @@ -85,9 +85,9 @@ func AddManifest(s *state.State, manifestid string, data string) error { } // DeleteManifest deletes a manifest from database -func DeleteManifest(s *state.State, manifestid string) error { +func DeleteManifest(ctx context.Context, s state.State, manifestid string) error { // Delete manifest from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := database.DeleteManifestItem(ctx, tx, manifestid) if err != nil { return fmt.Errorf("Failed to delete manifest: %w", err) diff --git a/sunbeam-microcluster/sunbeam/nodes.go b/sunbeam-microcluster/sunbeam/nodes.go index 3ec0f231..5abed377 100644 --- a/sunbeam-microcluster/sunbeam/nodes.go +++ b/sunbeam-microcluster/sunbeam/nodes.go @@ -7,18 +7,18 @@ import ( "fmt" "sort" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" "github.com/canonical/snap-openstack/sunbeam-microcluster/database" ) // ListNodes return all the nodes, filterable by role (Optional) -func ListNodes(s *state.State, roles []string) (types.Nodes, error) { +func ListNodes(ctx context.Context, s state.State, roles []string) (types.Nodes, error) { nodes := types.Nodes{} // Get the nodes from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { records, err := database.GetNodesFromRoles(ctx, tx, roles) if err != nil { return fmt.Errorf("Failed to fetch nodes: %w", err) @@ -47,9 +47,9 @@ func ListNodes(s *state.State, roles []string) (types.Nodes, error) { } // GetNode returns a Node with the given name -func GetNode(s *state.State, name string) (types.Node, error) { +func GetNode(ctx context.Context, s state.State, name string) (types.Node, error) { node := types.Node{MachineID: -1} - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { record, err := database.GetNode(ctx, tx, name) if err != nil { return err @@ -71,13 +71,13 @@ func GetNode(s *state.State, name string) (types.Node, error) { } // AddNode adds a node to the database -func AddNode(s *state.State, name string, role []string, machineid int, systemid string) error { +func AddNode(ctx context.Context, s state.State, name string, role []string, machineid int, systemid string) error { nodeRole, err := roleToStr(role) if err != nil { return err } // Add node to the database. - err = s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { _, err := database.CreateNode(ctx, tx, database.Node{Member: s.Name(), Name: name, Role: nodeRole, MachineID: machineid, SystemID: systemid}) if err != nil { return fmt.Errorf("Failed to record node: %w", err) @@ -93,13 +93,13 @@ func AddNode(s *state.State, name string, role []string, machineid int, systemid } // UpdateNode updates a node record in the database -func UpdateNode(s *state.State, name string, role []string, machineid int, systemid string) error { +func UpdateNode(ctx context.Context, s state.State, name string, role []string, machineid int, systemid string) error { nodeRole, err := roleToStr(role) if err != nil { return err } // Update node to the database. - err = s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { node, err := database.GetNode(ctx, tx, name) if err != nil { return fmt.Errorf("Failed to retrieve node details: %w", err) @@ -130,9 +130,9 @@ func UpdateNode(s *state.State, name string, role []string, machineid int, syste } // DeleteNode deletes a node from database -func DeleteNode(s *state.State, name string) error { +func DeleteNode(ctx context.Context, s state.State, name string) error { // Delete node from the database. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := database.DeleteNode(ctx, tx, name) if err != nil { return fmt.Errorf("Failed to delete node: %w", err) diff --git a/sunbeam-microcluster/sunbeam/terraform.go b/sunbeam-microcluster/sunbeam/terraform.go index febf695b..33f32883 100644 --- a/sunbeam-microcluster/sunbeam/terraform.go +++ b/sunbeam-microcluster/sunbeam/terraform.go @@ -1,12 +1,13 @@ package sunbeam import ( + "context" "encoding/json" "net/http" "strings" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/snap-openstack/sunbeam-microcluster/api/types" ) @@ -15,9 +16,9 @@ const tfstatePrefix = "tfstate-" const tflockPrefix = "tflock-" // GetTerraformStates returns the list of terraform states from the database -func GetTerraformStates(s *state.State) ([]string, error) { +func GetTerraformStates(ctx context.Context, s state.State) ([]string, error) { prefix := tfstatePrefix - states, err := GetConfigItemKeys(s, &prefix) + states, err := GetConfigItemKeys(ctx, s, &prefix) if err != nil { return nil, err } @@ -31,18 +32,18 @@ func GetTerraformStates(s *state.State) ([]string, error) { } // GetTerraformState returns the terraform state from the database -func GetTerraformState(s *state.State, name string) (string, error) { +func GetTerraformState(ctx context.Context, s state.State, name string) (string, error) { tfstateKey := tfstatePrefix + name - state, err := GetConfig(s, tfstateKey) + state, err := GetConfig(ctx, s, tfstateKey) return state, err } // UpdateTerraformState updates the terraform state record in the database -func UpdateTerraformState(s *state.State, name string, lockID string, state string) (types.Lock, error) { +func UpdateTerraformState(ctx context.Context, s state.State, name string, lockID string, state string) (types.Lock, error) { var dbLock types.Lock tflockKey := tflockPrefix + name - lockInDb, err := GetConfig(s, tflockKey) + lockInDb, err := GetConfig(ctx, s, tflockKey) if err != nil { return dbLock, err } @@ -57,7 +58,7 @@ func UpdateTerraformState(s *state.State, name string, lockID string, state stri } tfstateKey := tfstatePrefix + name - err = UpdateConfig(s, tfstateKey, state) + err = UpdateConfig(ctx, s, tfstateKey, state) if err != nil { return dbLock, err } @@ -66,16 +67,16 @@ func UpdateTerraformState(s *state.State, name string, lockID string, state stri } // DeleteTerraformState deletes the terraform state from the database -func DeleteTerraformState(s *state.State, name string) error { +func DeleteTerraformState(ctx context.Context, s state.State, name string) error { tfstateKey := tfstatePrefix + name - err := DeleteConfig(s, tfstateKey) + err := DeleteConfig(ctx, s, tfstateKey) return err } // GetTerraformLocks returns the list of terraform locks from the database -func GetTerraformLocks(s *state.State) ([]string, error) { +func GetTerraformLocks(ctx context.Context, s state.State) ([]string, error) { prefix := tflockPrefix - locks, err := GetConfigItemKeys(s, &prefix) + locks, err := GetConfigItemKeys(ctx, s, &prefix) if err != nil { return nil, err } @@ -89,14 +90,14 @@ func GetTerraformLocks(s *state.State) ([]string, error) { } // GetTerraformLock returns the terraform lock from the database -func GetTerraformLock(s *state.State, name string) (string, error) { +func GetTerraformLock(ctx context.Context, s state.State, name string) (string, error) { tflockKey := tflockPrefix + name - lock, err := GetConfig(s, tflockKey) + lock, err := GetConfig(ctx, s, tflockKey) return lock, err } // UpdateTerraformLock updates the terraform lock record in the database -func UpdateTerraformLock(s *state.State, name string, lock string) (types.Lock, error) { +func UpdateTerraformLock(ctx context.Context, s state.State, name string, lock string) (types.Lock, error) { var reqLock types.Lock var dbLock types.Lock @@ -106,7 +107,7 @@ func UpdateTerraformLock(s *state.State, name string, lock string) (types.Lock, } tflockKey := tflockPrefix + name - lockInDb, err := GetConfig(s, tflockKey) + lockInDb, err := GetConfig(ctx, s, tflockKey) if err != nil { if err, ok := err.(api.StatusError); ok { // No Lock exists, add lock details in DB @@ -116,7 +117,7 @@ func UpdateTerraformLock(s *state.State, name string, lock string) (types.Lock, return dbLock, err } - err = UpdateConfig(s, tflockKey, string(j)) + err = UpdateConfig(ctx, s, tflockKey, string(j)) return dbLock, err } } @@ -138,7 +139,7 @@ func UpdateTerraformLock(s *state.State, name string, lock string) (types.Lock, } // DeleteTerraformLock deletes the terraform lock from the database -func DeleteTerraformLock(s *state.State, name string, lock string) (types.Lock, error) { +func DeleteTerraformLock(ctx context.Context, s state.State, name string, lock string) (types.Lock, error) { var reqLock types.Lock var dbLock types.Lock @@ -148,7 +149,7 @@ func DeleteTerraformLock(s *state.State, name string, lock string) (types.Lock, } tflockKey := tflockPrefix + name - lockInDb, err := GetConfig(s, tflockKey) + lockInDb, err := GetConfig(ctx, s, tflockKey) if err != nil { if err, ok := err.(api.StatusError); ok { // No Lock exists to unlock, send 200: OK @@ -166,7 +167,7 @@ func DeleteTerraformLock(s *state.State, name string, lock string) (types.Lock, // If the lock from DB and request are same, clear the lock from DB if dbLock.ID == reqLock.ID && dbLock.Operation == reqLock.Operation && dbLock.Who == reqLock.Who { - err = DeleteConfig(s, tflockKey) + err = DeleteConfig(ctx, s, tflockKey) return dbLock, err } diff --git a/sunbeam-python/sunbeam/clusterd/cluster.py b/sunbeam-python/sunbeam/clusterd/cluster.py index 527b9d34..3eb34b5f 100644 --- a/sunbeam-python/sunbeam/clusterd/cluster.py +++ b/sunbeam-python/sunbeam/clusterd/cluster.py @@ -41,7 +41,7 @@ def bootstrap_cluster(self, name: str, address: str) -> None: invoked on already existing node in cluster. """ data = {"bootstrap": True, "address": address, "name": name} - self._post("cluster/control", data=json.dumps(data)) + self._post("/core/control", data=json.dumps(data)) def join(self, name: str, address: str, token: str) -> None: """Join node to the micro cluster. @@ -55,7 +55,7 @@ def join(self, name: str, address: str, token: str) -> None: part of the generated tokens list. """ data = {"join_token": token, "address": address, "name": name} - self._post("cluster/control", data=json.dumps(data)) + self._post("/core/control", data=json.dumps(data)) def get_cluster_members(self) -> list: """List members in the cluster. @@ -63,7 +63,7 @@ def get_cluster_members(self) -> list: Returns a list of all members in the cluster. """ result = [] - cluster = self._get("/cluster/1.0/cluster") + cluster = self._get("/core/1.0/cluster") members = cluster.get("metadata", {}) keys = ["name", "address", "status"] for member in members: @@ -78,7 +78,7 @@ def remove(self, name: str) -> None: Raises NodeRemoveFromClusterException if the node is last member of the cluster. """ - self._delete(f"/cluster/1.0/cluster/{name}") + self._delete(f"/core/1.0/cluster/{name}") def generate_token(self, name: str) -> str: """Generate token for the node. @@ -89,12 +89,12 @@ def generate_token(self, name: str) -> str: generated. """ data = {"name": name} - result = self._post("/cluster/1.0/tokens", data=json.dumps(data)) + result = self._post("/core/control/tokens", data=json.dumps(data)) return result.get("metadata") def list_tokens(self) -> list: """List all generated tokens.""" - tokens = self._get("/cluster/1.0/tokens") + tokens = self._get("/core/control/tokens") return tokens.get("metadata") def delete_token(self, name: str) -> None: @@ -102,7 +102,7 @@ def delete_token(self, name: str) -> None: Raises TokenNotFoundException if token does not exist. """ - self._delete(f"/cluster/internal/tokens/{name}") + self._delete(f"/core/1.0/tokens/{name}") class ExtendedAPIService(service.BaseService): diff --git a/sunbeam-python/sunbeam/clusterd/service.py b/sunbeam-python/sunbeam/clusterd/service.py index 98c150cc..bb87ead4 100644 --- a/sunbeam-python/sunbeam/clusterd/service.py +++ b/sunbeam-python/sunbeam/clusterd/service.py @@ -94,6 +94,16 @@ class JujuUserNotFoundException(RemoteException): pass +class URLNotFoundException(RemoteException): + """Raise when URL is not found. + + Happens when the URL is not found in the remote or + microcluster is not bootstrapped. + """ + + pass + + class BaseService(ABC): """BaseService is the base service class for sunbeam clusterd services.""" @@ -144,6 +154,8 @@ def _request(self, method, path, **kwargs): # noqa: C901 too complex raise NodeAlreadyExistsException( "Already node exists in the sunbeam cluster" ) + elif "not found" == error: + raise URLNotFoundException("URL not found") elif "No remote exists with the given name" in error: raise NodeNotExistInClusterException( "Node does not exist in the sunbeam cluster" @@ -160,7 +172,7 @@ def _request(self, method, path, **kwargs): # noqa: C901 too complex raise TokenAlreadyGeneratedException( "Token already generated for the node" ) - elif "Daemon not yet initialized" in error: + elif "Database is not yet initialized" in error: raise ClusterServiceUnavailableException( "Sunbeam Cluster not initialized" ) diff --git a/sunbeam-python/sunbeam/provider/local/deployment.py b/sunbeam-python/sunbeam/provider/local/deployment.py index d98dae8e..e022893c 100644 --- a/sunbeam-python/sunbeam/provider/local/deployment.py +++ b/sunbeam-python/sunbeam/provider/local/deployment.py @@ -25,6 +25,7 @@ from sunbeam.clusterd.service import ( ClusterServiceUnavailableException, ConfigItemNotFoundException, + URLNotFoundException, ) from sunbeam.commands.configure import ( CLOUD_CONFIG_SECTION, @@ -88,6 +89,9 @@ def _load_juju_account(self) -> JujuAccount | None: def _load_juju_controller(self) -> JujuController | None: try: return JujuController.load(self.get_client()) + except URLNotFoundException: + LOG.debug("Url not found, is microcluster bootstrapped?", exc_info=True) + return None except ConfigItemNotFoundException: LOG.debug("No juju controller found", exc_info=True) return None @@ -101,6 +105,9 @@ def _load_juju_controller(self) -> JujuController | None: def _load_cert_pair(self) -> CertPair | None: try: return CertPair(**self.get_client().cluster.get_server_certpair()) + except URLNotFoundException: + LOG.debug("Url not found, is microcluster bootstrapped?", exc_info=True) + return None except ClusterServiceUnavailableException: LOG.debug("Clusterd service unavailable", exc_info=True) return None diff --git a/sunbeam-python/sunbeam/steps/clusterd.py b/sunbeam-python/sunbeam/steps/clusterd.py index 57aaad1e..f778b915 100644 --- a/sunbeam-python/sunbeam/steps/clusterd.py +++ b/sunbeam-python/sunbeam/steps/clusterd.py @@ -33,6 +33,7 @@ NodeNotExistInClusterException, TokenAlreadyGeneratedException, TokenNotFoundException, + URLNotFoundException, ) from sunbeam.core import questions from sunbeam.core.common import BaseStep, Result, ResultType, Status @@ -155,7 +156,7 @@ def prompt(self, console: Console | None = None) -> None: # And it *might* be called afterwards # We don't allow updating it return - except ClusterServiceUnavailableException: + except (ClusterServiceUnavailableException, URLNotFoundException): self.variables = {} self.variables.setdefault("bootstrap", {}) preseed = {} diff --git a/sunbeam-python/tests/unit/sunbeam/test_clusterd.py b/sunbeam-python/tests/unit/sunbeam/test_clusterd.py index 83a0993d..d3ec3ae1 100644 --- a/sunbeam-python/tests/unit/sunbeam/test_clusterd.py +++ b/sunbeam-python/tests/unit/sunbeam/test_clusterd.py @@ -338,7 +338,7 @@ def test_get_cluster_members_when_cluster_not_initialised(self): "status_code": 0, "operation": "", "error_code": 500, - "error": "Daemon not yet initialized", + "error": "Database is not yet initialized", "metadata": None, } mock_response = self._mock_response(