Skip to content

Commit

Permalink
Set the 'require-osd-release' option on startup
Browse files Browse the repository at this point in the history
Signed-off-by: Luciano Lo Giudice <[email protected]>
  • Loading branch information
lmlg committed Nov 10, 2024
1 parent ad8b261 commit c2ac588
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
99 changes: 99 additions & 0 deletions microceph/ceph/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package ceph
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"reflect"
"strings"
"time"

"github.com/canonical/lxd/shared/logger"
Expand All @@ -12,6 +15,100 @@ import (
"github.com/canonical/microceph/microceph/interfaces"
)

type cephVersionElem map[string]int32

type cephVersion struct {
Mon cephVersionElem `json:"mon"`
Mgr cephVersionElem `json:"mgr"`
Osd cephVersionElem `json:"osd"`
Mds cephVersionElem `json:"mds"`
Overall cephVersionElem `json:"overall"`
}

func checkVersions() (bool, error) {
out, err := processExec.RunCommand("ceph", "versions")
if err != nil {
return false, fmt.Errorf("Failed to get Ceph versions: %w", err)
}

var cephVer cephVersion
err = json.Unmarshal([]byte(out), &cephVer)
if err != nil {
return false, fmt.Errorf("Failed to unmarshal Ceph versions: %w", err)
}

if len(cephVer.Overall) > 1 {
logger.Debug("Not all upgrades have completed")
return false, nil
}

if len(cephVer.Osd) < 1 {
logger.Debug("No OSD versions found")
return false, nil
}

return true, nil
}

func osdReleaseRequired(version string) (bool, error) {
out, err := processExec.RunCommand("ceph", "osd", "dump", "-f", "json")
if err != nil {
return false, fmt.Errorf("Failed to get OSD dump: %w", err)
}

var result map[string]any
err = json.Unmarshal([]byte(out), &result)
if err != nil {
return false, fmt.Errorf("Failed to unmarshal OSD dump: %w", err)
}

return result["require_osd_release"].(string) != version, nil
}

func PostRefresh() error {
currentVersion, err := processExec.RunCommand("ceph", "-v")
if err != nil {
return err
}

lastPos := strings.LastIndex(currentVersion, " ")
if lastPos < 0 {
return fmt.Errorf("invalid version string: %s", currentVersion)
}

currentVersion = currentVersion[0:lastPos]
lastPos = strings.LastIndex(currentVersion, " ")
if lastPos < 0 {
return fmt.Errorf("invalid version string: %s", currentVersion)
}

currentVersion = currentVersion[lastPos+1 : len(currentVersion)]
allVersionsEqual, err := checkVersions()

if err != nil {
return err
}

if !allVersionsEqual {
return nil
}

mustUpdate, err := osdReleaseRequired(currentVersion)
if err != nil {
return err
}

if mustUpdate {
_, err = processExec.RunCommand("ceph", "osd", "require-osd-release",
currentVersion, "--yes-i-really-mean-it")
if err != nil {
return err
}
}

return nil
}

// Start is run on daemon startup.
func Start(ctx context.Context, s interfaces.StateInterface) error {
// Start background loop to refresh the config every minute if needed.
Expand Down Expand Up @@ -67,5 +164,7 @@ func Start(ctx context.Context, s interfaces.StateInterface) error {
}
}()

go PostRefresh()

return nil
}
57 changes: 57 additions & 0 deletions microceph/ceph/start_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package ceph

import (
"testing"

"github.com/canonical/microceph/microceph/mocks"
"github.com/canonical/microceph/microceph/tests"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

type startSuite struct {
tests.BaseSuite
}

func TestStart(t *testing.T) {
suite.Run(t, new(startSuite))
}

func addExpected(r *mocks.Runner) {
version := `ceph version 19.2.0 (e7ad5345525c7aa95470c26863873b581076945d) squid (stable)`
versionsJson := `{
"mon": {
"ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)": 1
},
"mgr": {
"ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)": 1
},
"osd": {
"ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)": 4
},
"mds": {
"ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)": 1
},
"overall": {
"ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)": 7
}
}`
osdDump := `{"require_osd_release": "reef"}`

r.On("RunCommand", "ceph", "-v").Return(version, nil).Once()
r.On("RunCommand", "ceph", "versions").Return(versionsJson, nil).Once()
r.On("RunCommand", "ceph", "osd", "dump", "-f", "json").Return(osdDump, nil).Once()
r.On("RunCommand", "ceph", "osd", "require-osd-release",
"squid", "--yes-i-really-mean-it").Return("ok", nil).Once()
}

func (s *startSuite) TestStart() {
r := mocks.NewRunner(s.T())

addExpected(r)
processExec = r

err := PostRefresh()
assert.NoError(s.T(), err)
}

0 comments on commit c2ac588

Please sign in to comment.