Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

misc #391

Merged
merged 30 commits into from
Aug 11, 2023
Merged

misc #391

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e5fd59a
Remove spurious "mode xxx" message from ip.netns start/stop
cvaroqui Aug 8, 2023
db2f0c7
Fix a ip.netns stack on shutdown/stop when already stopped
cvaroqui Aug 8, 2023
a9dc70e
Automatically set the provisioned resource flag for up resources
cvaroqui Aug 8, 2023
9706899
Allow the "om3 svc create -s s1" syntax
cvaroqui Aug 8, 2023
9dd8ff7
Fix om node events templating
cvaroqui Aug 8, 2023
afc6bdc
Fix a prov and unprov orchestration stale case
cvaroqui Aug 9, 2023
22d3594
Move a imon log to debug and rephrase
cvaroqui Aug 9, 2023
be5b74a
Fix the object monitor placement aggregation
cvaroqui Aug 9, 2023
6717397
Discard unprovisioned instances from the IsHALeader evaluation
cvaroqui Aug 9, 2023
2d64b81
Fix the placed orchestration to use IsHALeader instead of IsLeader
cvaroqui Aug 9, 2023
0b6ba6f
Tweak log message
cvaroqui Aug 10, 2023
966c70b
Remove the "reached" mon state
cvaroqui Aug 10, 2023
2fb76f0
Document the set --param and --value flags and not ported to om3
cvaroqui Aug 10, 2023
c9d53b2
Fix "om ... delete --rid ..." not actually deleting
cvaroqui Aug 10, 2023
5790d9c
Display the basename of argv[0] in the cobra help message
cvaroqui Aug 10, 2023
2ff5ca1
Display the SetInstanceMonitor result in "om <sel> action" output
cvaroqui Aug 10, 2023
1e48e37
Fix the standby up/down icons in "om mon"
cvaroqui Aug 11, 2023
9d84a2b
Implement SetNodeMonitor error reporting
cvaroqui Aug 11, 2023
7d6df19
Fix a nodeaction http error code mismatch on POST /node_monitor
cvaroqui Aug 11, 2023
e0a6d6c
Fix handling of stdby states in stop and start orchestrations
cvaroqui Aug 11, 2023
4065114
Report SetObjectMonitor errors from POST /object/switch_to
cvaroqui Aug 11, 2023
78072b3
Set OrchestrationIsDone on abort orchestration too
cvaroqui Aug 11, 2023
dbd83a1
Fix a fmt in SetInstanceMonitor
cvaroqui Aug 11, 2023
f93d008
Fix imon testing
cvaroqui Aug 11, 2023
3d4ad2c
Better comments on imon done() and doneAndIdle()
cvaroqui Aug 11, 2023
4f68cef
Remove now unused imon.clearStoppedIfObjectStatusAvailUp()
cvaroqui Aug 11, 2023
0161a1a
Define xconfig.DeleteSections() as a pointer receiver
cvaroqui Aug 11, 2023
b35c41b
Use a 409 Conflict error on POST /object/monitor and co
cvaroqui Aug 11, 2023
f512241
Refuse a new orchestration while another is not finished
cvaroqui Aug 11, 2023
fd24177
Add sanity checks in POST /object/monitor and co
cvaroqui Aug 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@

* **breaking change:** "om node freeze" is now local only. Use "om cluster freeze" for the orchestrated freeze of all nodes. Same applies to "unfreeze" and its hidden alias "thaw".

* **breaking change:** "om ... set|unset" no longer accept --param and --value. Use --kw instead, which was also supported in v2.

* "om monitor" instance availability icons changes:

standby down: s => x
standby up: S => o

### driver ip

* **breaking change:** Drop the `dns_name_suffix`, `provisioner`, `dns_update` keywords. The zone management feature of the collector will be dropped in the collector too.
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var (
bashCompletionFunction string

root = &cobra.Command{
Use: "om3",
Use: filepath.Base(os.Args[0]),
Short: "Manage the opensvc cluster infrastructure and its deployed services.",
PersistentPreRunE: persistentPreRunE,
SilenceUsage: true,
Expand Down
6 changes: 3 additions & 3 deletions core/cluster/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ var (
iconDownIssue = red("X")
iconPlacementAlert = red("^")
iconProvisionAlert = red("P")
iconStandbyDown = red("o")
iconStandbyUpIssue = red("x")
iconStandbyDown = red("x")
iconStandbyUpIssue = red("o")
iconUndef = red("?")
iconFrozen = blue("*")
iconDown = hiblack("X")
iconDRP = hiblack("#")
iconLeader = hiblack("^")
iconNotApplicable = hiblack("/")
iconPreserved = hiblack("?")
iconStandbyUp = hiblack("x")
iconStandbyUp = hiblack("o")
)

type (
Expand Down
5 changes: 3 additions & 2 deletions core/commands/node_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,12 @@ func (t *CmdNodeEvents) doEvent(e event.Event) {
ce := e.AsConcreteEvent(msg)
if t.templ != nil {
var i any
if err := json.Unmarshal(e.Data, &i); err != nil {
if b, err := json.Marshal(ce); err != nil {
return
} else if err := json.Unmarshal(b, &i); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "unmarshal event data in a any-typed variable: %s\n", err)
return
}
msg.GetLabels()
if err := t.templ.Execute(os.Stdout, i); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "template execute error %s\n", err)
}
Expand Down
14 changes: 11 additions & 3 deletions core/commands/object_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,24 @@ func (t *CmdObjectCreate) Run(selector, kind string) error {
}

func (t *CmdObjectCreate) parseSelector(selector, kind string) (path.T, error) {
if selector == "" {
var objectPath string
if selector != "" && t.ObjectSelector != "" {
return path.T{}, fmt.Errorf("use either 'om <path> create' or 'om <kind> create -s <path>', not 'om <path> create -s <path>'")
} else if selector == "" && t.ObjectSelector != "" {
objectPath = t.ObjectSelector
} else {
objectPath = selector
}
if objectPath == "" {
// allowed with multi-definitions fed via stdin
return path.T{}, nil
}
p, err := path.Parse(selector)
p, err := path.Parse(objectPath)
if err != nil {
return p, err
}
// now we know the path is valid. Verify it is non-existing or matches only one object.
objectSelector := mergeSelector(selector, t.ObjectSelector, kind, "**")
objectSelector := mergeSelector(objectPath, "", kind, "**")
paths, err := objectselector.NewSelection(
objectSelector,
objectselector.SelectionWithLocal(t.Local),
Expand Down
32 changes: 25 additions & 7 deletions core/instance/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package instance

import (
"encoding/json"
"errors"
"fmt"
"strings"
"time"
Expand All @@ -15,15 +16,28 @@ type (
GlobalExpect MonitorGlobalExpect `json:"global_expect" yaml:"global_expect"`
GlobalExpectUpdatedAt time.Time `json:"global_expect_updated_at" yaml:"global_expect_updated_at"`
GlobalExpectOptions any `json:"global_expect_options" yaml:"global_expect_options"`
IsLeader bool `json:"is_leader" yaml:"is_leader"`
IsHALeader bool `json:"is_ha_leader" yaml:"is_ha_leader"`
LocalExpect MonitorLocalExpect `json:"local_expect" yaml:"local_expect"`
LocalExpectUpdatedAt time.Time `json:"local_expect_updated_at" yaml:"local_expect_updated_at"`

// IsLeader flags the instance as the one where to provision as leader.
// The provisioning leader is responsible for preparing the shared resources.
// There can be only one leader, whatever the topology.
IsLeader bool `json:"is_leader" yaml:"is_leader"`

// IsHALeader flags the instances to start automatically if orchestrate=ha
// or when the admin posted a start orchestration.
// There can be one leader on a failover object, or many leaders with a flex topology.
IsHALeader bool `json:"is_ha_leader" yaml:"is_ha_leader"`

LocalExpect MonitorLocalExpect `json:"local_expect" yaml:"local_expect"`
LocalExpectUpdatedAt time.Time `json:"local_expect_updated_at" yaml:"local_expect_updated_at"`

// OrchestrationId is the accepted orchestration id that will be unset
// when orchestration is reached on local node
OrchestrationId uuid.UUID `json:"orchestration_id" yaml:"orchestration_id"`

// OrchestrationIsDone is set by the orchestration when it decides the instance state has reached its target.
// A orchestration is cleaned up when all instance monitors have OrchestrationIsDone set.
OrchestrationIsDone bool `json:"orchestration_is_done" yaml:"orchestration_is_done"`

SessionId uuid.UUID `json:"session_id" yaml:"session_id"`
State MonitorState `json:"state" yaml:"state"`
StateUpdatedAt time.Time `json:"state_updated_at" yaml:"state_updated_at"`
Expand Down Expand Up @@ -73,7 +87,6 @@ const (
MonitorStateBootFailed
MonitorStateBooting
MonitorStateIdle
MonitorStateReached
MonitorStateDeleted
MonitorStateDeleting
MonitorStateFreezeFailed
Expand Down Expand Up @@ -137,7 +150,6 @@ var (
MonitorStateProvisioning: "provisioning",
MonitorStateProvisionFailed: "provision failed",
MonitorStatePurgeFailed: "purge failed",
MonitorStateReached: "reached",
MonitorStateReady: "ready",
MonitorStateShutting: "shutting",
MonitorStateStarted: "started",
Expand Down Expand Up @@ -172,7 +184,6 @@ var (
"provisioning": MonitorStateProvisioning,
"provision failed": MonitorStateProvisionFailed,
"purge failed": MonitorStatePurgeFailed,
"reached": MonitorStateReached,
"ready": MonitorStateReady,
"shutting": MonitorStateShutting,
"started": MonitorStateStarted,
Expand Down Expand Up @@ -232,6 +243,13 @@ var (
"unprovisioned": MonitorGlobalExpectUnprovisioned,
"none": MonitorGlobalExpectNone,
}

ErrInvalidGlobalExpect = errors.New("invalid instance monitor global expect")
ErrInvalidLocalExpect = errors.New("invalid instance monitor local expect")
ErrInvalidState = errors.New("invalid instance monitor state")
ErrSameGlobalExpect = errors.New("instance monitor global expect is already set to the same value")
ErrSameLocalExpect = errors.New("instance monitor local expect is already set to the same value")
ErrSameState = errors.New("instance monitor state is already set to the same value")
)

func (t MonitorState) IsDoing() bool {
Expand Down
8 changes: 8 additions & 0 deletions core/node/monitor.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package node

import (
"errors"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -138,6 +139,13 @@ var (
MonitorStateShutting: nil,
MonitorStateRejoin: nil,
}

ErrInvalidGlobalExpect = errors.New("invalid node monitor global expect")
ErrInvalidLocalExpect = errors.New("invalid node monitor local expect")
ErrInvalidState = errors.New("invalid node monitor state")
ErrSameGlobalExpect = errors.New("node monitor global expect is already set to the same value")
ErrSameLocalExpect = errors.New("node monitor local expect is already set to the same value")
ErrSameState = errors.New("node monitor state is already set to the same value")
)

func (t MonitorState) IsDoing() bool {
Expand Down
8 changes: 6 additions & 2 deletions core/nodeaction/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,13 @@ func (t T) DoAsync() error {
case 400:
return fmt.Errorf("%s", resp.JSON400)
case 401:
return fmt.Errorf("%s", resp.JSON403)
case 403:
return fmt.Errorf("%s", resp.JSON401)
case 403:
return fmt.Errorf("%s", resp.JSON403)
case 408:
return fmt.Errorf("%s", resp.JSON408)
case 409:
return fmt.Errorf("%s", resp.JSON409)
case 500:
return fmt.Errorf("%s", resp.JSON500)
default:
Expand Down
12 changes: 12 additions & 0 deletions core/object/actor_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/opensvc/om3/core/actioncontext"
"github.com/opensvc/om3/core/colorstatus"
"github.com/opensvc/om3/core/instance"
"github.com/opensvc/om3/core/provisioned"
"github.com/opensvc/om3/core/rawconfig"
"github.com/opensvc/om3/core/resource"
"github.com/opensvc/om3/core/status"
Expand Down Expand Up @@ -128,6 +129,17 @@ func (t *actor) resourceStatusEval(ctx context.Context, data *instance.Status) e
var mu sync.Mutex
err := t.ResourceSets().Do(ctx, t, "", "status", func(ctx context.Context, r resource.Driver) error {
xd := resource.GetExposedStatus(ctx, r)

// If the resource is up but the provisioned flag is unset, set
// the provisioned flag.
if xd.Provisioned.State == provisioned.False {
switch xd.Status {
case status.Up, status.StandbyUp:
resource.SetProvisioned(ctx, r)
xd.Provisioned.State = provisioned.True
}
}

mu.Lock()
resources = append(resources, xd)
data.Resources = resources
Expand Down
49 changes: 32 additions & 17 deletions core/objectaction/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,13 @@ func (t T) DoAsync() error {
case 400:
err = fmt.Errorf("%s", resp.JSON400)
case 401:
err = fmt.Errorf("%s", resp.JSON403)
case 403:
err = fmt.Errorf("%s", resp.JSON401)
case 403:
err = fmt.Errorf("%s", resp.JSON403)
case 408:
err = fmt.Errorf("%s", resp.JSON408)
case 409:
err = fmt.Errorf("%s", resp.JSON409)
case 500:
err = fmt.Errorf("%s", resp.JSON500)
}
Expand All @@ -431,37 +435,48 @@ func (t T) DoAsync() error {
case 400:
err = fmt.Errorf("%s", resp.JSON400)
case 401:
err = fmt.Errorf("%s", resp.JSON403)
case 403:
err = fmt.Errorf("%s", resp.JSON401)
case 403:
err = fmt.Errorf("%s", resp.JSON403)
case 408:
err = fmt.Errorf("%s", resp.JSON408)
case 409:
err = fmt.Errorf("%s", resp.JSON409)
case 500:
err = fmt.Errorf("%s", resp.JSON500)
}
}
if err != nil {
errs = errors.Join(errs, err)
} else {
toWait++
}
var monitorUpdateQueued api.MonitorUpdateQueued
var r result
if err := json.Unmarshal(b, &monitorUpdateQueued); err == nil {
r = result{
OrchestrationId: monitorUpdateQueued.OrchestrationId,
Path: p.String(),
}
} else {
if err != nil {
r = result{
Error: err,
Path: p.String(),
}
} else {
toWait++
var monitorUpdateQueued api.MonitorUpdateQueued
if err := json.Unmarshal(b, &monitorUpdateQueued); err == nil {
r = result{
OrchestrationId: monitorUpdateQueued.OrchestrationId,
Path: p.String(),
}
} else {
r = result{
Error: err,
Path: p.String(),
}
}
}
rs = append(rs, r)
}
human := func() string {
s := ""
for _, r := range rs {
s += fmt.Sprintf("%s: %s\n", r.Path, r.OrchestrationId)
if r.Error != nil {
s += fmt.Sprintf("%s %s %s\n", r.OrchestrationId, r.Path, rawconfig.Colorize.Error(r.Error))
} else {
s += fmt.Sprintf("%s %s\n", r.OrchestrationId, r.Path)
}
}
return s
}
Expand Down
3 changes: 2 additions & 1 deletion core/xconfig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,7 @@ func (t *T) CommitDataToInvalid(configData rawconfig.T, configPath string) error
return t.rawCommit(configData, configPath, false)
}

func (t T) DeleteSections(sections []string) error {
func (t *T) DeleteSections(sections []string) error {
deleted := 0
for _, section := range sections {
if _, err := t.file.GetSection(section); err != nil {
Expand All @@ -1205,6 +1205,7 @@ func (t T) DeleteSections(sections []string) error {
deleted++
}
if deleted > 0 {
t.changed = true
t.Commit()
}
return nil
Expand Down
26 changes: 26 additions & 0 deletions daemon/api/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,10 @@ paths:
$ref: '#/components/responses/401'
403:
$ref: '#/components/responses/403'
408:
$ref: '#/components/responses/408'
409:
$ref: '#/components/responses/409'
500:
$ref: '#/components/responses/500'
/nodes/info:
Expand Down Expand Up @@ -696,6 +700,10 @@ paths:
$ref: '#/components/responses/401'
403:
$ref: '#/components/responses/403'
408:
$ref: '#/components/responses/408'
409:
$ref: '#/components/responses/409'
500:
$ref: '#/components/responses/500'
/object/progress:
Expand Down Expand Up @@ -773,6 +781,10 @@ paths:
$ref: '#/components/responses/401'
403:
$ref: '#/components/responses/403'
408:
$ref: '#/components/responses/408'
409:
$ref: '#/components/responses/409'
500:
$ref: '#/components/responses/500'
/pools:
Expand Down Expand Up @@ -1920,6 +1932,20 @@ components:
application/json:
schema:
$ref: "#/components/schemas/Problem"
'408':
type: object
description: Request Timeout
content:
application/json:
schema:
$ref: "#/components/schemas/Problem"
'409':
type: object
description: Conflict
content:
application/json:
schema:
$ref: "#/components/schemas/Problem"
'500':
type: object
description: Internal Server Error
Expand Down
Loading