diff --git a/microceph/Makefile b/microceph/Makefile index d5297e7c..f8ada913 100644 --- a/microceph/Makefile +++ b/microceph/Makefile @@ -1,11 +1,16 @@ +pkg_version=$(shell apt-cache policy ceph-common | awk '/Candidate:/{ print $$2 }' ) +git_version=$(shell git describe --always --dirty --abbrev=10) +MC_VERSION=ceph-version: $(pkg_version); microceph-git: $(git_version) +LDFLAGS="-X 'github.com/canonical/microceph/microceph/version.version=$(MC_VERSION)'" + .PHONY: default default: build # Build targets. .PHONY: build build: - go install -v ./cmd/microceph - go install -v ./cmd/microcephd + go install -v -ldflags $(LDFLAGS) ./cmd/microceph + go install -v -ldflags $(LDFLAGS) ./cmd/microcephd # Testing targets. .PHONY: check diff --git a/microceph/api/client_configs.go b/microceph/api/client_configs.go index b7503a54..8f061580 100644 --- a/microceph/api/client_configs.go +++ b/microceph/api/client_configs.go @@ -16,8 +16,8 @@ import ( "github.com/canonical/microceph/microceph/ceph" "github.com/canonical/microceph/microceph/client" "github.com/canonical/microceph/microceph/database" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" ) // Top level client API @@ -33,7 +33,7 @@ var clientConfigsCmd = rest.Endpoint{ } // cmdClientConfigsGet fetches multiple client config key entries from internal database. -func cmdClientConfigsGet(s *state.State, r *http.Request) response.Response { +func cmdClientConfigsGet(s state.State, r *http.Request) response.Response { var req types.ClientConfig var configs database.ClientConfigItems @@ -43,9 +43,9 @@ func cmdClientConfigsGet(s *state.State, r *http.Request) response.Response { } if req.Host == constants.ClientConfigGlobalHostConst { - configs, err = database.ClientConfigQuery.GetAll(s) + configs, err = database.ClientConfigQuery.GetAll(r.Context(), s) } else { - configs, err = database.ClientConfigQuery.GetAllForHost(s, req.Host) + configs, err = database.ClientConfigQuery.GetAllForHost(r.Context(), s, req.Host) } if err != nil { logger.Errorf("failed fetching client configs: %v for %v", err, req) @@ -58,9 +58,9 @@ func cmdClientConfigsGet(s *state.State, r *http.Request) response.Response { } // cmdClientConfigsPut renders .conf file at that particular host. -func cmdClientConfigsPut(s *state.State, r *http.Request) response.Response { +func cmdClientConfigsPut(s state.State, r *http.Request) response.Response { // Check if microceph is bootstrapped. - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.Database().Transaction(r.Context(), func(ctx context.Context, tx *sql.Tx) error { isFsid, err := database.ConfigItemExists(ctx, tx, "fsid") if err != nil || !isFsid { return fmt.Errorf("client configuration cannot be performed before bootstrapping the cluster") @@ -72,7 +72,7 @@ func cmdClientConfigsPut(s *state.State, r *http.Request) response.Response { return response.BadRequest(err) } - err = ceph.UpdateConfig(interfaces.CephState{State: s}) + err = ceph.UpdateConfig(r.Context(), interfaces.CephState{State: s}) if err != nil { logger.Error(err.Error()) response.InternalError(err) @@ -90,7 +90,7 @@ var clientConfigsKeyCmd = rest.Endpoint{ } // clientConfigsKeyGet fetches particular client config key entries from internal db. -func clientConfigsKeyGet(s *state.State, r *http.Request) response.Response { +func clientConfigsKeyGet(s state.State, r *http.Request) response.Response { var req types.ClientConfig var configs database.ClientConfigItems @@ -100,9 +100,9 @@ func clientConfigsKeyGet(s *state.State, r *http.Request) response.Response { } if req.Host == constants.ClientConfigGlobalHostConst { - configs, err = database.ClientConfigQuery.GetAllForKey(s, req.Key) + configs, err = database.ClientConfigQuery.GetAllForKey(r.Context(), s, req.Key) } else { - configs, err = database.ClientConfigQuery.GetAllForKeyAndHost(s, req.Key, req.Host) + configs, err = database.ClientConfigQuery.GetAllForKeyAndHost(r.Context(), s, req.Key, req.Host) } if err != nil { logger.Errorf("failed fetching client configs: %v for %v", err, req) @@ -115,7 +115,7 @@ func clientConfigsKeyGet(s *state.State, r *http.Request) response.Response { } // clientConfigsKeyPut sets particular client config key. -func clientConfigsKeyPut(s *state.State, r *http.Request) response.Response { +func clientConfigsKeyPut(s state.State, r *http.Request) response.Response { var req types.ClientConfig err := json.NewDecoder(r.Body).Decode(&req) @@ -124,19 +124,19 @@ func clientConfigsKeyPut(s *state.State, r *http.Request) response.Response { } // If new config request is for global configuration. - err = database.ClientConfigQuery.AddNew(s, req.Key, req.Value, req.Host) + err = database.ClientConfigQuery.AddNew(r.Context(), s, req.Key, req.Value, req.Host) if err != nil { return response.InternalError(err) } // Trigger /conf file update across cluster. - clientConfigUpdate(s, req.Wait) + clientConfigUpdate(r.Context(), s, req.Wait) return response.EmptySyncResponse } // clientConfigsKeyDelete removes particular client config key entries from internal db. -func clientConfigsKeyDelete(s *state.State, r *http.Request) response.Response { +func clientConfigsKeyDelete(s state.State, r *http.Request) response.Response { var req types.ClientConfig err := json.NewDecoder(r.Body).Decode(&req) @@ -145,38 +145,38 @@ func clientConfigsKeyDelete(s *state.State, r *http.Request) response.Response { } if req.Host == constants.ClientConfigGlobalHostConst { - err = database.ClientConfigQuery.RemoveAllForKey(s, req.Key) + err = database.ClientConfigQuery.RemoveAllForKey(r.Context(), s, req.Key) } else { - err = database.ClientConfigQuery.RemoveOneForKeyAndHost(s, req.Key, req.Host) + err = database.ClientConfigQuery.RemoveOneForKeyAndHost(r.Context(), s, req.Key, req.Host) } if err != nil { return response.InternalError(err) } // Trigger /conf file update across cluster. - clientConfigUpdate(s, req.Wait) + clientConfigUpdate(r.Context(), s, req.Wait) return response.EmptySyncResponse } // clientConfigUpdate performs ordered (one after other) updation of ceph.conf across the ceph cluster. -func clientConfigUpdate(s *state.State, wait bool) error { +func clientConfigUpdate(ctx context.Context, s state.State, wait bool) error { if wait { // Execute update conf synchronously - err := client.SendUpdateClientConfRequestToClusterMembers(interfaces.CephState{State: s}) + err := client.SendUpdateClientConfRequestToClusterMembers(ctx, interfaces.CephState{State: s}) if err != nil { return err } // Update on current host. - err = ceph.UpdateConfig(interfaces.CephState{State: s}) + err = ceph.UpdateConfig(ctx, interfaces.CephState{State: s}) if err != nil { return err } } else { // Execute update asynchronously go func() { - client.SendUpdateClientConfRequestToClusterMembers(interfaces.CephState{State: s}) - ceph.UpdateConfig(interfaces.CephState{State: s}) // Restart on current host. + client.SendUpdateClientConfRequestToClusterMembers(context.Background(), interfaces.CephState{State: s}) + ceph.UpdateConfig(context.Background(), interfaces.CephState{State: s}) // Restart on current host. }() } diff --git a/microceph/api/configs.go b/microceph/api/configs.go index c5673503..7f31c0ee 100644 --- a/microceph/api/configs.go +++ b/microceph/api/configs.go @@ -1,12 +1,13 @@ package api import ( + "context" "encoding/json" "net/http" "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/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/ceph" @@ -23,7 +24,7 @@ var configsCmd = rest.Endpoint{ Delete: rest.EndpointAction{Handler: cmdConfigsDelete, ProxyTarget: true}, } -func cmdConfigsGet(s *state.State, r *http.Request) response.Response { +func cmdConfigsGet(s state.State, r *http.Request) response.Response { var err error var req types.Config var configs types.Configs @@ -47,7 +48,7 @@ func cmdConfigsGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, configs) } -func cmdConfigsPut(s *state.State, r *http.Request) response.Response { +func cmdConfigsPut(s state.State, r *http.Request) response.Response { var req types.Config configTable := ceph.GetConstConfigTable() @@ -64,13 +65,13 @@ func cmdConfigsPut(s *state.State, r *http.Request) response.Response { if !req.SkipRestart { services := configTable[req.Key].Daemons - configChangeRefresh(s, services, req.Wait) + configChangeRefresh(r.Context(), s, services, req.Wait) } return response.EmptySyncResponse } -func cmdConfigsDelete(s *state.State, r *http.Request) response.Response { +func cmdConfigsDelete(s state.State, r *http.Request) response.Response { var req types.Config configTable := ceph.GetConstConfigTable() @@ -87,30 +88,30 @@ func cmdConfigsDelete(s *state.State, r *http.Request) response.Response { if !req.SkipRestart { services := configTable[req.Key].Daemons - configChangeRefresh(s, services, req.Wait) + configChangeRefresh(r.Context(), s, services, req.Wait) } return response.EmptySyncResponse } // Perform ordered (one after other) restart of provided Ceph services across the ceph cluster. -func configChangeRefresh(s *state.State, services []string, wait bool) error { +func configChangeRefresh(ctx context.Context, s state.State, services []string, wait bool) error { if wait { // Execute restart synchronously - err := client.SendRestartRequestToClusterMembers(s, services) + err := client.SendRestartRequestToClusterMembers(ctx, s, services) if err != nil { return err } // Restart on current host. - err = ceph.RestartCephServices(interfaces.CephState{State: s}, services) + err = ceph.RestartCephServices(ctx, interfaces.CephState{State: s}, services) if err != nil { return err } } else { // Execute restart asynchronously go func() { - client.SendRestartRequestToClusterMembers(s, services) - ceph.RestartCephServices(interfaces.CephState{State: s}, services) // Restart on current host. + client.SendRestartRequestToClusterMembers(context.Background(), s, services) + ceph.RestartCephServices(context.Background(), interfaces.CephState{State: s}, services) // Restart on current host. }() } diff --git a/microceph/api/disks.go b/microceph/api/disks.go index c5ce6166..da644608 100644 --- a/microceph/api/disks.go +++ b/microceph/api/disks.go @@ -17,8 +17,8 @@ import ( "github.com/tidwall/sjson" "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/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/ceph" @@ -41,8 +41,8 @@ var disksDelCmd = rest.Endpoint{ var mu sync.Mutex -func cmdDisksGet(s *state.State, r *http.Request) response.Response { - disks, err := ceph.ListOSD(s) +func cmdDisksGet(s state.State, r *http.Request) response.Response { + disks, err := ceph.ListOSD(r.Context(), s) if err != nil { return response.InternalError(err) } @@ -50,7 +50,7 @@ func cmdDisksGet(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, disks) } -func cmdDisksPost(s *state.State, r *http.Request) response.Response { +func cmdDisksPost(s state.State, r *http.Request) response.Response { var req types.DisksPost var wal *types.DiskParameter var db *types.DiskParameter @@ -88,7 +88,7 @@ func cmdDisksPost(s *state.State, r *http.Request) response.Response { db = &types.DiskParameter{Path: *req.DBDev, Encrypt: req.DBEncrypt, Wipe: req.DBWipe, LoopSize: 0} } - resp := ceph.AddBulkDisks(s, disks, wal, db) + resp := ceph.AddBulkDisks(r.Context(), s, disks, wal, db) if len(resp.ValidationError) == 0 { response.SyncResponse(false, resp) } @@ -97,7 +97,7 @@ func cmdDisksPost(s *state.State, r *http.Request) response.Response { } // cmdDisksDelete is the handler for DELETE /1.0/disks/{osdid}. -func cmdDisksDelete(s *state.State, r *http.Request) response.Response { +func cmdDisksDelete(s state.State, r *http.Request) response.Response { var osd string osd, err := url.PathUnescape(mux.Vars(r)["osdid"]) if err != nil { @@ -122,7 +122,7 @@ func cmdDisksDelete(s *state.State, r *http.Request) response.Response { // if check for crush rule scaledown only if crush change is not prohibited. if !req.ProhibitCrushScaledown { - needDowngrade, err := ceph.IsDowngradeNeeded(cs, osdid) + needDowngrade, err := ceph.IsDowngradeNeeded(r.Context(), cs, osdid) if err != nil { return response.InternalError(err) } @@ -137,7 +137,7 @@ func cmdDisksDelete(s *state.State, r *http.Request) response.Response { } } - err = ceph.RemoveOSD(cs, osdid, req.BypassSafety, req.Timeout) + err = ceph.RemoveOSD(r.Context(), cs, osdid, req.BypassSafety, req.Timeout) if err != nil { return response.SmartError(err) } diff --git a/microceph/api/microceph_configs.go b/microceph/api/microceph_configs.go index 53929179..4e3801ce 100644 --- a/microceph/api/microceph_configs.go +++ b/microceph/api/microceph_configs.go @@ -8,8 +8,8 @@ import ( "github.com/canonical/lxd/shared/logger" "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/ceph" - "github.com/canonical/microcluster/rest" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/rest" + "github.com/canonical/microcluster/v2/state" ) // top level microceph API @@ -28,7 +28,7 @@ var logLevelCmd = rest.Endpoint{ Get: rest.EndpointAction{Handler: logLevelGet, ProxyTarget: true}, } -func logLevelPut(s *state.State, r *http.Request) response.Response { +func logLevelPut(s state.State, r *http.Request) response.Response { var req types.LogLevelPut err := json.NewDecoder(r.Body).Decode(&req) @@ -46,6 +46,6 @@ func logLevelPut(s *state.State, r *http.Request) response.Response { return response.EmptySyncResponse } -func logLevelGet(s *state.State, r *http.Request) response.Response { +func logLevelGet(s state.State, r *http.Request) response.Response { return response.SyncResponse(true, ceph.GetLogLevel()) } diff --git a/microceph/api/pool.go b/microceph/api/pool.go index 8a6fd302..a98cdca2 100644 --- a/microceph/api/pool.go +++ b/microceph/api/pool.go @@ -7,8 +7,8 @@ import ( "github.com/canonical/lxd/shared/logger" "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/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/ceph" @@ -20,7 +20,7 @@ var poolsCmd = rest.Endpoint{ Put: rest.EndpointAction{Handler: cmdPoolsPut, ProxyTarget: true}, } -func cmdPoolsPut(s *state.State, r *http.Request) response.Response { +func cmdPoolsPut(s state.State, r *http.Request) response.Response { var req types.PoolPut err := json.NewDecoder(r.Body).Decode(&req) diff --git a/microceph/api/resources.go b/microceph/api/resources.go index 29e4b5ae..f8d5a889 100644 --- a/microceph/api/resources.go +++ b/microceph/api/resources.go @@ -5,8 +5,8 @@ import ( "github.com/canonical/lxd/lxd/resources" "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" ) // /1.0/resources endpoint. @@ -16,7 +16,7 @@ var resourcesCmd = rest.Endpoint{ Get: rest.EndpointAction{Handler: cmdResourcesGet, ProxyTarget: true}, } -func cmdResourcesGet(s *state.State, r *http.Request) response.Response { +func cmdResourcesGet(s state.State, r *http.Request) response.Response { storage, err := resources.GetStorage() if err != nil { return response.InternalError(err) diff --git a/microceph/api/servers.go b/microceph/api/servers.go index 2a5b1a87..b943eefc 100644 --- a/microceph/api/servers.go +++ b/microceph/api/servers.go @@ -1,13 +1,13 @@ package api import ( - "github.com/canonical/microcluster/rest" + "github.com/canonical/microcluster/v2/rest" "github.com/canonical/microceph/microceph/api/types" ) -var Servers = []rest.Server{ - { +var Servers = map[string]rest.Server{ + "microceph": { CoreAPI: true, ServeUnix: true, Resources: []rest.Resources{ diff --git a/microceph/api/services.go b/microceph/api/services.go index a83b699d..3c0c270c 100644 --- a/microceph/api/services.go +++ b/microceph/api/services.go @@ -11,8 +11,8 @@ import ( "github.com/canonical/lxd/lxd/response" "github.com/canonical/lxd/shared/logger" "github.com/canonical/microceph/microceph/api/types" - "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/microceph/microceph/ceph" ) @@ -24,8 +24,8 @@ var servicesCmd = rest.Endpoint{ Get: rest.EndpointAction{Handler: cmdServicesGet, ProxyTarget: true}, } -func cmdServicesGet(s *state.State, r *http.Request) response.Response { - services, err := ceph.ListServices(s) +func cmdServicesGet(s state.State, r *http.Request) response.Response { + services, err := ceph.ListServices(r.Context(), s) if err != nil { return response.InternalError(err) } @@ -55,7 +55,7 @@ var rgwServiceCmd = rest.Endpoint{ Delete: rest.EndpointAction{Handler: cmdRGWServiceDelete, ProxyTarget: true}, } -func cmdEnableServicePut(s *state.State, r *http.Request) response.Response { +func cmdEnableServicePut(s state.State, r *http.Request) response.Response { var payload types.EnableService err := json.NewDecoder(r.Body).Decode(&payload) @@ -64,7 +64,7 @@ func cmdEnableServicePut(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err = ceph.ServicePlacementHandler(interfaces.CephState{State: s}, payload) + err = ceph.ServicePlacementHandler(r.Context(), interfaces.CephState{State: s}, payload) if err != nil { return response.SyncResponse(false, err) } @@ -78,7 +78,7 @@ var restartServiceCmd = rest.Endpoint{ Post: rest.EndpointAction{Handler: cmdRestartServicePost, ProxyTarget: true}, } -func cmdRestartServicePost(s *state.State, r *http.Request) response.Response { +func cmdRestartServicePost(s state.State, r *http.Request) response.Response { var services types.Services err := json.NewDecoder(r.Body).Decode(&services) @@ -97,7 +97,7 @@ func cmdRestartServicePost(s *state.State, r *http.Request) response.Response { } } - clusterServices, err := ceph.ListServices(s) + clusterServices, err := ceph.ListServices(r.Context(), s) if err != nil { logger.Errorf("failed fetching services from db: %v", err) return response.SyncResponse(false, err) @@ -116,7 +116,7 @@ func cmdRestartServicePost(s *state.State, r *http.Request) response.Response { } // cmdDeleteService handles service deletion. -func cmdDeleteService(s *state.State, r *http.Request) response.Response { +func cmdDeleteService(s state.State, r *http.Request) response.Response { which := path.Base(r.URL.Path) _, ok := ceph.GetConfigTableServiceSet()[which] if !ok { @@ -125,7 +125,7 @@ func cmdDeleteService(s *state.State, r *http.Request) response.Response { return response.InternalError(err) } - err := ceph.DeleteService(interfaces.CephState{State: s}, which) + err := ceph.DeleteService(r.Context(), interfaces.CephState{State: s}, which) if err != nil { return response.SyncResponse(false, err) } @@ -133,8 +133,8 @@ func cmdDeleteService(s *state.State, r *http.Request) response.Response { return response.SyncResponse(true, nil) } -func cmdRGWServiceDelete(s *state.State, r *http.Request) response.Response { - err := ceph.DisableRGW(interfaces.CephState{State: s}) +func cmdRGWServiceDelete(s state.State, r *http.Request) response.Response { + err := ceph.DisableRGW(r.Context(), interfaces.CephState{State: s}) if err != nil { logger.Errorf("Failed disabling RGW: %v", err) return response.SmartError(err) diff --git a/microceph/api/types/endpoint_prefix.go b/microceph/api/types/endpoint_prefix.go index 9073bb45..c1836f25 100644 --- a/microceph/api/types/endpoint_prefix.go +++ b/microceph/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/microceph/ceph/bootstrap.go b/microceph/ceph/bootstrap.go index 204ca11a..2b583006 100644 --- a/microceph/ceph/bootstrap.go +++ b/microceph/ceph/bootstrap.go @@ -5,12 +5,13 @@ import ( "context" "database/sql" "fmt" - "github.com/canonical/microceph/microceph/constants" - "github.com/canonical/microceph/microceph/interfaces" "os" "path/filepath" "strings" + "github.com/canonical/microceph/microceph/constants" + "github.com/canonical/microceph/microceph/interfaces" + "github.com/pborman/uuid" apiTypes "github.com/canonical/microceph/microceph/api/types" @@ -19,7 +20,7 @@ import ( ) // Bootstrap will initialize a new Ceph deployment. -func Bootstrap(s interfaces.StateInterface, data common.BootstrapConfig) error { +func Bootstrap(ctx context.Context, s interfaces.StateInterface, data common.BootstrapConfig) error { pathConsts := constants.GetPathConst() pathFileMode := constants.GetPathFileMode() @@ -98,7 +99,7 @@ func Bootstrap(s interfaces.StateInterface, data common.BootstrapConfig) error { } // Update the database. - err = populateDatabase(s, fsid, adminKey, data) + err = populateDatabase(ctx, s, fsid, adminKey, data) if err != nil { return err } @@ -121,7 +122,7 @@ func Bootstrap(s interfaces.StateInterface, data common.BootstrapConfig) error { } // Re-generate the configuration from the database. - err = UpdateConfig(s) + err = UpdateConfig(ctx, s) if err != nil { return fmt.Errorf("failed to re-generate the configuration: %w", err) } @@ -265,11 +266,12 @@ func initMgr(s interfaces.StateInterface, dataPath string) error { } // populateDatabase injects the bootstrap entries to the internal database. -func populateDatabase(s interfaces.StateInterface, fsid string, adminKey string, data common.BootstrapConfig) error { - if s.ClusterState().Database == nil { - return fmt.Errorf("no database") +func populateDatabase(ctx context.Context, s interfaces.StateInterface, fsid string, adminKey string, data common.BootstrapConfig) error { + if s.ClusterState().ServerCert() == nil { + return fmt.Errorf("no server certificate") } - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { // Record the roles. _, err := database.CreateService(ctx, tx, database.Service{Member: s.ClusterState().Name(), Service: "mon"}) if err != nil { diff --git a/microceph/ceph/bootstrap_test.go b/microceph/ceph/bootstrap_test.go index 569f7731..1f87d025 100644 --- a/microceph/ceph/bootstrap_test.go +++ b/microceph/ceph/bootstrap_test.go @@ -1,14 +1,15 @@ package ceph import ( + "context" + "testing" + "github.com/canonical/microceph/microceph/interfaces" "github.com/canonical/microceph/microceph/tests" - "testing" "github.com/canonical/lxd/shared/api" "github.com/canonical/microceph/microceph/common" "github.com/canonical/microceph/microceph/mocks" - "github.com/canonical/microcluster/state" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" @@ -81,14 +82,9 @@ func (s *bootstrapSuite) SetupTest() { s.TestStateInterface = mocks.NewStateInterface(s.T()) u := api.NewURL() - state := &state.State{ - Address: func() *api.URL { - return u - }, - Name: func() string { - return "foohost" - }, - Database: nil, + state := &mocks.MockState{ + URL: u, + ClusterName: "foohost", } s.TestStateInterface.On("ClusterState").Return(state).Maybe() } @@ -109,10 +105,10 @@ func (s *bootstrapSuite) TestBootstrap() { processExec = r common.Network = nw - err := Bootstrap(s.TestStateInterface, common.BootstrapConfig{MonIp: "1.1.1.1", PublicNet: "1.1.1.1/24"}) + err := Bootstrap(context.Background(), s.TestStateInterface, common.BootstrapConfig{MonIp: "1.1.1.1", PublicNet: "1.1.1.1/24"}) // we expect a missing database error - assert.EqualError(s.T(), err, "no database") + assert.EqualError(s.T(), err, "no server certificate") } diff --git a/microceph/ceph/client_config.go b/microceph/ceph/client_config.go index 33e5c19b..5e5d7c23 100644 --- a/microceph/ceph/client_config.go +++ b/microceph/ceph/client_config.go @@ -1,10 +1,12 @@ package ceph import ( + "context" "fmt" - "github.com/canonical/microceph/microceph/interfaces" "reflect" + "github.com/canonical/microceph/microceph/interfaces" + "github.com/canonical/microceph/microceph/common" "github.com/canonical/microceph/microceph/database" ) @@ -22,11 +24,11 @@ type ClientConfigT struct { } // GetClientConfigForHost fetches all the applicable client configurations for the provided host. -func GetClientConfigForHost(s interfaces.StateInterface, hostname string) (ClientConfigT, error) { +func GetClientConfigForHost(ctx context.Context, s interfaces.StateInterface, hostname string) (ClientConfigT, error) { retval := ClientConfigT{} // Get all client configs for the current host. - configs, err := database.ClientConfigQuery.GetAllForHost(s.ClusterState(), hostname) + configs, err := database.ClientConfigQuery.GetAllForHost(ctx, s.ClusterState(), hostname) if err != nil { return ClientConfigT{}, fmt.Errorf("could not query database for client configs: %v", err) } diff --git a/microceph/ceph/client_config_test.go b/microceph/ceph/client_config_test.go index ee8fd718..dfe76761 100644 --- a/microceph/ceph/client_config_test.go +++ b/microceph/ceph/client_config_test.go @@ -1,14 +1,17 @@ package ceph import ( + "context" "fmt" - "github.com/canonical/microceph/microceph/tests" "reflect" "testing" + "github.com/canonical/lxd/shared/api" + "github.com/canonical/microceph/microceph/tests" + "github.com/canonical/microcluster/v2/state" + "github.com/canonical/microceph/microceph/database" "github.com/canonical/microceph/microceph/mocks" - "github.com/canonical/microcluster/state" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) @@ -26,12 +29,16 @@ func (ccs *ClientConfigSuite) SetupTest() { ccs.BaseSuite.SetupTest() ccs.TestStateInterface = mocks.NewStateInterface(ccs.T()) - state := &state.State{} + u := api.NewURL() + state := &mocks.MockState{ + URL: u, + ClusterName: "foohost", + } ccs.TestStateInterface.On("ClusterState").Return(state) } -func addGetHostConfigsExpectation(mci *mocks.ClientConfigQueryIntf, cs *state.State, hostname string) { +func addGetHostConfigsExpectation(mci *mocks.ClientConfigQueryIntf, cs state.State, hostname string) { output := database.ClientConfigItems{} count := 0 for configKey, field := range GetClientConfigSet() { @@ -55,7 +62,7 @@ func (ccs *ClientConfigSuite) TestFetchHostConfig() { addGetHostConfigsExpectation(ccq, ccs.TestStateInterface.ClusterState(), hostname) database.ClientConfigQuery = ccq - configs, err := GetClientConfigForHost(ccs.TestStateInterface, hostname) + configs, err := GetClientConfigForHost(context.Background(), ccs.TestStateInterface, hostname) assert.NoError(ccs.T(), err) // check fields diff --git a/microceph/ceph/config.go b/microceph/ceph/config.go index 3513dd3b..241fd16d 100644 --- a/microceph/ceph/config.go +++ b/microceph/ceph/config.go @@ -191,8 +191,8 @@ func ListConfigs() (types.Configs, error) { // backwardCompatPubnet ensures that the public_network is set in the database // this is a backward-compat shim to accomodate older versions of microceph // which will ensure that the public_network is set in the database -func backwardCompatPubnet(s interfaces.StateInterface) error { - config, err := getConfigDb(s) +func backwardCompatPubnet(ctx context.Context, s interfaces.StateInterface) error { + config, err := getConfigDb(ctx, s) if err != nil { return fmt.Errorf("failed to get config from db: %w", err) } @@ -209,7 +209,7 @@ func backwardCompatPubnet(s interfaces.StateInterface) error { return fmt.Errorf("failed to locate public network: %w", err) } // update the database - err = s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { _, err = database.CreateConfigItem(ctx, tx, database.ConfigItem{Key: "public_network", Value: pubNet}) if err != nil { return fmt.Errorf("failed to record public_network: %w", err) @@ -223,12 +223,12 @@ func backwardCompatPubnet(s interfaces.StateInterface) error { // backwardCompatMonitors retrieves monitor addresses from the node list and returns that // this a backward-compat shim to accomodate older versions of microceph -func backwardCompatMonitors(s interfaces.StateInterface) ([]string, error) { +func backwardCompatMonitors(ctx context.Context, s interfaces.StateInterface) ([]string, error) { var err error var monitors []database.Service serviceName := "mon" - err = s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { monitors, err = database.GetServices(ctx, tx, database.ServiceFilter{Service: &serviceName}) if err != nil { return err @@ -252,16 +252,16 @@ func backwardCompatMonitors(s interfaces.StateInterface) ([]string, error) { } // UpdateConfig updates the ceph.conf file with the current configuration. -func UpdateConfig(s interfaces.StateInterface) error { +func UpdateConfig(ctx context.Context, s interfaces.StateInterface) error { confPath := filepath.Join(os.Getenv("SNAP_DATA"), "conf") runPath := filepath.Join(filepath.Dir(os.Getenv("SNAP_DATA")), "current", "run") - err := backwardCompatPubnet(s) + err := backwardCompatPubnet(ctx, s) if err != nil { return fmt.Errorf("failed to ensure backward compat: %w", err) } - config, err := getConfigDb(s) + config, err := getConfigDb(ctx, s) if err != nil { return fmt.Errorf("failed to get config db: %w", err) } @@ -274,7 +274,7 @@ func UpdateConfig(s interfaces.StateInterface) error { // backward compat: if no mon hosts found, get them from the node addresses but don't // insert into db, as the join logic will take care of that. if len(monitorAddresses) == 0 { - monitorAddresses, err = backwardCompatMonitors(s) + monitorAddresses, err = backwardCompatMonitors(ctx, s) if err != nil { return fmt.Errorf("failed to get monitor addresses: %w", err) } @@ -288,7 +288,7 @@ func UpdateConfig(s interfaces.StateInterface) error { return fmt.Errorf("failed to locate IP on public network %s: %w", config["public_network"], err) } - clientConfig, err := GetClientConfigForHost(s, s.ClusterState().Name()) + clientConfig, err := GetClientConfigForHost(ctx, s, s.ClusterState().Name()) if err != nil { logger.Errorf("Failed to pull Client Configurations: %v", err) return err @@ -333,11 +333,11 @@ func UpdateConfig(s interfaces.StateInterface) error { } // getConfigDb retrieves the configuration from the database. -func getConfigDb(s interfaces.StateInterface) (map[string]string, error) { +func getConfigDb(ctx context.Context, s interfaces.StateInterface) (map[string]string, error) { var err error var configItems []database.ConfigItem - err = s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { configItems, err = database.GetConfigItems(ctx, tx) if err != nil { return err diff --git a/microceph/ceph/join.go b/microceph/ceph/join.go index 1a80c2ce..f0da4236 100644 --- a/microceph/ceph/join.go +++ b/microceph/ceph/join.go @@ -15,7 +15,7 @@ import ( ) // Join will join an existing Ceph deployment. -func Join(s interfaces.StateInterface) error { +func Join(ctx context.Context, s interfaces.StateInterface) error { pathFileMode := constants.GetPathFileMode() var spt = GetServicePlacementTable() @@ -28,13 +28,13 @@ func Join(s interfaces.StateInterface) error { } // Generate the configuration files from the database. - err := UpdateConfig(s) + err := UpdateConfig(ctx, s) if err != nil { return fmt.Errorf("failed to generate the configuration: %w", err) } // check and create service records if needed to be spawned. - err = s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { autoServices := []string{"mon", "mds", "mgr"} for _, service := range autoServices { err := checkAndCreateServiceRecord(s, ctx, tx, service) @@ -50,14 +50,14 @@ func Join(s interfaces.StateInterface) error { } // Get services recorded for this host. - plannedServices, err := getServicesForHost(s, s.ClusterState().Name()) + plannedServices, err := getServicesForHost(ctx, s, s.ClusterState().Name()) if err != nil { return err } // spawn planned auto services. for _, service := range plannedServices { - err := spt[service.Service].ServiceInit(s) + err := spt[service.Service].ServiceInit(ctx, s) if err != nil { logger.Errorf("%v", err) return err @@ -74,10 +74,10 @@ func Join(s interfaces.StateInterface) error { } // getServicesForHost get services needed to be spawned on this machine. -func getServicesForHost(s interfaces.StateInterface, hostname string) ([]database.Service, error) { +func getServicesForHost(ctx context.Context, s interfaces.StateInterface, hostname string) ([]database.Service, error) { hostname = s.ClusterState().Name() var services []database.Service - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { var err error services, err = database.GetServices(ctx, tx, database.ServiceFilter{Member: &hostname}) if err != nil { diff --git a/microceph/ceph/osd.go b/microceph/ceph/osd.go index 9d1640ef..c42a0087 100644 --- a/microceph/ceph/osd.go +++ b/microceph/ceph/osd.go @@ -27,7 +27,7 @@ import ( "github.com/canonical/lxd/lxd/resources" "github.com/canonical/lxd/shared" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/pborman/uuid" "github.com/canonical/microceph/microceph/api/types" @@ -230,8 +230,8 @@ func switchFailureDomain(old string, new string) error { // updateFailureDomain checks if we need to update the crush rules failure domain. // Once we have at least 3 nodes with at least 1 OSD each, we set the failure domain to host. // Currently this function only handles scale-up scenarios, i.e. adding a new node. -func updateFailureDomain(s *state.State) error { - numNodes, err := database.MemberCounter.Count(s) +func updateFailureDomain(ctx context.Context, s state.State) error { + numNodes, err := database.MemberCounter.Count(ctx, s) if err != nil { return fmt.Errorf("failed to count members: %w", err) } @@ -363,7 +363,7 @@ func createBackingFile(dir string, size uint64) (string, error) { } // AddLoopBackOSDs adds OSDs to the cluster backed by loopback files -func AddLoopBackOSDs(s *state.State, spec string) error { +func AddLoopBackOSDs(ctx context.Context, s state.State, spec string) error { size, num, err := parseBackingSpec(spec) if err != nil { return err @@ -378,7 +378,7 @@ func AddLoopBackOSDs(s *state.State, spec string) error { } // create backing files in a loop and add them to the cluster for i := 0; i < num; i++ { - err = AddOSD(s, types.DiskParameter{LoopSize: size}, nil, nil) + err = AddOSD(ctx, s, types.DiskParameter{LoopSize: size}, nil, nil) if err != nil { return fmt.Errorf("failed to add loop OSD: %w", err) } @@ -465,12 +465,12 @@ func prepareValidationFailureResp(disks []types.DiskParameter, err error) types. } // AddBulkDisks adds multiple disks as OSDs and generates the API response for request. -func AddBulkDisks(s *state.State, disks []types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) types.DiskAddResponse { +func AddBulkDisks(ctx context.Context, s state.State, disks []types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) types.DiskAddResponse { ret := types.DiskAddResponse{} if len(disks) == 1 { // Add single disk with requested WAL/DB devices. - resp := AddSingleDisk(s, disks[0], wal, db) + resp := AddSingleDisk(ctx, s, disks[0], wal, db) ret.Reports = append(ret.Reports, resp) ret.ValidationError = "" // Validation is done for batch requests. return ret @@ -487,7 +487,7 @@ func AddBulkDisks(s *state.State, disks []types.DiskParameter, wal *types.DiskPa // Add all requested disks. for _, disk := range disks { - resp := AddSingleDisk(s, disk, nil, nil) + resp := AddSingleDisk(ctx, s, disk, nil, nil) ret.Reports = append(ret.Reports, resp) } @@ -495,17 +495,17 @@ func AddBulkDisks(s *state.State, disks []types.DiskParameter, wal *types.DiskPa } // AddSingleDisk is a wrapper around AddOSD which logs disk addition failures and returns a formatted response. -func AddSingleDisk(s *state.State, disk types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) types.DiskAddReport { +func AddSingleDisk(ctx context.Context, s state.State, disk types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) types.DiskAddReport { if strings.Contains(disk.Path, constants.LoopSpecId) { // Add file based OSDs. - err := AddLoopBackOSDs(s, disk.Path) + err := AddLoopBackOSDs(ctx, s, disk.Path) if err != nil { logger.Errorf("failed to add disk: spec %s, err %v", disk.Path, err) return types.DiskAddReport{Path: disk.Path, Report: "Failure", Error: err.Error()} } } else { // Add physical disk based OSD. - err := AddOSD(s, disk, wal, db) + err := AddOSD(ctx, s, disk, wal, db) if err != nil { logger.Errorf("failed to add disk: path %s, err %v", disk.Path, err) // return failure as response. @@ -519,7 +519,7 @@ func AddSingleDisk(s *state.State, disk types.DiskParameter, wal *types.DiskPara // AddOSD adds an OSD to the cluster, given the data, WAL and DB devices and their respective // flags for wiping and encrypting. -func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) error { +func AddOSD(ctx context.Context, s state.State, data types.DiskParameter, wal *types.DiskParameter, db *types.DiskParameter) error { logger.Debugf("Adding OSD %s", data.Path) var err error @@ -548,7 +548,7 @@ func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, // Record the disk. var nr int64 - 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 { nr, err = database.CreateDisk(ctx, tx, database.Disk{Member: s.Name(), Path: data.Path}) if err != nil { return fmt.Errorf("failed to record disk: %w", err) @@ -566,7 +566,7 @@ func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, // if we fail later, make sure we free up the record revert.Add(func() { os.RemoveAll(osdDataPath) - s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { + s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { database.DeleteDisk(ctx, tx, s.Name(), data.Path) return nil }) @@ -586,8 +586,8 @@ func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, } data.Path = backing // update db, it didn't have a path before - err = s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { - err = database.OSDQuery.UpdatePath(s, nr, backing) + err = s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { + err = database.OSDQuery.UpdatePath(ctx, s, nr, backing) if err != nil { return fmt.Errorf("failed to update disk record: %w", err) } @@ -630,7 +630,7 @@ func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, } // Maybe update the failure domain - err = updateFailureDomain(s) + err = updateFailureDomain(ctx, s) if err != nil { return err } @@ -641,12 +641,12 @@ func AddOSD(s *state.State, data types.DiskParameter, wal *types.DiskParameter, } // ListOSD lists current OSD disks -func ListOSD(s *state.State) (types.Disks, error) { - return database.OSDQuery.List(s) +func ListOSD(ctx context.Context, s state.State) (types.Disks, error) { + return database.OSDQuery.List(ctx, s) } // RemoveOSD removes an OSD disk -func RemoveOSD(s interfaces.StateInterface, osd int64, bypassSafety bool, timeout int64) error { +func RemoveOSD(ctx context.Context, s interfaces.StateInterface, osd int64, bypassSafety bool, timeout int64) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(timeout)) defer cancel() err := doRemoveOSD(ctx, s, osd, bypassSafety) @@ -662,14 +662,14 @@ func RemoveOSD(s interfaces.StateInterface, osd int64, bypassSafety bool, timeou } // sanityCheck checks if input is valid -func sanityCheck(s interfaces.StateInterface, osd int64) error { +func sanityCheck(ctx context.Context, s interfaces.StateInterface, osd int64) error { // check osd is positive if osd < 0 { return fmt.Errorf("OSD must be a positive integer") } // check if the OSD exists in the database - exists, err := database.OSDQuery.HaveOSD(s.ClusterState(), osd) + exists, err := database.OSDQuery.HaveOSD(ctx, s.ClusterState(), osd) if err != nil { return err } @@ -681,7 +681,7 @@ func sanityCheck(s interfaces.StateInterface, osd int64) error { // IsDowngradeNeeded checks if we need to downgrade the failure domain from 'host' to 'osd' level // if we remove the given OSD -func IsDowngradeNeeded(s interfaces.StateInterface, osd int64) (bool, error) { +func IsDowngradeNeeded(ctx context.Context, s interfaces.StateInterface, osd int64) (bool, error) { currentRule, err := getDefaultCrushRule() if err != nil { return false, err @@ -696,7 +696,7 @@ func IsDowngradeNeeded(s interfaces.StateInterface, osd int64) (bool, error) { logger.Infof("No need to downgrade auto failure domain, current rule is %v", currentRule) return false, nil } - numNodes, err := database.MemberCounter.CountExclude(s.ClusterState(), osd) + numNodes, err := database.MemberCounter.CountExclude(ctx, s.ClusterState(), osd) logger.Infof("Number of nodes excluding osd.%v: %v", osd, numNodes) if err != nil { return false, err @@ -708,8 +708,8 @@ func IsDowngradeNeeded(s interfaces.StateInterface, osd int64) (bool, error) { } // scaleDownFailureDomain scales down the failure domain from 'host' to 'osd' level -func scaleDownFailureDomain(s interfaces.StateInterface, osd int64) error { - needDowngrade, err := IsDowngradeNeeded(s, osd) +func scaleDownFailureDomain(ctx context.Context, s interfaces.StateInterface, osd int64) error { + needDowngrade, err := IsDowngradeNeeded(ctx, s, osd) logger.Debugf("Downgrade needed: %v", needDowngrade) if err != nil { return err @@ -785,7 +785,7 @@ func purgeOSD(osd int64) error { return nil } -func wipeDevice(s interfaces.StateInterface, path string) { +func wipeDevice(ctx context.Context, s interfaces.StateInterface, path string) { var err error // wipe the device, retry with exponential backoff retries := 8 @@ -826,20 +826,20 @@ func doRemoveOSD(ctx context.Context, s interfaces.StateInterface, osd int64, by var err error // general sanity - err = sanityCheck(s, osd) + err = sanityCheck(ctx, s, osd) if err != nil { return err } if !bypassSafety { // check: at least 3 OSDs - err = checkMinOSDs(s, osd) + err = checkMinOSDs(ctx, s, osd) if err != nil { return err } } - err = scaleDownFailureDomain(s, osd) + err = scaleDownFailureDomain(ctx, s, osd) if err != nil { return err } @@ -886,7 +886,7 @@ func doRemoveOSD(ctx context.Context, s interfaces.StateInterface, osd int64, by } } - err = clearStorage(s, osd) + err = clearStorage(ctx, s, osd) if err != nil { // log error but don't fail, we still want to remove the OSD from the cluster logger.Errorf("Failed to clear storage for osd.%d: %v", osd, err) @@ -898,7 +898,7 @@ func doRemoveOSD(ctx context.Context, s interfaces.StateInterface, osd int64, by return err } // Remove db entry - err = database.OSDQuery.Delete(s.ClusterState(), osd) + err = database.OSDQuery.Delete(ctx, s.ClusterState(), osd) if err != nil { logger.Errorf("Failed to remove osd.%d from database: %v", osd, err) return fmt.Errorf("failed to remove osd.%d from database: %w", osd, err) @@ -906,8 +906,8 @@ func doRemoveOSD(ctx context.Context, s interfaces.StateInterface, osd int64, by return nil } -func clearStorage(s interfaces.StateInterface, osd int64) error { - path, err := database.OSDQuery.Path(s.ClusterState(), osd) +func clearStorage(ctx context.Context, s interfaces.StateInterface, osd int64) error { + path, err := database.OSDQuery.Path(ctx, s.ClusterState(), osd) if err != nil { return err } @@ -924,15 +924,15 @@ func clearStorage(s interfaces.StateInterface, osd int64) error { } if fileInfo.Mode()&os.ModeDevice != 0 { // wipe the device - wipeDevice(s, path) + wipeDevice(ctx, s, path) } // backing files etc. are being removed later along with config return nil } -func checkMinOSDs(s interfaces.StateInterface, osd int64) error { +func checkMinOSDs(ctx context.Context, s interfaces.StateInterface, osd int64) error { // check if we have at least 3 OSDs post-removal - disks, err := database.OSDQuery.List(s.ClusterState()) + disks, err := database.OSDQuery.List(ctx, s.ClusterState()) if err != nil { return err } diff --git a/microceph/ceph/osd_test.go b/microceph/ceph/osd_test.go index 87338c82..ecec782c 100644 --- a/microceph/ceph/osd_test.go +++ b/microceph/ceph/osd_test.go @@ -1,13 +1,14 @@ package ceph import ( - "github.com/canonical/microceph/microceph/tests" + "context" "testing" "github.com/canonical/lxd/shared/api" + "github.com/canonical/microceph/microceph/tests" + "github.com/canonical/microceph/microceph/database" "github.com/canonical/microceph/microceph/mocks" - "github.com/canonical/microcluster/state" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" @@ -132,14 +133,9 @@ func (s *osdSuite) TestSwitchHostFailureDomain() { // TestUpdateFailureDomain tests the updateFailureDomain function func (s *osdSuite) TestUpdateFailureDomain() { u := api.NewURL() - state := &state.State{ - Address: func() *api.URL { - return u - }, - Name: func() string { - return "foohost" - }, - Database: nil, + state := &mocks.MockState{ + URL: u, + ClusterName: "foohost", } r := mocks.NewRunner(s.T()) @@ -163,7 +159,9 @@ func (s *osdSuite) TestUpdateFailureDomain() { c.On("Count", mock.Anything).Return(3, nil).Once() database.MemberCounter = c - err := updateFailureDomain(state) + s.TestStateInterface = mocks.NewStateInterface(s.T()) + s.TestStateInterface.On("ClusterState").Return(state).Maybe() + err := updateFailureDomain(context.Background(), s.TestStateInterface.ClusterState()) assert.NoError(s.T(), err) } diff --git a/microceph/ceph/remove.go b/microceph/ceph/remove.go index f1d1e7cb..3eb08e70 100644 --- a/microceph/ceph/remove.go +++ b/microceph/ceph/remove.go @@ -1,19 +1,20 @@ package ceph import ( + "context" "fmt" "github.com/canonical/lxd/shared/logger" - microCli "github.com/canonical/microcluster/client" - "github.com/canonical/microcluster/microcluster" - "github.com/canonical/microcluster/state" + microCli "github.com/canonical/microcluster/v2/client" + "github.com/canonical/microcluster/v2/microcluster" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/microceph/microceph/client" ) // PreRemove cleans up the underlying ceph services before the node is removed from the dqlite cluster. -func PreRemove(m *microcluster.MicroCluster) func(s *state.State, force bool) error { - return func(s *state.State, force bool) error { +func PreRemove(m *microcluster.MicroCluster) func(ctx context.Context, s state.State, force bool) error { + return func(ctx context.Context, s state.State, force bool) error { cli, err := m.LocalClient() if err != nil { return err diff --git a/microceph/ceph/rgw.go b/microceph/ceph/rgw.go index 4dc909e5..11fc05aa 100644 --- a/microceph/ceph/rgw.go +++ b/microceph/ceph/rgw.go @@ -75,7 +75,7 @@ func EnableRGW(s interfaces.StateInterface, port int, sslPort int, sslCertificat } // DisableRGW disables the RGW service on the cluster. -func DisableRGW(s interfaces.StateInterface) error { +func DisableRGW(ctx context.Context, s interfaces.StateInterface) error { pathConsts := constants.GetPathConst() err := stopRGW() @@ -83,7 +83,7 @@ func DisableRGW(s interfaces.StateInterface) error { return fmt.Errorf("Failed to stop RGW service: %w", err) } - err = removeServiceDatabase(s, "rgw") + err = removeServiceDatabase(ctx, s, "rgw") if err != nil { return err } @@ -120,12 +120,12 @@ func DisableRGW(s interfaces.StateInterface) error { } // rgwCreateServiceDatabase creates a rgw service record in the database. -func rgwCreateServiceDatabase(s interfaces.StateInterface) error { - if s.ClusterState().Database == nil { - return fmt.Errorf("no database") +func rgwCreateServiceDatabase(ctx context.Context, s interfaces.StateInterface) error { + if s.ClusterState().ServerCert() == nil { + return fmt.Errorf("no server certificate") } - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { // Create the service. _, err := database.CreateService(ctx, tx, database.Service{Member: s.ClusterState().Name(), Service: "rgw"}) if err != nil { diff --git a/microceph/ceph/rgw_test.go b/microceph/ceph/rgw_test.go index 1d96e317..60f0f778 100644 --- a/microceph/ceph/rgw_test.go +++ b/microceph/ceph/rgw_test.go @@ -1,13 +1,13 @@ package ceph import ( + "context" "os" "path/filepath" "testing" "github.com/canonical/lxd/shared/api" "github.com/canonical/microceph/microceph/tests" - "github.com/canonical/microcluster/state" "github.com/canonical/microceph/microceph/mocks" "github.com/stretchr/testify/assert" @@ -40,14 +40,9 @@ func addRGWEnableExpectations(r *mocks.Runner) { func addStopRGWExpectations(s *rgwSuite, r *mocks.Runner) { u := api.NewURL() - state := &state.State{ - Address: func() *api.URL { - return u - }, - Name: func() string { - return "foohost" - }, - Database: nil, + state := &mocks.MockState{ + URL: u, + ClusterName: "foohost", } s.TestStateInterface.On("ClusterState").Return(state) @@ -172,10 +167,10 @@ func (s *rgwSuite) TestDisableRGW() { processExec = r - err := DisableRGW(s.TestStateInterface) + err := DisableRGW(context.Background(), s.TestStateInterface) // we expect a missing database error - assert.EqualError(s.T(), err, "no database") + assert.EqualError(s.T(), err, "no server certificate") // check that the radosgw.conf file is absent _, err = os.Stat(filepath.Join(s.Tmp, "SNAP_DATA", "conf", "radosgw.conf")) diff --git a/microceph/ceph/service_placement_mon.go b/microceph/ceph/service_placement_mon.go index f01c4ad6..94d3819a 100644 --- a/microceph/ceph/service_placement_mon.go +++ b/microceph/ceph/service_placement_mon.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "github.com/canonical/microceph/microceph/interfaces" "github.com/canonical/microceph/microceph/database" @@ -34,9 +35,9 @@ func (msp *MonServicePlacement) PostPlacementCheck(s interfaces.StateInterface) } // Perform DB updates to persist the service enablement changes. -func (msp *MonServicePlacement) DbUpdate(s interfaces.StateInterface) error { +func (msp *MonServicePlacement) DbUpdate(ctx context.Context, s interfaces.StateInterface) error { // Update the database. - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { // Record the role. _, err := database.CreateService(ctx, tx, database.Service{Member: s.ClusterState().Name(), Service: msp.Name}) if err != nil { diff --git a/microceph/ceph/services.go b/microceph/ceph/services.go index d2393e34..fa357962 100644 --- a/microceph/ceph/services.go +++ b/microceph/ceph/services.go @@ -15,7 +15,7 @@ import ( "github.com/Rican7/retry/backoff" "github.com/Rican7/retry/strategy" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/common" @@ -31,8 +31,8 @@ var serviceWorkerTable = map[string](func() (common.Set, error)){ } // Restarts (in order) all Ceph Services provided in the input slice on the host. -func RestartCephServices(s interfaces.StateInterface, services []string) error { - clusterServices, err := ListServices(s.ClusterState()) +func RestartCephServices(ctx context.Context, s interfaces.StateInterface, services []string) error { + clusterServices, err := ListServices(ctx, s.ClusterState()) if err != nil { logger.Errorf("failed fetching services from db: %v", err) return err @@ -166,11 +166,11 @@ func isServicePlacementOnHost(services types.Services, serviceName string, hostn } // ListServices retrieves a list of services from the database -func ListServices(s *state.State) (types.Services, error) { +func ListServices(ctx context.Context, s state.State) (types.Services, error) { services := types.Services{} // Get the services 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.GetServices(ctx, tx) if err != nil { return fmt.Errorf("Failed to fetch service: %w", err) @@ -205,12 +205,12 @@ func cleanService(hostname, service string) error { } // removeServiceDatabase removes a service record from the database. -func removeServiceDatabase(s interfaces.StateInterface, service string) error { - if s.ClusterState().Database == nil { - return fmt.Errorf("no database") +func removeServiceDatabase(ctx context.Context, s interfaces.StateInterface, service string) error { + if s.ClusterState().ServerCert() == nil { + return fmt.Errorf("no server certificate") } - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := database.DeleteService(ctx, tx, s.ClusterState().Name(), service) if err != nil { logger.Errorf("failed to remove service from db %q: %v", service, err) @@ -223,7 +223,7 @@ func removeServiceDatabase(s interfaces.StateInterface, service string) error { } // DeleteService deletes a service from the node. -func DeleteService(s interfaces.StateInterface, service string) error { +func DeleteService(ctx context.Context, s interfaces.StateInterface, service string) error { err := snapStop(service, true) if err != nil { logger.Errorf("failed to stop daemon %q: %v", service, err) @@ -241,7 +241,7 @@ func DeleteService(s interfaces.StateInterface, service string) error { if err != nil { return fmt.Errorf("failed to clean service %q: %w", service, err) } - err = removeServiceDatabase(s, service) + err = removeServiceDatabase(ctx, s, service) if err != nil { return fmt.Errorf("failed to remove service %q from database: %w", service, err) } diff --git a/microceph/ceph/services_placement.go b/microceph/ceph/services_placement.go index b5ba29fa..c4c69407 100644 --- a/microceph/ceph/services_placement.go +++ b/microceph/ceph/services_placement.go @@ -1,7 +1,9 @@ package ceph import ( + "context" "fmt" + "github.com/canonical/microceph/microceph/interfaces" "github.com/canonical/lxd/shared/logger" @@ -15,11 +17,11 @@ type PlacementIntf interface { // Check if host is hospitable to the new service to be enabled. HospitalityCheck(interfaces.StateInterface) error // Initialise the new service. - ServiceInit(interfaces.StateInterface) error + ServiceInit(context.Context, interfaces.StateInterface) error // Perform Post Placement checks for the service PostPlacementCheck(interfaces.StateInterface) error // Perform DB updates to persist the service enablement changes. - DbUpdate(interfaces.StateInterface) error + DbUpdate(context.Context, interfaces.StateInterface) error } func GetServicePlacementTable() map[string](PlacementIntf) { @@ -31,7 +33,7 @@ func GetServicePlacementTable() map[string](PlacementIntf) { } } -func ServicePlacementHandler(s interfaces.StateInterface, payload types.EnableService) error { +func ServicePlacementHandler(ctx context.Context, s interfaces.StateInterface, payload types.EnableService) error { var ok bool var spt = GetServicePlacementTable() var sp PlacementIntf @@ -45,7 +47,7 @@ func ServicePlacementHandler(s interfaces.StateInterface, payload types.EnableSe } if payload.Wait { - err := EnableService(s, payload, sp) + err := EnableService(ctx, s, payload, sp) if err != nil { logger.Errorf("failed %s service enablement request: %v", payload.Name, err) return err @@ -53,7 +55,7 @@ func ServicePlacementHandler(s interfaces.StateInterface, payload types.EnableSe } else { go func() { // Async call to Enable service. - err := EnableService(s, payload, sp) + err := EnableService(context.Background(), s, payload, sp) if err != nil { logger.Errorf("failed %s service enablement request: %v", payload.Name, err) } @@ -63,7 +65,7 @@ func ServicePlacementHandler(s interfaces.StateInterface, payload types.EnableSe return nil } -func EnableService(s interfaces.StateInterface, payload types.EnableService, item PlacementIntf) error { +func EnableService(ctx context.Context, s interfaces.StateInterface, payload types.EnableService, item PlacementIntf) error { // Populate json payload data to the service object. err := item.PopulateParams(s, payload.Payload) @@ -82,7 +84,7 @@ func EnableService(s interfaces.StateInterface, payload types.EnableService, ite } // Initialise the new service. - err = item.ServiceInit(s) + err = item.ServiceInit(ctx, s) if err != nil { retErr := fmt.Errorf("failed to initialise %s service at host: %v", payload.Name, err) logger.Error(retErr.Error()) @@ -98,7 +100,7 @@ func EnableService(s interfaces.StateInterface, payload types.EnableService, ite } // Perform DB updates to persist the service enablement changes. - err = item.DbUpdate(s) + err = item.DbUpdate(ctx, s) if err != nil { retErr := fmt.Errorf("failed to add DB record for %s: %v", payload.Name, err) logger.Error(retErr.Error()) diff --git a/microceph/ceph/services_placement_generic.go b/microceph/ceph/services_placement_generic.go index 3232bebd..4871b176 100644 --- a/microceph/ceph/services_placement_generic.go +++ b/microceph/ceph/services_placement_generic.go @@ -4,12 +4,13 @@ import ( "context" "database/sql" "fmt" - "github.com/canonical/microceph/microceph/constants" - "github.com/canonical/microceph/microceph/interfaces" "os" "path/filepath" "time" + "github.com/canonical/microceph/microceph/constants" + "github.com/canonical/microceph/microceph/interfaces" + "github.com/canonical/lxd/shared/logger" "github.com/canonical/microceph/microceph/database" ) @@ -38,7 +39,7 @@ func (gsp *GenericServicePlacement) HospitalityCheck(s interfaces.StateInterface return genericHospitalityCheck(gsp.Name) } -func (gsp *GenericServicePlacement) ServiceInit(s interfaces.StateInterface) error { +func (gsp *GenericServicePlacement) ServiceInit(ctx context.Context, s interfaces.StateInterface) error { return genericServiceInit(s, gsp.Name) } @@ -46,8 +47,8 @@ func (gsp *GenericServicePlacement) PostPlacementCheck(s interfaces.StateInterfa return genericPostPlacementCheck(gsp.Name) } -func (gsp *GenericServicePlacement) DbUpdate(s interfaces.StateInterface) error { - return genericDbUpdate(s, gsp.Name) +func (gsp *GenericServicePlacement) DbUpdate(ctx context.Context, s interfaces.StateInterface) error { + return genericDbUpdate(ctx, s, gsp.Name) } // Generic Method Implementations @@ -120,9 +121,9 @@ func genericPostPlacementCheck(service string) error { return nil } -func genericDbUpdate(s interfaces.StateInterface, service string) error { +func genericDbUpdate(ctx context.Context, s interfaces.StateInterface, service string) error { // Update the database. - err := s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err := s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { // Record the roles. _, err := database.CreateService(ctx, tx, database.Service{Member: s.ClusterState().Name(), Service: service}) if err != nil { diff --git a/microceph/ceph/services_placement_rgw.go b/microceph/ceph/services_placement_rgw.go index 7aa4b3ff..2dc438ab 100644 --- a/microceph/ceph/services_placement_rgw.go +++ b/microceph/ceph/services_placement_rgw.go @@ -1,6 +1,7 @@ package ceph import ( + "context" "encoding/json" "fmt" @@ -28,9 +29,9 @@ func (rgw *RgwServicePlacement) HospitalityCheck(s interfaces.StateInterface) er return genericHospitalityCheck("rgw") } -func (rgw *RgwServicePlacement) ServiceInit(s interfaces.StateInterface) error { +func (rgw *RgwServicePlacement) ServiceInit(ctx context.Context, s interfaces.StateInterface) error { // fetch configs from db - config, err := getConfigDb(s) + config, err := getConfigDb(ctx, s) if err != nil { return fmt.Errorf("failed to get config db: %w", err) } @@ -42,6 +43,6 @@ func (rgw *RgwServicePlacement) PostPlacementCheck(s interfaces.StateInterface) return genericPostPlacementCheck("rgw") } -func (rgw *RgwServicePlacement) DbUpdate(s interfaces.StateInterface) error { - return genericDbUpdate(s, "rgw") +func (rgw *RgwServicePlacement) DbUpdate(ctx context.Context, s interfaces.StateInterface) error { + return genericDbUpdate(ctx, s, "rgw") } diff --git a/microceph/ceph/services_placement_test.go b/microceph/ceph/services_placement_test.go index 23e95681..c4b99976 100644 --- a/microceph/ceph/services_placement_test.go +++ b/microceph/ceph/services_placement_test.go @@ -1,10 +1,12 @@ package ceph import ( + "context" "fmt" - "github.com/canonical/microceph/microceph/tests" "testing" + "github.com/canonical/microceph/microceph/tests" + "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/mocks" "github.com/stretchr/testify/assert" @@ -60,7 +62,7 @@ func (s *servicesPlacementSuite) TestUnknownServiceFailure() { } // Check Enable Service fails for unregistered services. - err := ServicePlacementHandler(s.TestStateInterface, payload) + err := ServicePlacementHandler(context.Background(), s.TestStateInterface, payload) assert.Error(s.T(), err) } @@ -74,7 +76,7 @@ func (s *servicesPlacementSuite) TestIllStructuredPayloadFailure() { } // Check Enable Service fails for unregistered services. - err := ServicePlacementHandler(s.TestStateInterface, payload) + err := ServicePlacementHandler(context.Background(), s.TestStateInterface, payload) assert.ErrorContains(s.T(), err, "failed to populate the payload") } @@ -92,7 +94,7 @@ func (s *servicesPlacementSuite) TestHospitalityCheckFailure() { } // Check Enable Service fails for unregistered services. - err := ServicePlacementHandler(s.TestStateInterface, payload) + err := ServicePlacementHandler(context.Background(), s.TestStateInterface, payload) assert.ErrorContains(s.T(), err, "host failed hospitality check") } @@ -107,7 +109,7 @@ func (s *servicesPlacementSuite) TestServiceInitFailure() { addPlacementServiceInitFailExpectation(sp, s.TestStateInterface, payload) // Check Enable Service fails for unregistered services. - err := EnableService(s.TestStateInterface, payload, sp) + err := EnableService(context.Background(), s.TestStateInterface, payload, sp) assert.ErrorContains(s.T(), err, "failed to initialise") } @@ -122,7 +124,7 @@ func (s *servicesPlacementSuite) TestPostPlacementCheckFailure() { addPostPlacementCheckFailExpectation(sp, s.TestStateInterface, payload) // Check Enable Service fails for unregistered services. - err := EnableService(s.TestStateInterface, payload, sp) + err := EnableService(context.Background(), s.TestStateInterface, payload, sp) assert.ErrorContains(s.T(), err, "service unable to sustain on host") } @@ -137,6 +139,6 @@ func (s *servicesPlacementSuite) TestDbUpdateFailure() { addDbUpdateFailExpectation(sp, s.TestStateInterface, payload) // Check Enable Service fails for unregistered services. - err := EnableService(s.TestStateInterface, payload, sp) + err := EnableService(context.Background(), s.TestStateInterface, payload, sp) assert.ErrorContains(s.T(), err, "failed to add DB record for") } diff --git a/microceph/ceph/services_test.go b/microceph/ceph/services_test.go index 3b11cb7b..7fcb2c53 100644 --- a/microceph/ceph/services_test.go +++ b/microceph/ceph/services_test.go @@ -10,7 +10,6 @@ import ( "github.com/canonical/lxd/shared/api" "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/tests" - "github.com/canonical/microcluster/state" "github.com/canonical/microceph/microceph/mocks" "github.com/stretchr/testify/assert" @@ -32,14 +31,9 @@ func (s *servicesSuite) SetupTest() { s.TestStateInterface = mocks.NewStateInterface(s.T()) u := api.NewURL() - state := &state.State{ - Address: func() *api.URL { - return u - }, - Name: func() string { - return "foohost" - }, - Database: nil, + state := mocks.MockState{ + URL: u, + ClusterName: "foohost", } s.TestStateInterface.On("ClusterState").Return(state).Maybe() } diff --git a/microceph/ceph/start.go b/microceph/ceph/start.go index 0949e6dd..3450df61 100644 --- a/microceph/ceph/start.go +++ b/microceph/ceph/start.go @@ -13,14 +13,14 @@ import ( ) // Start is run on daemon startup. -func Start(s interfaces.StateInterface) error { +func Start(ctx context.Context, s interfaces.StateInterface) error { // Start background loop to refresh the config every minute if needed. go func() { oldMonitors := []string{} for { // Check that the database is ready. - err := s.ClusterState().Database.IsOpen(context.Background()) + err := s.ClusterState().Database().IsOpen(context.Background()) if err != nil { logger.Debug("start: database not ready, waiting...") time.Sleep(10 * time.Second) @@ -29,7 +29,7 @@ func Start(s interfaces.StateInterface) error { // Get the current list of monitors. monitors := []string{} - err = s.ClusterState().Database.Transaction(s.ClusterState().Context, func(ctx context.Context, tx *sql.Tx) error { + err = s.ClusterState().Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { serviceName := "mon" services, err := database.GetServices(ctx, tx, database.ServiceFilter{Service: &serviceName}) if err != nil { @@ -55,7 +55,7 @@ func Start(s interfaces.StateInterface) error { continue } - err = UpdateConfig(s) + err = UpdateConfig(ctx, s) if err != nil { logger.Errorf("start: failed to update config, retrying: %v", err) time.Sleep(10 * time.Second) diff --git a/microceph/client/client_configs.go b/microceph/client/client_configs.go index 6cc8936e..c0f632b1 100644 --- a/microceph/client/client_configs.go +++ b/microceph/client/client_configs.go @@ -7,7 +7,7 @@ import ( "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/client" + "github.com/canonical/microcluster/v2/client" "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/interfaces" @@ -79,7 +79,7 @@ func UpdateClientConf(ctx context.Context, c *client.Client) error { } // Sends the update conf request to every other member of the cluster. -func SendUpdateClientConfRequestToClusterMembers(s interfaces.StateInterface) error { +func SendUpdateClientConfRequestToClusterMembers(ctx context.Context, s interfaces.StateInterface) error { // Get a collection of clients to every other cluster member, with the notification user-agent set. cluster, err := s.ClusterState().Cluster(false) if err != nil { @@ -89,7 +89,7 @@ func SendUpdateClientConfRequestToClusterMembers(s interfaces.StateInterface) er for _, remoteClient := range cluster { // In order send restart to each cluster member and wait. - err = UpdateClientConf(s.ClusterState().Context, &remoteClient) + err = UpdateClientConf(ctx, &remoteClient) if err != nil { logger.Errorf("update conf error: %v", err) return err diff --git a/microceph/client/configs.go b/microceph/client/configs.go index 00da1abb..f5985234 100644 --- a/microceph/client/configs.go +++ b/microceph/client/configs.go @@ -7,7 +7,7 @@ import ( "github.com/canonical/lxd/shared/api" "github.com/canonical/microceph/microceph/api/types" - microCli "github.com/canonical/microcluster/client" + microCli "github.com/canonical/microcluster/v2/client" ) func SetConfig(ctx context.Context, c *microCli.Client, data *types.Config) error { diff --git a/microceph/client/disks.go b/microceph/client/disks.go index 3d0d32ac..c0375815 100644 --- a/microceph/client/disks.go +++ b/microceph/client/disks.go @@ -9,7 +9,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/microceph/microceph/api/types" ) diff --git a/microceph/client/log.go b/microceph/client/log.go index 75bbe5d9..f3a3cb86 100644 --- a/microceph/client/log.go +++ b/microceph/client/log.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/microceph/microceph/api/types" ) diff --git a/microceph/client/pool.go b/microceph/client/pool.go index 214e82c3..7c68f983 100644 --- a/microceph/client/pool.go +++ b/microceph/client/pool.go @@ -7,7 +7,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/microceph/microceph/api/types" ) diff --git a/microceph/client/services.go b/microceph/client/services.go index 05c0cbf9..211535a2 100644 --- a/microceph/client/services.go +++ b/microceph/client/services.go @@ -8,8 +8,8 @@ import ( "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/client" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/client" + "github.com/canonical/microcluster/v2/state" "github.com/canonical/microceph/microceph/api/types" ) @@ -77,7 +77,7 @@ func RestartService(ctx context.Context, c *client.Client, data *types.Services) } // Sends the desired list of services to be restarted on every other member of the cluster. -func SendRestartRequestToClusterMembers(s *state.State, services []string) error { +func SendRestartRequestToClusterMembers(ctx context.Context, s state.State, services []string) error { // Populate the restart request data. var data types.Services for _, service := range services { @@ -93,7 +93,7 @@ func SendRestartRequestToClusterMembers(s *state.State, services []string) error for _, remoteClient := range cluster { // In order send restart to each cluster member and wait. - err = RestartService(s.Context, &remoteClient, &data) + err = RestartService(ctx, &remoteClient, &data) if err != nil { logger.Errorf("restart error: %v", err) return err diff --git a/microceph/client/wrap.go b/microceph/client/wrap.go index 112251a6..6af73c69 100644 --- a/microceph/client/wrap.go +++ b/microceph/client/wrap.go @@ -4,7 +4,7 @@ import ( "context" "github.com/canonical/microceph/microceph/api/types" - microCli "github.com/canonical/microcluster/client" + microCli "github.com/canonical/microcluster/v2/client" ) // ClientInterface wraps client functions diff --git a/microceph/cmd/microceph/client_config_get.go b/microceph/cmd/microceph/client_config_get.go index c1fb3fdc..a077a633 100644 --- a/microceph/cmd/microceph/client_config_get.go +++ b/microceph/cmd/microceph/client_config_get.go @@ -5,7 +5,7 @@ import ( "fmt" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -46,7 +46,7 @@ func (c *cmdClientConfigGet) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("key %s is invalid. \nSupported Keys: %v", args[0], allowList.Keys()) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/client_config_list.go b/microceph/cmd/microceph/client_config_list.go index 7a485b31..d89b1037 100644 --- a/microceph/cmd/microceph/client_config_list.go +++ b/microceph/cmd/microceph/client_config_list.go @@ -5,7 +5,7 @@ import ( "fmt" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -37,7 +37,7 @@ func (c *cmdClientConfigList) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/client_config_reset.go b/microceph/cmd/microceph/client_config_reset.go index 745a68a9..e261d43a 100644 --- a/microceph/cmd/microceph/client_config_reset.go +++ b/microceph/cmd/microceph/client_config_reset.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -53,7 +53,7 @@ func (c *cmdClientConfigReset) Run(cmd *cobra.Command, args []string) error { args[0], constants.CliForcePrompt) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/client_config_set.go b/microceph/cmd/microceph/client_config_set.go index ad94f78e..48a08945 100644 --- a/microceph/cmd/microceph/client_config_set.go +++ b/microceph/cmd/microceph/client_config_set.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -45,7 +45,7 @@ func (c *cmdClientConfigSet) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("configuring key %s is not supported.\nSupported Keys: %v", args[0], allowList.Keys()) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_add.go b/microceph/cmd/microceph/cluster_add.go index 85c142b2..e2bf10a3 100644 --- a/microceph/cmd/microceph/cluster_add.go +++ b/microceph/cmd/microceph/cluster_add.go @@ -3,14 +3,17 @@ package main import ( "context" "fmt" + "time" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" ) type cmdClusterAdd struct { common *CmdControl cluster *cmdCluster + + flagTokenDuration string } func (c *cmdClusterAdd) Command() *cobra.Command { @@ -20,6 +23,8 @@ func (c *cmdClusterAdd) Command() *cobra.Command { RunE: c.Run, } + cmd.Flags().StringVarP(&c.flagTokenDuration, "timeout", "t", "3h", "Set the lifetime for the token. Default is 3 hours. (eg. 10s, 5m, 3h)") + return cmd } @@ -28,12 +33,17 @@ func (c *cmdClusterAdd) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } - token, err := m.NewJoinToken(context.Background(), args[0]) + expireAfter, err := time.ParseDuration(c.flagTokenDuration) + if err != nil { + return fmt.Errorf("Invalid value for timeout flag: %w", err) + } + + token, err := m.NewJoinToken(context.Background(), args[0], expireAfter) if err != nil { return err } diff --git a/microceph/cmd/microceph/cluster_bootstrap.go b/microceph/cmd/microceph/cluster_bootstrap.go index a765de1a..5129cc18 100644 --- a/microceph/cmd/microceph/cluster_bootstrap.go +++ b/microceph/cmd/microceph/cluster_bootstrap.go @@ -7,7 +7,7 @@ import ( "time" "github.com/canonical/lxd/lxd/util" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/common" @@ -43,7 +43,7 @@ func (c *cmdClusterBootstrap) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_config_get.go b/microceph/cmd/microceph/cluster_config_get.go index 8e502843..89a83464 100644 --- a/microceph/cmd/microceph/cluster_config_get.go +++ b/microceph/cmd/microceph/cluster_config_get.go @@ -5,7 +5,7 @@ import ( "fmt" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -41,7 +41,7 @@ func (c *cmdClusterConfigGet) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("Key %s is invalid. \nPermitted Keys: %v", args[0], allowList.Keys()) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("Unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_config_list.go b/microceph/cmd/microceph/cluster_config_list.go index c92c5d7f..02adc750 100644 --- a/microceph/cmd/microceph/cluster_config_list.go +++ b/microceph/cmd/microceph/cluster_config_list.go @@ -5,7 +5,7 @@ import ( "fmt" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -33,7 +33,7 @@ func (c *cmdClusterConfigList) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("Unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_config_reset.go b/microceph/cmd/microceph/cluster_config_reset.go index 5662066a..81c8a2d5 100644 --- a/microceph/cmd/microceph/cluster_config_reset.go +++ b/microceph/cmd/microceph/cluster_config_reset.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -43,7 +43,7 @@ func (c *cmdClusterConfigReset) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("resetting key %s is not allowed", args[0]) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_config_set.go b/microceph/cmd/microceph/cluster_config_set.go index faa60ed7..10042586 100644 --- a/microceph/cmd/microceph/cluster_config_set.go +++ b/microceph/cmd/microceph/cluster_config_set.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -43,7 +43,7 @@ func (c *cmdClusterConfigSet) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("configuring key %s is not allowed. \nPermitted Keys: %v", args[0], allowList.Keys()) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCeph: %w", err) } diff --git a/microceph/cmd/microceph/cluster_join.go b/microceph/cmd/microceph/cluster_join.go index 40461663..da36a1ad 100644 --- a/microceph/cmd/microceph/cluster_join.go +++ b/microceph/cmd/microceph/cluster_join.go @@ -7,7 +7,7 @@ import ( "time" "github.com/canonical/lxd/lxd/util" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/constants" @@ -36,7 +36,7 @@ func (c *cmdClusterJoin) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return fmt.Errorf("unable to configure MicroCluster: %w", err) } diff --git a/microceph/cmd/microceph/cluster_list.go b/microceph/cmd/microceph/cluster_list.go index bc3ff549..0e139a1c 100644 --- a/microceph/cmd/microceph/cluster_list.go +++ b/microceph/cmd/microceph/cluster_list.go @@ -6,7 +6,7 @@ import ( "github.com/canonical/lxd/shared" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" ) @@ -26,7 +26,7 @@ func (c *cmdClusterList) Command() *cobra.Command { } func (c *cmdClusterList) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/cluster_migrate.go b/microceph/cmd/microceph/cluster_migrate.go index d1ff94b4..9e9ab87d 100644 --- a/microceph/cmd/microceph/cluster_migrate.go +++ b/microceph/cmd/microceph/cluster_migrate.go @@ -4,7 +4,7 @@ import ( "context" "github.com/canonical/lxd/shared/logger" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -30,7 +30,7 @@ func (c *cmdClusterMigrate) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/cluster_remove.go b/microceph/cmd/microceph/cluster_remove.go index 2549584f..4b122eb0 100644 --- a/microceph/cmd/microceph/cluster_remove.go +++ b/microceph/cmd/microceph/cluster_remove.go @@ -3,7 +3,7 @@ package main import ( "context" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" ) @@ -31,7 +31,7 @@ func (c *cmdClusterRemove) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/cluster_sql.go b/microceph/cmd/microceph/cluster_sql.go index 42b581f5..d7013fcf 100644 --- a/microceph/cmd/microceph/cluster_sql.go +++ b/microceph/cmd/microceph/cluster_sql.go @@ -5,7 +5,7 @@ import ( "fmt" "os" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" ) @@ -37,7 +37,7 @@ func (c *cmdClusterSQL) Run(cmd *cobra.Command, args []string) error { } } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/disable_rgw.go b/microceph/cmd/microceph/disable_rgw.go index d0bbcdf0..1014ca8b 100644 --- a/microceph/cmd/microceph/disable_rgw.go +++ b/microceph/cmd/microceph/disable_rgw.go @@ -3,7 +3,7 @@ package main import ( "context" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/client" @@ -27,7 +27,7 @@ func (c *cmdDisableRGW) Command() *cobra.Command { // Run handles the disable rgw command. func (c *cmdDisableRGW) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/disk_add.go b/microceph/cmd/microceph/disk_add.go index 75015543..96863891 100644 --- a/microceph/cmd/microceph/disk_add.go +++ b/microceph/cmd/microceph/disk_add.go @@ -7,7 +7,7 @@ import ( "strings" lxdCmd "github.com/canonical/lxd/shared/cmd" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -75,7 +75,7 @@ func (c *cmdDiskAdd) Run(cmd *cobra.Command, args []string) error { return fmt.Errorf("arg validation failed: %w", err) } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/disk_list.go b/microceph/cmd/microceph/disk_list.go index ce5c7743..c1f5593f 100644 --- a/microceph/cmd/microceph/disk_list.go +++ b/microceph/cmd/microceph/disk_list.go @@ -11,8 +11,8 @@ import ( lxdCmd "github.com/canonical/lxd/shared/cmd" "github.com/canonical/lxd/shared/logger" "github.com/canonical/lxd/shared/units" - microCli "github.com/canonical/microcluster/client" - "github.com/canonical/microcluster/microcluster" + microCli "github.com/canonical/microcluster/v2/client" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -54,7 +54,7 @@ type DiskListOutput struct { } func (c *cmdDiskList) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/disk_remove.go b/microceph/cmd/microceph/disk_remove.go index f70fade8..fe185e7e 100644 --- a/microceph/cmd/microceph/disk_remove.go +++ b/microceph/cmd/microceph/disk_remove.go @@ -5,7 +5,7 @@ import ( "fmt" "strconv" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -42,7 +42,7 @@ func (c *cmdDiskRemove) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/enable_mds.go b/microceph/cmd/microceph/enable_mds.go index ada5da86..bf73ef0b 100644 --- a/microceph/cmd/microceph/enable_mds.go +++ b/microceph/cmd/microceph/enable_mds.go @@ -3,7 +3,7 @@ package main import ( "context" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -29,7 +29,7 @@ func (c *cmdEnableMDS) Command() *cobra.Command { // Run handles the enable mds command. func (c *cmdEnableMDS) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/enable_mgr.go b/microceph/cmd/microceph/enable_mgr.go index ce618f65..2f22a7a7 100644 --- a/microceph/cmd/microceph/enable_mgr.go +++ b/microceph/cmd/microceph/enable_mgr.go @@ -3,7 +3,7 @@ package main import ( "context" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -29,7 +29,7 @@ func (c *cmdEnableMGR) Command() *cobra.Command { // Run handles the enable mgr command. func (c *cmdEnableMGR) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/enable_mon.go b/microceph/cmd/microceph/enable_mon.go index 1c150648..dd2df839 100644 --- a/microceph/cmd/microceph/enable_mon.go +++ b/microceph/cmd/microceph/enable_mon.go @@ -3,7 +3,7 @@ package main import ( "context" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -29,7 +29,7 @@ func (c *cmdEnableMON) Command() *cobra.Command { // Run handles the enable mon command. func (c *cmdEnableMON) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/enable_rgw.go b/microceph/cmd/microceph/enable_rgw.go index 2ad1fe82..a321361e 100644 --- a/microceph/cmd/microceph/enable_rgw.go +++ b/microceph/cmd/microceph/enable_rgw.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -40,7 +40,7 @@ func (c *cmdEnableRGW) Command() *cobra.Command { // Run handles the enable rgw command. func (c *cmdEnableRGW) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/init.go b/microceph/cmd/microceph/init.go index 69ca84e4..0d5ba4ff 100644 --- a/microceph/cmd/microceph/init.go +++ b/microceph/cmd/microceph/init.go @@ -9,8 +9,8 @@ import ( "github.com/canonical/lxd/lxd/util" "github.com/canonical/lxd/shared/api" - microCli "github.com/canonical/microcluster/client" - "github.com/canonical/microcluster/microcluster" + microCli "github.com/canonical/microcluster/v2/client" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -33,7 +33,7 @@ func (c *cmdInit) Command() *cobra.Command { func (c *cmdInit) Run(cmd *cobra.Command, args []string) error { // Connect to the daemon. - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } @@ -128,7 +128,7 @@ func (c *cmdInit) Run(cmd *cobra.Command, args []string) error { } // Issue the token. - token, err := m.NewJoinToken(context.Background(), tokenName) + token, err := m.NewJoinToken(context.Background(), tokenName, 3*time.Hour) if err != nil { return err } diff --git a/microceph/cmd/microceph/log.go b/microceph/cmd/microceph/log.go index 56311b02..7415d4ce 100644 --- a/microceph/cmd/microceph/log.go +++ b/microceph/cmd/microceph/log.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api/types" @@ -61,7 +61,7 @@ func (c *cmdLogSetLevel) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } @@ -83,7 +83,7 @@ func (c *cmdLogGetLevel) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/main.go b/microceph/cmd/microceph/main.go index 6353e92b..649aa7bd 100644 --- a/microceph/cmd/microceph/main.go +++ b/microceph/cmd/microceph/main.go @@ -23,8 +23,6 @@ type CmdControl struct { FlagStateDir string } -var Version string // set by build process - func main() { // common flags. commonCmd := CmdControl{Asker: cli.NewAsker(bufio.NewReader(os.Stdin))} @@ -32,7 +30,7 @@ func main() { app := &cobra.Command{ Use: "microceph", Short: "Command for managing the MicroCeph deployment", - Version: version.Version, + Version: version.Version(), SilenceUsage: true, CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true}, } @@ -44,7 +42,7 @@ func main() { app.PersistentFlags().BoolVarP(&commonCmd.FlagLogVerbose, "verbose", "v", false, "Show all information messages") app.SetVersionTemplate("{{.Version}}\n") - app.Version = Version + app.Version = version.Version() // Top-level. var cmdEnable = cmdEnable{common: &commonCmd} diff --git a/microceph/cmd/microceph/pool.go b/microceph/cmd/microceph/pool.go index 5f9bdb76..b6a4bc21 100644 --- a/microceph/cmd/microceph/pool.go +++ b/microceph/cmd/microceph/pool.go @@ -7,7 +7,7 @@ import ( "github.com/canonical/microceph/microceph/api/types" "github.com/canonical/microceph/microceph/client" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" ) type cmdPool struct { @@ -43,7 +43,7 @@ func (c *cmdPoolSetRF) Run(cmd *cobra.Command, args []string) error { return cmd.Help() } - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microceph/status.go b/microceph/cmd/microceph/status.go index 4190cef3..33bfcad3 100644 --- a/microceph/cmd/microceph/status.go +++ b/microceph/cmd/microceph/status.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "github.com/canonical/microcluster/microcluster" + "github.com/canonical/microcluster/v2/microcluster" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/client" @@ -27,7 +27,7 @@ func (c *cmdStatus) Command() *cobra.Command { } func (c *cmdStatus) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir, Verbose: c.common.FlagLogVerbose, Debug: c.common.FlagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.common.FlagStateDir}) if err != nil { return err } diff --git a/microceph/cmd/microcephd/main.go b/microceph/cmd/microcephd/main.go index 4f4a10ce..4d25a9fe 100644 --- a/microceph/cmd/microcephd/main.go +++ b/microceph/cmd/microcephd/main.go @@ -8,9 +8,8 @@ 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/state" "github.com/spf13/cobra" "github.com/canonical/microceph/microceph/api" @@ -54,7 +53,7 @@ func (c *cmdDaemon) Command() *cobra.Command { cmd := &cobra.Command{ Use: "microcephd", Short: "Daemon for MicroCeph", - Version: version.Version, + Version: version.Version(), } cmd.RunE = c.Run @@ -63,33 +62,43 @@ func (c *cmdDaemon) Command() *cobra.Command { } func (c *cmdDaemon) Run(cmd *cobra.Command, args []string) error { - m, err := microcluster.App(microcluster.Args{StateDir: c.flagStateDir, Verbose: c.global.flagLogVerbose, Debug: c.global.flagLogDebug}) + m, err := microcluster.App(microcluster.Args{StateDir: c.flagStateDir}) if err != nil { return err } - h := &config.Hooks{} - h.PostBootstrap = func(s *state.State, initConfig map[string]string) error { + h := &state.Hooks{} + h.PostBootstrap = func(ctx context.Context, s state.State, initConfig map[string]string) error { data := common.BootstrapConfig{} interf := interfaces.CephState{State: s} common.DecodeBootstrapConfig(initConfig, &data) - return ceph.Bootstrap(interf, data) + return ceph.Bootstrap(ctx, interf, data) } - h.PostJoin = func(s *state.State, initConfig map[string]string) error { + h.PostJoin = func(ctx context.Context, s state.State, initConfig map[string]string) error { interf := interfaces.CephState{State: s} - return ceph.Join(interf) + return ceph.Join(ctx, interf) } - h.OnStart = func(s *state.State) error { + h.OnStart = func(ctx context.Context, s state.State) error { interf := interfaces.CephState{State: s} - return ceph.Start(interf) + return ceph.Start(ctx, interf) } h.PreRemove = ceph.PreRemove(m) - m.AddServers(api.Servers) - return m.Start(context.Background(), database.SchemaExtensions, nil, h) + daemonArgs := microcluster.DaemonArgs{ + Version: version.Version(), + + Verbose: c.global.flagLogVerbose, + Debug: c.global.flagLogDebug, + ExtensionsSchema: database.SchemaExtensions, + APIExtensions: nil, + Hooks: h, + ExtensionServers: api.Servers, + } + + return m.Start(context.Background(), daemonArgs) } func init() { diff --git a/microceph/common/cluster.go b/microceph/common/cluster.go index 9087417b..fe4ac2f5 100644 --- a/microceph/common/cluster.go +++ b/microceph/common/cluster.go @@ -1,17 +1,19 @@ package common import ( + "context" + "github.com/canonical/lxd/shared/logger" "github.com/canonical/microceph/microceph/interfaces" ) -func GetClusterMemberNames(s interfaces.StateInterface) ([]string, error) { +func GetClusterMemberNames(ctx context.Context, s interfaces.StateInterface) ([]string, error) { leader, err := s.ClusterState().Leader() if err != nil { return nil, err } - members, err := leader.GetClusterMembers(s.ClusterState().Context) + members, err := leader.GetClusterMembers(ctx) if err != nil { return nil, err } diff --git a/microceph/database/client_config.go b/microceph/database/client_config.go index 97725171..75974099 100644 --- a/microceph/database/client_config.go +++ b/microceph/database/client_config.go @@ -3,30 +3,30 @@ package database //go:generate -command mapper lxd-generate db mapper -t client_config.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem objects table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem objects-by-Key table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem objects-by-Host table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem objects-by-Key-and-Host table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem id table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem create table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem delete-by-Key table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem delete-by-Host table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem delete-by-Key-and-Host table=client_config -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e ClientConfigItem update table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem objects table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem objects-by-Key table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem objects-by-Host table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem objects-by-Key-and-Host table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem id table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem create table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem delete-by-Key table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem delete-by-Host table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem delete-by-Key-and-Host table=client_config +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem update table=client_config // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem GetMany table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem GetOne table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem ID table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem Exists table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem Create table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem DeleteOne-by-Key-and-Host table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem DeleteMany-by-Key table=client_config -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e ClientConfigItem Update table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem GetMany table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem GetOne table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem ID table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem Exists table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem Create table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem DeleteOne-by-Key-and-Host table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem DeleteMany-by-Key table=client_config +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e ClientConfigItem Update table=client_config type ClientConfigItem struct { ID int - Host string `db:"primary=yes&join=internal_cluster_members.name&joinon=client_config.member_id"` + Host string `db:"primary=yes&join=core_cluster_members.name&joinon=client_config.member_id"` Key string `db:"primary=yes"` Value string } diff --git a/microceph/database/client_config.mapper.go b/microceph/database/client_config.mapper.go index bc7de4c5..84ad9f37 100644 --- a/microceph/database/client_config.mapper.go +++ b/microceph/database/client_config.mapper.go @@ -12,51 +12,51 @@ 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 clientConfigItemObjects = cluster.RegisterStmt(` -SELECT client_config.id, internal_cluster_members.name AS host, client_config.key, client_config.value +SELECT client_config.id, core_cluster_members.name AS host, client_config.key, client_config.value FROM client_config - JOIN internal_cluster_members ON client_config.member_id = internal_cluster_members.id - ORDER BY internal_cluster_members.id, client_config.key + JOIN core_cluster_members ON client_config.member_id = core_cluster_members.id + ORDER BY core_cluster_members.id, client_config.key `) var clientConfigItemObjectsByKey = cluster.RegisterStmt(` -SELECT client_config.id, internal_cluster_members.name AS host, client_config.key, client_config.value +SELECT client_config.id, core_cluster_members.name AS host, client_config.key, client_config.value FROM client_config - JOIN internal_cluster_members ON client_config.member_id = internal_cluster_members.id + JOIN core_cluster_members ON client_config.member_id = core_cluster_members.id WHERE ( client_config.key = ? ) - ORDER BY internal_cluster_members.id, client_config.key + ORDER BY core_cluster_members.id, client_config.key `) var clientConfigItemObjectsByHost = cluster.RegisterStmt(` -SELECT client_config.id, internal_cluster_members.name AS host, client_config.key, client_config.value +SELECT client_config.id, core_cluster_members.name AS host, client_config.key, client_config.value FROM client_config - JOIN internal_cluster_members ON client_config.member_id = internal_cluster_members.id + JOIN core_cluster_members ON client_config.member_id = core_cluster_members.id WHERE ( host = ? ) - ORDER BY internal_cluster_members.id, client_config.key + ORDER BY core_cluster_members.id, client_config.key `) var clientConfigItemObjectsByKeyAndHost = cluster.RegisterStmt(` -SELECT client_config.id, internal_cluster_members.name AS host, client_config.key, client_config.value +SELECT client_config.id, core_cluster_members.name AS host, client_config.key, client_config.value FROM client_config - JOIN internal_cluster_members ON client_config.member_id = internal_cluster_members.id + JOIN core_cluster_members ON client_config.member_id = core_cluster_members.id WHERE ( client_config.key = ? AND host = ? ) - ORDER BY internal_cluster_members.id, client_config.key + ORDER BY core_cluster_members.id, client_config.key `) var clientConfigItemID = cluster.RegisterStmt(` SELECT client_config.id FROM client_config - JOIN internal_cluster_members ON client_config.member_id = internal_cluster_members.id - WHERE internal_cluster_members.name = ? AND client_config.key = ? + JOIN core_cluster_members ON client_config.member_id = core_cluster_members.id + WHERE core_cluster_members.name = ? AND client_config.key = ? `) var clientConfigItemCreate = cluster.RegisterStmt(` INSERT INTO client_config (member_id, key, value) - 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 clientConfigItemDeleteByKey = cluster.RegisterStmt(` @@ -64,23 +64,23 @@ DELETE FROM client_config WHERE key = ? `) var clientConfigItemDeleteByHost = cluster.RegisterStmt(` -DELETE FROM client_config WHERE member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) +DELETE FROM client_config WHERE member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) `) var clientConfigItemDeleteByKeyAndHost = cluster.RegisterStmt(` -DELETE FROM client_config WHERE key = ? AND member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) +DELETE FROM client_config WHERE key = ? AND member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) `) var clientConfigItemUpdate = cluster.RegisterStmt(` UPDATE client_config - SET member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?), key = ?, value = ? + SET member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?), key = ?, value = ? WHERE id = ? `) // clientConfigItemColumns 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 ClientConfigItem entity. func clientConfigItemColumns() string { - return "client_config.id, internal_cluster_members.name AS host, client_config.key, client_config.value" + return "client_config.id, core_cluster_members.name AS host, client_config.key, client_config.value" } // getClientConfigItems can be used to run handwritten sql.Stmts to return a slice of objects. diff --git a/microceph/database/client_config_extras.go b/microceph/database/client_config_extras.go index 5a459214..744e957b 100644 --- a/microceph/database/client_config_extras.go +++ b/microceph/database/client_config_extras.go @@ -4,14 +4,15 @@ import ( "context" "database/sql" "fmt" + "github.com/canonical/microceph/microceph/constants" "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/logger" "github.com/canonical/microceph/microceph/api/types" - "github.com/canonical/microcluster/cluster" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/cluster" + "github.com/canonical/microcluster/v2/state" ) var _ = api.ServerEnvironment{} @@ -34,7 +35,7 @@ INSERT OR REPLACE INTO client_config (member_id, key, value) var clientConfigItemCreateOrUpdate = cluster.RegisterStmt(` INSERT OR REPLACE INTO client_config (member_id, key, value) - 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 = ?), ?, ?) `) // Slice of ClientConfigItem(s) @@ -64,24 +65,24 @@ func (cci ClientConfigItems) GetClientConfigSlice() types.ClientConfigs { type ClientConfigQueryIntf interface { // Add Method - AddNew(s *state.State, key string, value string, host string) error + AddNew(ctx context.Context, s state.State, key string, value string, host string) error // Fetch Methods - GetAll(s *state.State) (ClientConfigItems, error) - GetAllForKey(s *state.State, key string) (ClientConfigItems, error) - GetAllForHost(s *state.State, host string) (ClientConfigItems, error) - GetAllForKeyAndHost(s *state.State, key string, host string) (ClientConfigItems, error) + GetAll(ctx context.Context, s state.State) (ClientConfigItems, error) + GetAllForKey(ctx context.Context, s state.State, key string) (ClientConfigItems, error) + GetAllForHost(ctx context.Context, s state.State, host string) (ClientConfigItems, error) + GetAllForKeyAndHost(ctx context.Context, s state.State, key string, host string) (ClientConfigItems, error) // Delete Methods - RemoveAllForKey(s *state.State, key string) error - RemoveOneForKeyAndHost(s *state.State, key string, host string) error + RemoveAllForKey(ctx context.Context, s state.State, key string) error + RemoveOneForKeyAndHost(ctx context.Context, s state.State, key string, host string) error } type ClientConfigQueryImpl struct{} // Add Method -func (ccq ClientConfigQueryImpl) AddNew(s *state.State, key string, value string, host string) error { - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { +func (ccq ClientConfigQueryImpl) AddNew(ctx context.Context, s state.State, key string, value string, host string) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { data := ClientConfigItem{ Key: key, Value: value, @@ -102,15 +103,15 @@ func (ccq ClientConfigQueryImpl) AddNew(s *state.State, key string, value string } // Fetch Methods -func (ccq ClientConfigQueryImpl) GetAll(s *state.State) (ClientConfigItems, error) { - globalConfigs, err := ccq.GetGlobalConfigs(s, "") +func (ccq ClientConfigQueryImpl) GetAll(ctx context.Context, s state.State) (ClientConfigItems, error) { + globalConfigs, err := ccq.GetGlobalConfigs(ctx, s, "") if err != nil { return nil, fmt.Errorf("failed to fetch global client configs: %w", err) } logger.Infof("Global Configs: %v", globalConfigs) - hostConfigs, err := ccq.GetAllForFilter(s) + hostConfigs, err := ccq.GetAllForFilter(ctx, s) if err != nil { return nil, fmt.Errorf("failed to fetch host configured client configs: %w", err) } @@ -120,15 +121,15 @@ func (ccq ClientConfigQueryImpl) GetAll(s *state.State) (ClientConfigItems, erro return append(globalConfigs, hostConfigs...), nil } -func (ccq ClientConfigQueryImpl) GetAllForKey(s *state.State, key string) (ClientConfigItems, error) { - globalConfigs, err := ccq.GetGlobalConfigs(s, key) +func (ccq ClientConfigQueryImpl) GetAllForKey(ctx context.Context, s state.State, key string) (ClientConfigItems, error) { + globalConfigs, err := ccq.GetGlobalConfigs(ctx, s, key) if err != nil { return nil, fmt.Errorf("failed to fetch global client configs, key %s: %w", key, err) } logger.Infof("Global Configs: %v", globalConfigs) - hostConfigs, err := ccq.GetAllForFilter(s, ClientConfigItemFilter{Host: nil, Key: &key}) + hostConfigs, err := ccq.GetAllForFilter(ctx, s, ClientConfigItemFilter{Host: nil, Key: &key}) if err != nil { return nil, fmt.Errorf("failed to fetch host configured client configs, key %s: %w", key, err) } @@ -138,15 +139,15 @@ func (ccq ClientConfigQueryImpl) GetAllForKey(s *state.State, key string) (Clien return append(globalConfigs, hostConfigs...), nil } -func (ccq ClientConfigQueryImpl) GetAllForHost(s *state.State, host string) (ClientConfigItems, error) { - globalConfigs, err := ccq.GetGlobalConfigs(s, "") +func (ccq ClientConfigQueryImpl) GetAllForHost(ctx context.Context, s state.State, host string) (ClientConfigItems, error) { + globalConfigs, err := ccq.GetGlobalConfigs(ctx, s, "") if err != nil { return nil, fmt.Errorf("failed to fetch global client configs, host %s: %w", host, err) } logger.Infof("Global Configs: %v", globalConfigs) - hostConfigs, err := ccq.GetAllForFilter(s, ClientConfigItemFilter{Host: &host, Key: nil}) + hostConfigs, err := ccq.GetAllForFilter(ctx, s, ClientConfigItemFilter{Host: &host, Key: nil}) if err != nil { return nil, fmt.Errorf("failed to fetch host client configs, host %s: %w", host, err) } @@ -156,15 +157,15 @@ func (ccq ClientConfigQueryImpl) GetAllForHost(s *state.State, host string) (Cli return squashClientConfigs(globalConfigs, hostConfigs), nil } -func (ccq ClientConfigQueryImpl) GetAllForKeyAndHost(s *state.State, key string, host string) (ClientConfigItems, error) { - return ccq.GetAllForFilter(s, ClientConfigItemFilter{Host: &host, Key: &key}) +func (ccq ClientConfigQueryImpl) GetAllForKeyAndHost(ctx context.Context, s state.State, key string, host string) (ClientConfigItems, error) { + return ccq.GetAllForFilter(ctx, s, ClientConfigItemFilter{Host: &host, Key: &key}) } -func (ccq ClientConfigQueryImpl) GetAllForFilter(s *state.State, filters ...ClientConfigItemFilter) (ClientConfigItems, error) { +func (ccq ClientConfigQueryImpl) GetAllForFilter(ctx context.Context, s state.State, filters ...ClientConfigItemFilter) (ClientConfigItems, error) { var err error var retval []ClientConfigItem - 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 { retval, err = GetClientConfigItems(ctx, tx, filters...) if err != nil { return err @@ -178,7 +179,7 @@ func (ccq ClientConfigQueryImpl) GetAllForFilter(s *state.State, filters ...Clie } // Fetch client configs using registered sql stmt and args -func (ccq ClientConfigQueryImpl) GetGlobalConfigs(s *state.State, key string) ([]ClientConfigItem, error) { +func (ccq ClientConfigQueryImpl) GetGlobalConfigs(ctx context.Context, s state.State, key string) ([]ClientConfigItem, error) { var err error objects := make([]ClientConfigItem, 0) @@ -196,7 +197,7 @@ func (ccq ClientConfigQueryImpl) GetGlobalConfigs(s *state.State, key string) ([ return nil } - 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 { if len(key) != 0 { return getOneGlobalConfigByKey(ctx, tx, dest, key) } @@ -211,8 +212,8 @@ func (ccq ClientConfigQueryImpl) GetGlobalConfigs(s *state.State, key string) ([ } // Delete Methods -func (ccq ClientConfigQueryImpl) RemoveAllForKey(s *state.State, key string) error { - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { +func (ccq ClientConfigQueryImpl) RemoveAllForKey(ctx context.Context, s state.State, key string) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := DeleteClientConfigItems(ctx, tx, key) if err != nil { return fmt.Errorf("failed to clean existing keys %s: %v", key, err) @@ -226,8 +227,8 @@ func (ccq ClientConfigQueryImpl) RemoveAllForKey(s *state.State, key string) err return nil } -func (ccq ClientConfigQueryImpl) RemoveOneForKeyAndHost(s *state.State, key string, host string) error { - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { +func (ccq ClientConfigQueryImpl) RemoveOneForKeyAndHost(ctx context.Context, s state.State, key string, host string) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { err := DeleteClientConfigItem(ctx, tx, key, host) if err != nil { return fmt.Errorf("failed to clean existing keys %s: %v", key, err) diff --git a/microceph/database/config.go b/microceph/database/config.go index d29378c0..75a73ae9 100644 --- a/microceph/database/config.go +++ b/microceph/database/config.go @@ -3,21 +3,21 @@ package database //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/microceph/database/config.mapper.go b/microceph/database/config.mapper.go index 66115dfe..b6dea5ba 100644 --- a/microceph/database/config.mapper.go +++ b/microceph/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/microceph/database/disk.go b/microceph/database/disk.go index 238ccfaf..15ae67d3 100644 --- a/microceph/database/disk.go +++ b/microceph/database/disk.go @@ -3,28 +3,28 @@ package database //go:generate -command mapper lxd-generate db mapper -t disk.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk objects table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk objects-by-Member table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk objects-by-Member-and-Path table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk id table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk create table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk delete-by-Member table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk delete-by-Member-and-Path table=Disks -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e Disk update table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk objects table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk objects-by-Member table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk objects-by-Member-and-Path table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk id table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk create table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk delete-by-Member table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk delete-by-Member-and-Path table=Disks +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e Disk update table=Disks // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk GetMany -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk GetOne -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk ID -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk Exists -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk Create -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk DeleteOne-by-Member-and-Path -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk DeleteMany-by-Member -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e Disk Update +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk GetMany +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk GetOne +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk ID +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk Exists +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk Create +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk DeleteOne-by-Member-and-Path +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk DeleteMany-by-Member +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e Disk Update // Disk is used to track the Ceph disks on a particular server. type Disk struct { ID int - Member string `db:"primary=yes&join=internal_cluster_members.name&joinon=Disks.member_id"` + Member string `db:"primary=yes&join=core_cluster_members.name&joinon=Disks.member_id"` Path string `db:"primary=yes"` } diff --git a/microceph/database/disk.mapper.go b/microceph/database/disk.mapper.go index df17b51f..e4c41c09 100644 --- a/microceph/database/disk.mapper.go +++ b/microceph/database/disk.mapper.go @@ -1,73 +1,74 @@ package database -// The code below was generated by lxd-generate, +// The code below was generated by lxd-generate - DO NOT EDIT! import ( "context" "database/sql" "errors" "fmt" - "github.com/canonical/lxd/lxd/db/query" - "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" "net/http" "strings" + + "github.com/canonical/lxd/lxd/db/query" + "github.com/canonical/lxd/shared/api" + "github.com/canonical/microcluster/v2/cluster" ) var _ = api.ServerEnvironment{} var diskObjects = cluster.RegisterStmt(` -SELECT Disks.id, internal_cluster_members.name AS member, Disks.path +SELECT Disks.id, core_cluster_members.name AS member, Disks.path FROM Disks - JOIN internal_cluster_members ON Disks.member_id = internal_cluster_members.id - ORDER BY internal_cluster_members.id, Disks.path + JOIN core_cluster_members ON Disks.member_id = core_cluster_members.id + ORDER BY core_cluster_members.id, Disks.path `) var diskObjectsByMember = cluster.RegisterStmt(` -SELECT Disks.id, internal_cluster_members.name AS member, Disks.path +SELECT Disks.id, core_cluster_members.name AS member, Disks.path FROM Disks - JOIN internal_cluster_members ON Disks.member_id = internal_cluster_members.id + JOIN core_cluster_members ON Disks.member_id = core_cluster_members.id WHERE ( member = ? ) - ORDER BY internal_cluster_members.id, Disks.path + ORDER BY core_cluster_members.id, Disks.path `) var diskObjectsByMemberAndPath = cluster.RegisterStmt(` -SELECT Disks.id, internal_cluster_members.name AS member, Disks.path +SELECT Disks.id, core_cluster_members.name AS member, Disks.path FROM Disks - JOIN internal_cluster_members ON Disks.member_id = internal_cluster_members.id + JOIN core_cluster_members ON Disks.member_id = core_cluster_members.id WHERE ( member = ? AND Disks.path = ? ) - ORDER BY internal_cluster_members.id, Disks.path + ORDER BY core_cluster_members.id, Disks.path `) var diskID = cluster.RegisterStmt(` SELECT Disks.id FROM Disks - JOIN internal_cluster_members ON Disks.member_id = internal_cluster_members.id - WHERE internal_cluster_members.name = ? AND Disks.path = ? + JOIN core_cluster_members ON Disks.member_id = core_cluster_members.id + WHERE core_cluster_members.name = ? AND Disks.path = ? `) var diskCreate = cluster.RegisterStmt(` INSERT INTO Disks (member_id, path) - 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 diskDeleteByMember = cluster.RegisterStmt(` -DELETE FROM Disks WHERE member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) +DELETE FROM Disks WHERE member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) `) var diskDeleteByMemberAndPath = cluster.RegisterStmt(` -DELETE FROM Disks WHERE member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) AND path = ? +DELETE FROM Disks WHERE member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) AND path = ? `) var diskUpdate = cluster.RegisterStmt(` UPDATE Disks - SET member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?), path = ? + SET member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?), path = ? WHERE id = ? `) // diskColumns 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 Disk entity. func diskColumns() string { - return "disks.id, internal_cluster_members.name AS member, disks.path" + return "disks.id, core_cluster_members.name AS member, disks.path" } // getDisks can be used to run handwritten sql.Stmts to return a slice of objects. diff --git a/microceph/database/disk_extras.go b/microceph/database/disk_extras.go index fe1eb416..136fb5d1 100644 --- a/microceph/database/disk_extras.go +++ b/microceph/database/disk_extras.go @@ -9,16 +9,16 @@ import ( "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/shared/api" - "github.com/canonical/microcluster/cluster" - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/cluster" + "github.com/canonical/microcluster/v2/state" ) // MemberCounterInterface is for counting member nodes. Introduced for mocking. // //go:generate mockery --name MemberCounterInterface type MemberCounterInterface interface { - Count(s *state.State) (int, error) - CountExclude(s *state.State, exclude int64) (int, error) + Count(ctx context.Context, s state.State) (int, error) + CountExclude(ctx context.Context, s state.State, exclude int64) (int, error) } type MemberCounterImpl struct{} @@ -31,18 +31,18 @@ type MemberDisk struct { var _ = api.ServerEnvironment{} var membersDiskCnt = cluster.RegisterStmt(` -SELECT internal_cluster_members.name AS member, count(disks.id) AS num_disks +SELECT core_cluster_members.name AS member, count(disks.id) AS num_disks FROM disks - JOIN internal_cluster_members ON disks.member_id = internal_cluster_members.id - GROUP BY internal_cluster_members.id + JOIN core_cluster_members ON disks.member_id = core_cluster_members.id + GROUP BY core_cluster_members.id `) var membersDiskCntExclude = cluster.RegisterStmt(` -SELECT internal_cluster_members.name AS member, count(disks.id) AS num_disks +SELECT core_cluster_members.name AS member, count(disks.id) AS num_disks FROM disks -JOIN internal_cluster_members ON disks.member_id = internal_cluster_members.id +JOIN core_cluster_members ON disks.member_id = core_cluster_members.id WHERE disks.id != ? -GROUP BY internal_cluster_members.id +GROUP BY core_cluster_members.id `) // MembersDiskCnt returns the number of disks per member for all members that have at least one disk excluding the given OSD @@ -87,10 +87,10 @@ func MembersDiskCnt(ctx context.Context, tx *sql.Tx, exclude int64) ([]MemberDis } // Count returns the number of nodes in the cluster with at least one disk -func (m MemberCounterImpl) Count(s *state.State) (int, error) { +func (m MemberCounterImpl) Count(ctx context.Context, s state.State) (int, error) { var numNodes int - 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 := MembersDiskCnt(ctx, tx, -1) if err != nil { return fmt.Errorf("Failed to fetch disks: %w", err) @@ -105,10 +105,10 @@ func (m MemberCounterImpl) Count(s *state.State) (int, error) { } // CountExclude returns the number of nodes in the cluster with at least one disk, excluding the given OSD -func (m MemberCounterImpl) CountExclude(s *state.State, exclude int64) (int, error) { +func (m MemberCounterImpl) CountExclude(ctx context.Context, s state.State, exclude int64) (int, error) { var numNodes int - 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 := MembersDiskCnt(ctx, tx, exclude) if err != nil { return fmt.Errorf("Failed to fetch disks: %w", err) @@ -127,11 +127,11 @@ var MemberCounter MemberCounterInterface = MemberCounterImpl{} // OSDQueryInterface is for querying OSDs. Introduced for mocking. type OSDQueryInterface interface { - HaveOSD(s *state.State, osd int64) (bool, error) - Path(s *state.State, osd int64) (string, error) - Delete(s *state.State, osd int64) error - List(s *state.State) (types.Disks, error) - UpdatePath(s *state.State, osd int64, path string) error + HaveOSD(ctx context.Context, s state.State, osd int64) (bool, error) + Path(ctx context.Context, s state.State, osd int64) (string, error) + Delete(ctx context.Context, s state.State, osd int64) error + List(ctx context.Context, s state.State) (types.Disks, error) + UpdatePath(ctx context.Context, s state.State, osd int64, path string) error } type OSDQueryImpl struct{} @@ -155,10 +155,10 @@ WHERE disks.id = ? `) // HaveOSD returns either false or true depending on whether the given OSD is present in the cluster -func (o OSDQueryImpl) HaveOSD(s *state.State, osd int64) (bool, error) { +func (o OSDQueryImpl) HaveOSD(ctx context.Context, s state.State, osd int64) (bool, error) { var present int - 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 { sqlStmt, err := cluster.Stmt(tx, haveOsd) if err != nil { return fmt.Errorf("Failed to get \"haveOsd\" prepared statement: %w", err) @@ -177,10 +177,10 @@ func (o OSDQueryImpl) HaveOSD(s *state.State, osd int64) (bool, error) { } // Path returns the path of the given OSD -func (o OSDQueryImpl) Path(s *state.State, osd int64) (string, error) { +func (o OSDQueryImpl) Path(ctx context.Context, s state.State, osd int64) (string, error) { var path 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 { sqlStmt, err := cluster.Stmt(tx, osdPath) if err != nil { return fmt.Errorf("Failed to get \"osdPath\" prepared statement: %w", err) @@ -199,22 +199,22 @@ func (o OSDQueryImpl) Path(s *state.State, osd int64) (string, error) { } // Delete OSD records for the given OSD -func (o OSDQueryImpl) Delete(s *state.State, osd int64) error { - path, err := o.Path(s, osd) +func (o OSDQueryImpl) Delete(ctx context.Context, s state.State, osd int64) error { + path, err := o.Path(ctx, s, osd) if err != nil { return err } - 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 { return DeleteDisk(ctx, tx, s.Name(), path) }) return err } // List OSD records -func (o OSDQueryImpl) List(s *state.State) (types.Disks, error) { +func (o OSDQueryImpl) List(ctx context.Context, s state.State) (types.Disks, error) { disks := types.Disks{} // Get the OSDs 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 := GetDisks(ctx, tx) if err != nil { return fmt.Errorf("Failed to fetch disks: %w", err) @@ -237,8 +237,8 @@ func (o OSDQueryImpl) List(s *state.State) (types.Disks, error) { } // UpdatePath updates the path of the given OSD -func (o OSDQueryImpl) UpdatePath(s *state.State, osd int64, path string) error { - err := s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error { +func (o OSDQueryImpl) UpdatePath(ctx context.Context, s state.State, osd int64, path string) error { + err := s.Database().Transaction(ctx, func(ctx context.Context, tx *sql.Tx) error { sqlStmt, err := cluster.Stmt(tx, updatePath) if err != nil { return fmt.Errorf("failed to get \"updatePath\" prepared statement: %w", err) diff --git a/microceph/database/schema.go b/microceph/database/schema.go index 876beb1a..1bf19eaa 100644 --- a/microceph/database/schema.go +++ b/microceph/database/schema.go @@ -4,7 +4,9 @@ package database import ( "context" "database/sql" + "fmt" + "github.com/canonical/lxd/lxd/db/query" "github.com/canonical/lxd/lxd/db/schema" ) @@ -14,10 +16,33 @@ var SchemaExtensions = []schema.Update{ schemaUpdate1, schemaUpdate2, schemaUpdate3, + schemaUpdate4, +} + +// getClusterTableName returns the name of the table that holds the record of cluster members from sqlite_master. +// Prior to microcluster V2, this table was called `internal_cluster_members`, but now it is `core_cluster_members`. +// Since extensions to the database may be at an earlier version (either 1, 2, or 3), this helper will dynamically determine the table name to use. +func getClusterTableName(ctx context.Context, tx *sql.Tx) (string, error) { + stmt := "SELECT name FROM sqlite_master WHERE name = 'internal_cluster_members' OR name = 'core_cluster_members'" + tables, err := query.SelectStrings(ctx, tx, stmt) + if err != nil { + return "", err + } + + if len(tables) != 1 || tables[0] == "" { + return "", fmt.Errorf("No cluster members table found") + } + + return tables[0], nil } func schemaUpdate1(ctx context.Context, tx *sql.Tx) error { - stmt := ` + tableName, err := getClusterTableName(ctx, tx) + if err != nil { + return err + } + + stmt := fmt.Sprintf(` CREATE TABLE config ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, key TEXT NOT NULL, @@ -30,7 +55,7 @@ CREATE TABLE disks ( member_id INTEGER NOT NULL, path TEXT NOT NULL, osd INTEGER NOT NULL, - FOREIGN KEY (member_id) REFERENCES "internal_cluster_members" (id) ON DELETE CASCADE, + FOREIGN KEY (member_id) REFERENCES "%s" (id) ON DELETE CASCADE, UNIQUE(member_id, path), UNIQUE(osd) ); @@ -39,51 +64,109 @@ CREATE TABLE services ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, member_id INTEGER NOT NULL, service TEXT NOT NULL, - FOREIGN KEY (member_id) REFERENCES "internal_cluster_members" (id) ON DELETE CASCADE, + FOREIGN KEY (member_id) REFERENCES "%s" (id) ON DELETE CASCADE, UNIQUE(member_id, service) ); - ` + `, tableName, tableName) - _, err := tx.Exec(stmt) + _, err = tx.Exec(stmt) return err } // Adds client config table in database schema. func schemaUpdate2(ctx context.Context, tx *sql.Tx) error { - stmt := ` + tableName, err := getClusterTableName(ctx, tx) + if err != nil { + return err + } + + stmt := fmt.Sprintf(` CREATE TABLE client_config ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, member_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, - FOREIGN KEY (member_id) REFERENCES "internal_cluster_members" (id) ON DELETE CASCADE + FOREIGN KEY (member_id) REFERENCES "%s" (id) ON DELETE CASCADE ); CREATE UNIQUE INDEX cc_index ON client_config(coalesce(member_id, 0), key); - ` + `, tableName) - _, err := tx.Exec(stmt) + _, err = tx.Exec(stmt) return err } // schemaUpdate3 generates the diskpaths table, copying the data from the disks table. func schemaUpdate3(ctx context.Context, tx *sql.Tx) error { - stmt := ` + tableName, err := getClusterTableName(ctx, tx) + if err != nil { + return err + } + + stmt := fmt.Sprintf(` CREATE TABLE disks2 ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, member_id INTEGER NOT NULL, path TEXT NOT NULL, - FOREIGN KEY (member_id) REFERENCES "internal_cluster_members" (id) ON DELETE CASCADE, + FOREIGN KEY (member_id) REFERENCES "%s" (id) ON DELETE CASCADE, UNIQUE(member_id, path) ); INSERT INTO disks2 (id, member_id, path) SELECT osd, member_id, path FROM disks; DROP TABLE disks; ALTER TABLE disks2 RENAME TO disks; + `, tableName) + _, err = tx.Exec(stmt) + + return err +} + +// schemaUpdate4 updates all tables referencing `internal_cluster_members` to now reference `core_cluster_members` instead. +func schemaUpdate4(ctx context.Context, tx *sql.Tx) error { + stmt := ` +CREATE TABLE disks2 ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + member_id INTEGER NOT NULL, + path TEXT NOT NULL, + FOREIGN KEY (member_id) REFERENCES "core_cluster_members" (id) ON DELETE CASCADE, + UNIQUE(member_id, path) +); +INSERT INTO disks2 (id, member_id, path) +SELECT id, member_id, path FROM disks; +DROP TABLE disks; +ALTER TABLE disks2 RENAME TO disks; + + +DROP INDEX IF EXISTS cc_index; +CREATE TABLE client_config_new ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + member_id INTEGER, + key TEXT NOT NULL, + value TEXT NOT NULL, + FOREIGN KEY (member_id) REFERENCES "core_cluster_members" (id) ON DELETE CASCADE +); + +CREATE UNIQUE INDEX cc_index ON client_config(coalesce(member_id, 0), key); +INSERT INTO client_config_new (id,member_id,key,value) SELECT id,member_id,key,value FROM client_config; +DROP TABLE client_config; +ALTER TABLE client_config_new RENAME TO client_config; + + +CREATE TABLE services_new ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + member_id INTEGER NOT NULL, + service TEXT NOT NULL, + FOREIGN KEY (member_id) REFERENCES "core_cluster_members" (id) ON DELETE CASCADE, + UNIQUE(member_id, service) +); + +INSERT INTO services_new (id,member_id,service) SELECT id,member_id,service FROM services; +DROP TABLE services; +ALTER TABLE services_new RENAME TO services; ` - _, err := tx.Exec(stmt) + _, err := tx.ExecContext(ctx, stmt) return err } diff --git a/microceph/database/service.go b/microceph/database/service.go index 327ec2b0..5376a0ce 100644 --- a/microceph/database/service.go +++ b/microceph/database/service.go @@ -3,29 +3,29 @@ package database //go:generate -command mapper lxd-generate db mapper -t service.mapper.go //go:generate mapper reset // -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service objects table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service objects-by-Member table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service objects-by-Service table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service objects-by-Member-and-Service table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service id table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service create table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service delete-by-Member table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service delete-by-Member-and-Service table=services -//go:generate mapper stmt -d github.com/canonical/microcluster/cluster -e service update table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service objects table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service objects-by-Member table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service objects-by-Service table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service objects-by-Member-and-Service table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service id table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service create table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service delete-by-Member table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service delete-by-Member-and-Service table=services +//go:generate mapper stmt -d github.com/canonical/microcluster/v2/cluster -e service update table=services // -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service GetMany -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service GetOne -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service ID -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service Exists -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service Create -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service DeleteOne-by-Member-and-Service -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service DeleteMany-by-Member -//go:generate mapper method -i -d github.com/canonical/microcluster/cluster -e service Update +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service GetMany +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service GetOne +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service ID +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service Exists +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service Create +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service DeleteOne-by-Member-and-Service +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service DeleteMany-by-Member +//go:generate mapper method -i -d github.com/canonical/microcluster/v2/cluster -e service Update // Service is used to track the Ceph services running on a particular server. type Service struct { ID int - Member string `db:"primary=yes&join=internal_cluster_members.name&joinon=services.member_id"` + Member string `db:"primary=yes&join=core_cluster_members.name&joinon=services.member_id"` Service string `db:"primary=yes"` } diff --git a/microceph/database/service.mapper.go b/microceph/database/service.mapper.go index 41e36fd6..1175db84 100644 --- a/microceph/database/service.mapper.go +++ b/microceph/database/service.mapper.go @@ -12,71 +12,71 @@ 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 serviceObjects = cluster.RegisterStmt(` -SELECT services.id, internal_cluster_members.name AS member, services.service +SELECT services.id, core_cluster_members.name AS member, services.service FROM services - JOIN internal_cluster_members ON services.member_id = internal_cluster_members.id - ORDER BY internal_cluster_members.id, services.service + JOIN core_cluster_members ON services.member_id = core_cluster_members.id + ORDER BY core_cluster_members.id, services.service `) var serviceObjectsByMember = cluster.RegisterStmt(` -SELECT services.id, internal_cluster_members.name AS member, services.service +SELECT services.id, core_cluster_members.name AS member, services.service FROM services - JOIN internal_cluster_members ON services.member_id = internal_cluster_members.id + JOIN core_cluster_members ON services.member_id = core_cluster_members.id WHERE ( member = ? ) - ORDER BY internal_cluster_members.id, services.service + ORDER BY core_cluster_members.id, services.service `) var serviceObjectsByService = cluster.RegisterStmt(` -SELECT services.id, internal_cluster_members.name AS member, services.service +SELECT services.id, core_cluster_members.name AS member, services.service FROM services - JOIN internal_cluster_members ON services.member_id = internal_cluster_members.id + JOIN core_cluster_members ON services.member_id = core_cluster_members.id WHERE ( services.service = ? ) - ORDER BY internal_cluster_members.id, services.service + ORDER BY core_cluster_members.id, services.service `) var serviceObjectsByMemberAndService = cluster.RegisterStmt(` -SELECT services.id, internal_cluster_members.name AS member, services.service +SELECT services.id, core_cluster_members.name AS member, services.service FROM services - JOIN internal_cluster_members ON services.member_id = internal_cluster_members.id + JOIN core_cluster_members ON services.member_id = core_cluster_members.id WHERE ( member = ? AND services.service = ? ) - ORDER BY internal_cluster_members.id, services.service + ORDER BY core_cluster_members.id, services.service `) var serviceID = cluster.RegisterStmt(` SELECT services.id FROM services - JOIN internal_cluster_members ON services.member_id = internal_cluster_members.id - WHERE internal_cluster_members.name = ? AND services.service = ? + JOIN core_cluster_members ON services.member_id = core_cluster_members.id + WHERE core_cluster_members.name = ? AND services.service = ? `) var serviceCreate = cluster.RegisterStmt(` INSERT INTO services (member_id, service) - 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 serviceDeleteByMember = cluster.RegisterStmt(` -DELETE FROM services WHERE member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) +DELETE FROM services WHERE member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) `) var serviceDeleteByMemberAndService = cluster.RegisterStmt(` -DELETE FROM services WHERE member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?) AND service = ? +DELETE FROM services WHERE member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?) AND service = ? `) var serviceUpdate = cluster.RegisterStmt(` UPDATE services - SET member_id = (SELECT internal_cluster_members.id FROM internal_cluster_members WHERE internal_cluster_members.name = ?), service = ? + SET member_id = (SELECT core_cluster_members.id FROM core_cluster_members WHERE core_cluster_members.name = ?), service = ? WHERE id = ? `) // serviceColumns 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 Service entity. func serviceColumns() string { - return "services.id, internal_cluster_members.name AS member, services.service" + return "services.id, core_cluster_members.name AS member, services.service" } // getServices can be used to run handwritten sql.Stmts to return a slice of objects. diff --git a/microceph/go.mod b/microceph/go.mod index 4c2c6c8e..03aeafcf 100644 --- a/microceph/go.mod +++ b/microceph/go.mod @@ -1,11 +1,11 @@ module github.com/canonical/microceph/microceph -go 1.22.4 +go 1.22.5 require ( github.com/Rican7/retry v0.3.1 - github.com/canonical/lxd v0.0.0-20240709081608-9df996e36bac - github.com/canonical/microcluster v0.0.0-20240709163503-3d587817830c + github.com/canonical/lxd v0.0.0-20240730172021-8e39e5d4f55f + github.com/canonical/microcluster/v2 v2.0.2 github.com/djherbis/times v1.6.0 github.com/google/go-cmp v0.6.0 github.com/gorilla/mux v1.8.1 @@ -20,13 +20,13 @@ require ( require ( 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fvbommel/sortorder v1.1.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 @@ -39,13 +39,13 @@ 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-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mitchellh/go-homedir v1.1.0 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect @@ -54,7 +54,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/zitadel/logging v0.6.0 // indirect - github.com/zitadel/oidc/v3 v3.25.1 // indirect + github.com/zitadel/oidc/v3 v3.26.0 // indirect github.com/zitadel/schema v1.3.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect diff --git a/microceph/go.sum b/microceph/go.sum index de581290..298c9c3d 100644 --- a/microceph/go.sum +++ b/microceph/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-20240709081608-9df996e36bac h1:WqXeS0uyAAmFB9aflCucb/pPZzIdivO9uG4tWw7CEAw= -github.com/canonical/lxd v0.0.0-20240709081608-9df996e36bac/go.mod h1:S2MXobHv9Wh6cpr3biLo2Kq0vqK2/PxpFuE/8ZsNDic= -github.com/canonical/microcluster v0.0.0-20240709163503-3d587817830c h1:Kjz8OZ2rFcpGfF9KYSJ6iAWraK131IQlO/13VB+saQ0= -github.com/canonical/microcluster v0.0.0-20240709163503-3d587817830c/go.mod h1:ldDJ32PQhoc7sTSkQnUs2CQPnjUOkkXrzlbUaq9EIPI= +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= @@ -100,8 +100,8 @@ github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITL 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= @@ -241,8 +241,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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/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= @@ -278,8 +278,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= @@ -347,8 +347,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.26.0 h1:BG3OUK+JpuKz7YHJIyUxL5Sl2JV6ePkG42UP4Xv3J2w= +github.com/zitadel/oidc/v3 v3.26.0/go.mod h1:Cx6AYPTJO5q2mjqF3jaknbKOUjpq1Xui0SYvVhkKuXU= 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= diff --git a/microceph/interfaces/state.go b/microceph/interfaces/state.go index fbf7fb0f..51fa65a3 100644 --- a/microceph/interfaces/state.go +++ b/microceph/interfaces/state.go @@ -2,20 +2,20 @@ package interfaces import ( - "github.com/canonical/microcluster/state" + "github.com/canonical/microcluster/v2/state" ) // StateInterface for retrieving cluster state type StateInterface interface { - ClusterState() *state.State + ClusterState() state.State } // CephState holds cluster state type CephState struct { - State *state.State + State state.State } // ClusterState gets the cluster state -func (c CephState) ClusterState() *state.State { +func (c CephState) ClusterState() state.State { return c.State } diff --git a/microceph/mocks/ClientConfigQueryIntf.go b/microceph/mocks/ClientConfigQueryIntf.go index 59b093d9..d0a4bcff 100644 --- a/microceph/mocks/ClientConfigQueryIntf.go +++ b/microceph/mocks/ClientConfigQueryIntf.go @@ -3,8 +3,10 @@ package mocks import ( + context "context" + database "github.com/canonical/microceph/microceph/database" - state "github.com/canonical/microcluster/state" + state "github.com/canonical/microcluster/v2/state" mock "github.com/stretchr/testify/mock" ) @@ -14,12 +16,12 @@ type ClientConfigQueryIntf struct { } // AddNew provides a mock function with given fields: s, key, value, host -func (_m *ClientConfigQueryIntf) AddNew(s *state.State, key string, value string, host string) error { +func (_m *ClientConfigQueryIntf) AddNew(ctx context.Context, s state.State, key string, value string, host string) error { ret := _m.Called(s, key, value, host) var r0 error - if rf, ok := ret.Get(0).(func(*state.State, string, string, string) error); ok { - r0 = rf(s, key, value, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string, string, string) error); ok { + r0 = rf(ctx, s, key, value, host) } else { r0 = ret.Error(0) } @@ -28,24 +30,24 @@ func (_m *ClientConfigQueryIntf) AddNew(s *state.State, key string, value string } // GetAll provides a mock function with given fields: s -func (_m *ClientConfigQueryIntf) GetAll(s *state.State) (database.ClientConfigItems, error) { +func (_m *ClientConfigQueryIntf) GetAll(ctx context.Context, s state.State) (database.ClientConfigItems, error) { ret := _m.Called(s) var r0 database.ClientConfigItems var r1 error - if rf, ok := ret.Get(0).(func(*state.State) (database.ClientConfigItems, error)); ok { - return rf(s) + if rf, ok := ret.Get(0).(func(context.Context, state.State) (database.ClientConfigItems, error)); ok { + return rf(ctx, s) } - if rf, ok := ret.Get(0).(func(*state.State) database.ClientConfigItems); ok { - r0 = rf(s) + if rf, ok := ret.Get(0).(func(context.Context, state.State) database.ClientConfigItems); ok { + r0 = rf(ctx, s) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(database.ClientConfigItems) } } - if rf, ok := ret.Get(1).(func(*state.State) error); ok { - r1 = rf(s) + if rf, ok := ret.Get(1).(func(context.Context, state.State) error); ok { + r1 = rf(ctx, s) } else { r1 = ret.Error(1) } @@ -54,24 +56,24 @@ func (_m *ClientConfigQueryIntf) GetAll(s *state.State) (database.ClientConfigIt } // GetAllForHost provides a mock function with given fields: s, host -func (_m *ClientConfigQueryIntf) GetAllForHost(s *state.State, host string) (database.ClientConfigItems, error) { +func (_m *ClientConfigQueryIntf) GetAllForHost(ctx context.Context, s state.State, host string) (database.ClientConfigItems, error) { ret := _m.Called(s, host) var r0 database.ClientConfigItems var r1 error - if rf, ok := ret.Get(0).(func(*state.State, string) (database.ClientConfigItems, error)); ok { - return rf(s, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string) (database.ClientConfigItems, error)); ok { + return rf(ctx, s, host) } - if rf, ok := ret.Get(0).(func(*state.State, string) database.ClientConfigItems); ok { - r0 = rf(s, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string) database.ClientConfigItems); ok { + r0 = rf(ctx, s, host) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(database.ClientConfigItems) } } - if rf, ok := ret.Get(1).(func(*state.State, string) error); ok { - r1 = rf(s, host) + if rf, ok := ret.Get(1).(func(context.Context, state.State, string) error); ok { + r1 = rf(ctx, s, host) } else { r1 = ret.Error(1) } @@ -80,24 +82,24 @@ func (_m *ClientConfigQueryIntf) GetAllForHost(s *state.State, host string) (dat } // GetAllForKey provides a mock function with given fields: s, key -func (_m *ClientConfigQueryIntf) GetAllForKey(s *state.State, key string) (database.ClientConfigItems, error) { +func (_m *ClientConfigQueryIntf) GetAllForKey(ctx context.Context, s state.State, key string) (database.ClientConfigItems, error) { ret := _m.Called(s, key) var r0 database.ClientConfigItems var r1 error - if rf, ok := ret.Get(0).(func(*state.State, string) (database.ClientConfigItems, error)); ok { - return rf(s, key) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string) (database.ClientConfigItems, error)); ok { + return rf(ctx, s, key) } - if rf, ok := ret.Get(0).(func(*state.State, string) database.ClientConfigItems); ok { - r0 = rf(s, key) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string) database.ClientConfigItems); ok { + r0 = rf(ctx, s, key) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(database.ClientConfigItems) } } - if rf, ok := ret.Get(1).(func(*state.State, string) error); ok { - r1 = rf(s, key) + if rf, ok := ret.Get(1).(func(context.Context, state.State, string) error); ok { + r1 = rf(ctx, s, key) } else { r1 = ret.Error(1) } @@ -106,24 +108,24 @@ func (_m *ClientConfigQueryIntf) GetAllForKey(s *state.State, key string) (datab } // GetAllForKeyAndHost provides a mock function with given fields: s, key, host -func (_m *ClientConfigQueryIntf) GetAllForKeyAndHost(s *state.State, key string, host string) (database.ClientConfigItems, error) { +func (_m *ClientConfigQueryIntf) GetAllForKeyAndHost(ctx context.Context, s state.State, key string, host string) (database.ClientConfigItems, error) { ret := _m.Called(s, key, host) var r0 database.ClientConfigItems var r1 error - if rf, ok := ret.Get(0).(func(*state.State, string, string) (database.ClientConfigItems, error)); ok { - return rf(s, key, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string, string) (database.ClientConfigItems, error)); ok { + return rf(ctx, s, key, host) } - if rf, ok := ret.Get(0).(func(*state.State, string, string) database.ClientConfigItems); ok { - r0 = rf(s, key, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string, string) database.ClientConfigItems); ok { + r0 = rf(ctx, s, key, host) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(database.ClientConfigItems) } } - if rf, ok := ret.Get(1).(func(*state.State, string, string) error); ok { - r1 = rf(s, key, host) + if rf, ok := ret.Get(1).(func(context.Context, state.State, string, string) error); ok { + r1 = rf(ctx, s, key, host) } else { r1 = ret.Error(1) } @@ -132,12 +134,12 @@ func (_m *ClientConfigQueryIntf) GetAllForKeyAndHost(s *state.State, key string, } // RemoveAllForKey provides a mock function with given fields: s, key -func (_m *ClientConfigQueryIntf) RemoveAllForKey(s *state.State, key string) error { +func (_m *ClientConfigQueryIntf) RemoveAllForKey(ctx context.Context, s state.State, key string) error { ret := _m.Called(s, key) var r0 error - if rf, ok := ret.Get(0).(func(*state.State, string) error); ok { - r0 = rf(s, key) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string) error); ok { + r0 = rf(ctx, s, key) } else { r0 = ret.Error(0) } @@ -146,12 +148,12 @@ func (_m *ClientConfigQueryIntf) RemoveAllForKey(s *state.State, key string) err } // RemoveOneForKeyAndHost provides a mock function with given fields: s, key, host -func (_m *ClientConfigQueryIntf) RemoveOneForKeyAndHost(s *state.State, key string, host string) error { +func (_m *ClientConfigQueryIntf) RemoveOneForKeyAndHost(ctx context.Context, s state.State, key string, host string) error { ret := _m.Called(s, key, host) var r0 error - if rf, ok := ret.Get(0).(func(*state.State, string, string) error); ok { - r0 = rf(s, key, host) + if rf, ok := ret.Get(0).(func(context.Context, state.State, string, string) error); ok { + r0 = rf(ctx, s, key, host) } else { r0 = ret.Error(0) } diff --git a/microceph/mocks/ClientInterface.go b/microceph/mocks/ClientInterface.go index 0a7cb182..84172768 100644 --- a/microceph/mocks/ClientInterface.go +++ b/microceph/mocks/ClientInterface.go @@ -3,7 +3,7 @@ package mocks import ( - client "github.com/canonical/microcluster/client" + client "github.com/canonical/microcluster/v2/client" mock "github.com/stretchr/testify/mock" diff --git a/microceph/mocks/MemberCounterInterface.go b/microceph/mocks/MemberCounterInterface.go index 405aa548..e40321e2 100644 --- a/microceph/mocks/MemberCounterInterface.go +++ b/microceph/mocks/MemberCounterInterface.go @@ -2,7 +2,9 @@ package mocks import ( - state "github.com/canonical/microcluster/state" // mockery gets confused about import paths here + context "context" + + state "github.com/canonical/microcluster/v2/state" // mockery gets confused about import paths here mock "github.com/stretchr/testify/mock" ) @@ -12,22 +14,22 @@ type MemberCounterInterface struct { } // Count provides a mock function with given fields: s -func (_m *MemberCounterInterface) Count(s *state.State) (int, error) { +func (_m *MemberCounterInterface) Count(ctx context.Context, s state.State) (int, error) { ret := _m.Called(s) var r0 int var r1 error - if rf, ok := ret.Get(0).(func(*state.State) (int, error)); ok { - return rf(s) + if rf, ok := ret.Get(0).(func(context.Context, state.State) (int, error)); ok { + return rf(ctx, s) } - if rf, ok := ret.Get(0).(func(*state.State) int); ok { - r0 = rf(s) + if rf, ok := ret.Get(0).(func(context.Context, state.State) int); ok { + r0 = rf(ctx, s) } else { r0 = ret.Get(0).(int) } - if rf, ok := ret.Get(1).(func(*state.State) error); ok { - r1 = rf(s) + if rf, ok := ret.Get(1).(func(context.Context, state.State) error); ok { + r1 = rf(ctx, s) } else { r1 = ret.Error(1) } @@ -36,22 +38,22 @@ func (_m *MemberCounterInterface) Count(s *state.State) (int, error) { } // CountExclude provides a mock function with given fields: s, exclude -func (_m *MemberCounterInterface) CountExclude(s *state.State, exclude int64) (int, error) { +func (_m *MemberCounterInterface) CountExclude(ctx context.Context, s state.State, exclude int64) (int, error) { ret := _m.Called(s, exclude) var r0 int var r1 error - if rf, ok := ret.Get(0).(func(*state.State, int64) (int, error)); ok { - return rf(s, exclude) + if rf, ok := ret.Get(0).(func(context.Context, state.State, int64) (int, error)); ok { + return rf(ctx, s, exclude) } - if rf, ok := ret.Get(0).(func(*state.State, int64) int); ok { - r0 = rf(s, exclude) + if rf, ok := ret.Get(0).(func(context.Context, state.State, int64) int); ok { + r0 = rf(ctx, s, exclude) } else { r0 = ret.Get(0).(int) } - if rf, ok := ret.Get(1).(func(*state.State, int64) error); ok { - r1 = rf(s, exclude) + if rf, ok := ret.Get(1).(func(context.Context, state.State, int64) error); ok { + r1 = rf(ctx, s, exclude) } else { r1 = ret.Error(1) } diff --git a/microceph/mocks/MicroclusterState.go b/microceph/mocks/MicroclusterState.go new file mode 100644 index 00000000..6d1d5a35 --- /dev/null +++ b/microceph/mocks/MicroclusterState.go @@ -0,0 +1,30 @@ +package mocks + +import ( + "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" + state "github.com/canonical/microcluster/v2/state" +) + +// MockState mocks the internal microcluster state. +type MockState struct { + state.State + + URL *api.URL + ClusterName string +} + +// Name returns the name supplied to MockState. +func (m *MockState) Name() string { + return m.ClusterName +} + +// Address returns the address supplied to MockState. +func (m *MockState) Address() *api.URL { + return m.URL +} + +// ServerCert is set to always return nil to prematurely return before making database actions. +func (m *MockState) ServerCert() *shared.CertInfo { + return nil +} diff --git a/microceph/mocks/OSDQueryInterface.go b/microceph/mocks/OSDQueryInterface.go index 5afdb1d5..9e638107 100644 --- a/microceph/mocks/OSDQueryInterface.go +++ b/microceph/mocks/OSDQueryInterface.go @@ -3,7 +3,7 @@ package mocks import ( types "github.com/canonical/microceph/microceph/api/types" - state "github.com/canonical/microcluster/state" // mockery gets confused about import paths here + state "github.com/canonical/microcluster/v2/state" // mockery gets confused about import paths here mock "github.com/stretchr/testify/mock" ) diff --git a/microceph/mocks/PlacementIntf.go b/microceph/mocks/PlacementIntf.go index eedfffe3..a180fa27 100644 --- a/microceph/mocks/PlacementIntf.go +++ b/microceph/mocks/PlacementIntf.go @@ -3,6 +3,8 @@ package mocks import ( + context "context" + interfaces "github.com/canonical/microceph/microceph/interfaces" mock "github.com/stretchr/testify/mock" ) @@ -13,12 +15,12 @@ type PlacementIntf struct { } // DbUpdate provides a mock function with given fields: _a0 -func (_m *PlacementIntf) DbUpdate(_a0 interfaces.StateInterface) error { +func (_m *PlacementIntf) DbUpdate(ctx context.Context, _a0 interfaces.StateInterface) error { ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func(interfaces.StateInterface) error); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, interfaces.StateInterface) error); ok { + r0 = rf(ctx, _a0) } else { r0 = ret.Error(0) } @@ -69,12 +71,12 @@ func (_m *PlacementIntf) PostPlacementCheck(_a0 interfaces.StateInterface) error } // ServiceInit provides a mock function with given fields: _a0 -func (_m *PlacementIntf) ServiceInit(_a0 interfaces.StateInterface) error { +func (_m *PlacementIntf) ServiceInit(ctx context.Context, _a0 interfaces.StateInterface) error { ret := _m.Called(_a0) var r0 error - if rf, ok := ret.Get(0).(func(interfaces.StateInterface) error); ok { - r0 = rf(_a0) + if rf, ok := ret.Get(0).(func(context.Context, interfaces.StateInterface) error); ok { + r0 = rf(ctx, _a0) } else { r0 = ret.Error(0) } diff --git a/microceph/mocks/StateInterface.go b/microceph/mocks/StateInterface.go index ea03fe29..0db95e12 100644 --- a/microceph/mocks/StateInterface.go +++ b/microceph/mocks/StateInterface.go @@ -2,7 +2,7 @@ package mocks import ( - state "github.com/canonical/microcluster/state" // mockery gets confused about import paths here + state "github.com/canonical/microcluster/v2/state" // mockery gets confused about import paths here mock "github.com/stretchr/testify/mock" ) @@ -12,15 +12,15 @@ type StateInterface struct { } // ClusterState provides a mock function with given fields: -func (_m *StateInterface) ClusterState() *state.State { +func (_m *StateInterface) ClusterState() state.State { ret := _m.Called() - var r0 *state.State - if rf, ok := ret.Get(0).(func() *state.State); ok { + var r0 state.State + if rf, ok := ret.Get(0).(func() state.State); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*state.State) + r0 = ret.Get(0).(state.State) } } diff --git a/microceph/version/version.go b/microceph/version/version.go index febdc3e0..3a895191 100644 --- a/microceph/version/version.go +++ b/microceph/version/version.go @@ -1,5 +1,9 @@ // Package version provides shared version information. package version -// Version is the current API version. -const Version = "0.1" +var version string + +// Version is set by the build system. +func Version() string { + return version +} diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index dbf6371e..ca9591b0 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -317,8 +317,8 @@ parts: export MC_VERSION="ceph-version: $pkg_version; microceph-git: $git_version" # Build the binaries - go build -trimpath -o "${CRAFT_PART_INSTALL}/bin/microceph" -ldflags "-X 'main.Version=${MC_VERSION}'" ./cmd/microceph - go build -trimpath -o "${CRAFT_PART_INSTALL}/bin/microcephd" -tags=libsqlite3 ./cmd/microcephd + go build -trimpath -o "${CRAFT_PART_INSTALL}/bin/microceph" -ldflags "-X 'github.com/canonical/microceph/microceph/version.version=${MC_VERSION}'" ./cmd/microceph + go build -trimpath -o "${CRAFT_PART_INSTALL}/bin/microcephd" -tags=libsqlite3 -ldflags "-X 'github.com/canonical/microceph/microceph/version.version=${MC_VERSION}'" ./cmd/microcephd # Strip binaries strip -s "${CRAFT_PART_INSTALL}/bin/microceph"