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

Fix Agent upgrade 8.2->8.3 #578

Merged
merged 6 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
77 changes: 72 additions & 5 deletions internal/pkg/agent/application/upgrade/step_mark.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,58 @@ type UpdateMarker struct {
Action *fleetapi.ActionUpgrade `json:"action" yaml:"action"`
}

// MarkerActionUpgrade adapter struct compatible with pre 8.3 version of the marker file format
type MarkerActionUpgrade struct {
ActionID string `yaml:"id"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a part of the update failed because I changed the serialization of the upgrade action with

type ActionUpgrade struct {
ActionID string `yaml:"action_id"`

I tried to make it more inline in fleet-server/model/schema.json (though fleet-server will remap action_id to id when giving an agent its actions on checkin).
Should we revisit that?

ActionType string `yaml:"type"`
Version string `yaml:"version"`
SourceURI string `yaml:"source_uri,omitempty"`
}

func convertToMarkerAction(a *fleetapi.ActionUpgrade) *MarkerActionUpgrade {
if a == nil {
return nil
}
return &MarkerActionUpgrade{
ActionID: a.ActionID,
ActionType: a.ActionType,
Version: a.Version,
SourceURI: a.SourceURI,
}
}

func convertToActionUpgrade(a *MarkerActionUpgrade) *fleetapi.ActionUpgrade {
if a == nil {
return nil
}
return &fleetapi.ActionUpgrade{
ActionID: a.ActionID,
ActionType: a.ActionType,
Version: a.Version,
SourceURI: a.SourceURI,
}
}

type updateMarkerSerializer struct {
Hash string `yaml:"hash"`
UpdatedOn time.Time `yaml:"updated_on"`
PrevVersion string `yaml:"prev_version"`
PrevHash string `yaml:"prev_hash"`
Acked bool `yaml:"acked"`
Action *MarkerActionUpgrade `yaml:"action"`
}

func newMarkerSerializer(m *UpdateMarker) *updateMarkerSerializer {
return &updateMarkerSerializer{
Hash: m.Hash,
UpdatedOn: m.UpdatedOn,
PrevVersion: m.PrevVersion,
PrevHash: m.PrevHash,
Acked: m.Acked,
Action: convertToMarkerAction(m.Action),
}
}

// markUpgrade marks update happened so we can handle grace period
func (u *Upgrader) markUpgrade(_ context.Context, hash string, action Action) error {
prevVersion := release.Version()
Expand All @@ -46,15 +98,15 @@ func (u *Upgrader) markUpgrade(_ context.Context, hash string, action Action) er
prevHash = prevHash[:hashLen]
}

marker := UpdateMarker{
marker := &UpdateMarker{
Hash: hash,
UpdatedOn: time.Now(),
PrevVersion: prevVersion,
PrevHash: prevHash,
Action: action.FleetAction(),
}

markerBytes, err := yaml.Marshal(marker)
markerBytes, err := yaml.Marshal(newMarkerSerializer(marker))
if err != nil {
return errors.New(err, errors.TypeConfig, "failed to parse marker file")
}
Expand Down Expand Up @@ -103,16 +155,31 @@ func LoadMarker() (*UpdateMarker, error) {
return nil, err
}

marker := &UpdateMarker{}
marker := &updateMarkerSerializer{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this work if marker already contains new form of action ID?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the action_id breakage is new and specific to 8.3 branch, it was not releases as a part of the 8.2.x, I tested the upgrade between latest 8.2.4 and 8.3

if err := yaml.Unmarshal(markerBytes, &marker); err != nil {
return nil, err
}

return marker, nil
return &UpdateMarker{
Hash: marker.Hash,
UpdatedOn: marker.UpdatedOn,
PrevVersion: marker.PrevVersion,
PrevHash: marker.PrevHash,
Acked: marker.Acked,
Action: convertToActionUpgrade(marker.Action),
}, nil
}

func saveMarker(marker *UpdateMarker) error {
markerBytes, err := yaml.Marshal(marker)
makerSerializer := &updateMarkerSerializer{
Hash: marker.Hash,
UpdatedOn: marker.UpdatedOn,
PrevVersion: marker.PrevVersion,
PrevHash: marker.PrevHash,
Acked: marker.Acked,
Action: convertToMarkerAction(marker.Action),
}
markerBytes, err := yaml.Marshal(makerSerializer)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/fleetapi/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func (a *ActionPolicyChange) Expiration() (time.Time, error) {

// ActionUpgrade is a request for agent to upgrade.
type ActionUpgrade struct {
ActionID string `yaml:"id"`
ActionID string `yaml:"action_id"`
ActionType string `yaml:"type"`
ActionStartTime string `json:"start_time" yaml:"start_time,omitempty"` // TODO change to time.Time in unmarshal
ActionExpiration string `json:"expiration" yaml:"expiration,omitempty"`
Expand Down