Skip to content

Commit

Permalink
satellite/overlay: insert node software update events into node events
Browse files Browse the repository at this point in the history
When a node checks in and its version is below the minimum, insert
BelowMinVersion event into node events

Change-Id: I0e437ac34496778369515cbc40c15676da8b27ae
  • Loading branch information
cam-a authored and Storj Robot committed Nov 11, 2022
1 parent d856569 commit 2a25974
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 38 deletions.
82 changes: 55 additions & 27 deletions satellite/overlay/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"storj.io/common/storj"
"storj.io/common/storj/location"
"storj.io/common/sync2"
"storj.io/private/version"
"storj.io/storj/satellite/geoip"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/metabase"
Expand Down Expand Up @@ -140,15 +141,17 @@ const (

// NodeCheckInInfo contains all the info that will be updated when a node checkins.
type NodeCheckInInfo struct {
NodeID storj.NodeID
Address *pb.NodeAddress
LastNet string
LastIPPort string
IsUp bool
Operator *pb.NodeOperator
Capacity *pb.NodeCapacity
Version *pb.NodeVersion
CountryCode location.CountryCode
NodeID storj.NodeID
Address *pb.NodeAddress
LastNet string
LastIPPort string
IsUp bool
Operator *pb.NodeOperator
Capacity *pb.NodeCapacity
Version *pb.NodeVersion
CountryCode location.CountryCode
SoftwareUpdateEmailSent bool
VersionBelowMin bool
}

// InfoResponse contains node dossier info requested from the storage node.
Expand Down Expand Up @@ -220,23 +223,24 @@ type ExitStatusRequest struct {
// NodeDossier is the complete info that the satellite tracks for a storage node.
type NodeDossier struct {
pb.Node
Type pb.NodeType
Operator pb.NodeOperator
Capacity pb.NodeCapacity
Reputation NodeStats
Version pb.NodeVersion
Contained bool
Disqualified *time.Time
DisqualificationReason *DisqualificationReason
UnknownAuditSuspended *time.Time
OfflineSuspended *time.Time
OfflineUnderReview *time.Time
PieceCount int64
ExitStatus ExitStatus
CreatedAt time.Time
LastNet string
LastIPPort string
CountryCode location.CountryCode
Type pb.NodeType
Operator pb.NodeOperator
Capacity pb.NodeCapacity
Reputation NodeStats
Version pb.NodeVersion
Contained bool
Disqualified *time.Time
DisqualificationReason *DisqualificationReason
UnknownAuditSuspended *time.Time
OfflineSuspended *time.Time
OfflineUnderReview *time.Time
PieceCount int64
ExitStatus ExitStatus
CreatedAt time.Time
LastNet string
LastIPPort string
CountryCode location.CountryCode
LastSoftwareUpdateEmail *time.Time
}

// NodeStats contains statistics about a node.
Expand Down Expand Up @@ -633,9 +637,33 @@ func (service *Service) UpdateCheckIn(ctx context.Context, node NodeCheckInInfo,
node.CountryCode = oldInfo.CountryCode
}

if service.config.SendNodeEmails && service.config.Node.MinimumVersion != "" {
min, err := version.NewSemVer(service.config.Node.MinimumVersion)
if err != nil {
return err
}
v, err := version.NewSemVer(node.Version.GetVersion())
if err != nil {
return err
}

if v.Compare(min) == -1 {
node.VersionBelowMin = true
if oldInfo.LastSoftwareUpdateEmail == nil ||
oldInfo.LastSoftwareUpdateEmail.Add(service.config.NodeSoftwareUpdateEmailCooldown).Before(time.Now()) {
_, err = service.nodeEvents.Insert(ctx, node.Operator.Email, node.NodeID, nodeevents.BelowMinVersion)
if err != nil {
service.log.Error("could not insert node software below minimum version into node events", zap.Error(err))
} else {
node.SoftwareUpdateEmailSent = true
}
}
}
}

if dbStale || addrChanged || walletChanged || verChanged || spaceChanged ||
oldInfo.LastNet != node.LastNet || oldInfo.LastIPPort != node.LastIPPort ||
oldInfo.CountryCode != node.CountryCode {
oldInfo.CountryCode != node.CountryCode || node.SoftwareUpdateEmailSent {
err = service.db.UpdateCheckIn(ctx, node, timestamp, service.config.Node)
if err != nil {
return Error.Wrap(err)
Expand Down
32 changes: 31 additions & 1 deletion satellite/overlay/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ func getNodeInfo(nodeID storj.NodeID) overlay.NodeCheckInInfo {
Wallet: "0x123",
},
Version: &pb.NodeVersion{
Version: "v0.0.0",
Version: "v3.0.0",
CommitHash: "",
Timestamp: time.Time{},
Release: false,
Expand Down Expand Up @@ -999,3 +999,33 @@ func TestUpdateCheckInNodeEventOnline(t *testing.T) {
require.Equal(t, node.ID(), ne.NodeID)
})
}

func TestUpdateCheckInBelowMinVersionEvent(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 1, UplinkCount: 0,
Reconfigure: testplanet.Reconfigure{
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
config.Overlay.SendNodeEmails = true
config.Overlay.Node.MinimumVersion = "v2.0.0"
},
},
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
service := planet.Satellites[0].Overlay.Service
node := planet.StorageNodes[0]
node.Contact.Chore.Pause(ctx)

// Set version to above minimum because we have no control over initial testplanet check in and it
// fails the test due to wait period between version update emails
checkInInfo := getNodeInfo(node.ID())
checkInInfo.Version = &pb.NodeVersion{Version: "v2.0.0"}
require.NoError(t, service.UpdateCheckIn(ctx, checkInInfo, time.Now()))
checkInInfo.Version = &pb.NodeVersion{Version: "v1.0.0"}
require.NoError(t, service.UpdateCheckIn(ctx, checkInInfo, time.Now()))

ne, err := planet.Satellites[0].DB.NodeEvents().GetLatestByEmailAndEvent(ctx, checkInInfo.Operator.Email, nodeevents.BelowMinVersion)
require.NoError(t, err)
require.Equal(t, node.ID(), ne.NodeID)
require.Equal(t, checkInInfo.Operator.Email, ne.Email)
require.Equal(t, nodeevents.BelowMinVersion, ne.Event)
})
}
33 changes: 23 additions & 10 deletions satellite/satellitedb/overlaycache.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,15 +1068,16 @@ func convertDBNode(ctx context.Context, info *dbx.Node) (_ *overlay.NodeDossier,
Timestamp: info.Timestamp,
Release: info.Release,
},
Disqualified: info.Disqualified,
DisqualificationReason: (*overlay.DisqualificationReason)(info.DisqualificationReason),
UnknownAuditSuspended: info.UnknownAuditSuspended,
OfflineSuspended: info.OfflineSuspended,
OfflineUnderReview: info.UnderReview,
PieceCount: info.PieceCount,
ExitStatus: exitStatus,
CreatedAt: info.CreatedAt,
LastNet: info.LastNet,
Disqualified: info.Disqualified,
DisqualificationReason: (*overlay.DisqualificationReason)(info.DisqualificationReason),
UnknownAuditSuspended: info.UnknownAuditSuspended,
OfflineSuspended: info.OfflineSuspended,
OfflineUnderReview: info.UnderReview,
PieceCount: info.PieceCount,
ExitStatus: exitStatus,
CreatedAt: info.CreatedAt,
LastNet: info.LastNet,
LastSoftwareUpdateEmail: info.LastSoftwareUpdateEmail,
}
if info.LastIpPort != nil {
node.LastIPPort = *info.LastIpPort
Expand Down Expand Up @@ -1255,6 +1256,10 @@ func (cache *overlaycache) UpdateCheckIn(ctx context.Context, node overlay.NodeC
last_ip_port=$16,
wallet_features=$17,
country_code=$18
last_software_update_email = CASE
WHEN $19::bool IS TRUE THEN $15::timestamptz
WHEN $20::bool IS FALSE THEN NULL
END
WHERE id = $1
`, // args $1 - $4
node.NodeID.Bytes(), node.Address.GetAddress(), node.LastNet, node.Address.GetTransport(),
Expand All @@ -1272,6 +1277,8 @@ func (cache *overlaycache) UpdateCheckIn(ctx context.Context, node overlay.NodeC
walletFeatures,
// args $18,
node.CountryCode.String(),
// args $19 - $20
node.SoftwareUpdateEmailSent, node.VersionBelowMin,
)

if err == nil {
Expand Down Expand Up @@ -1327,7 +1334,11 @@ func (cache *overlaycache) UpdateCheckIn(ctx context.Context, node overlay.NodeC
END,
last_ip_port=$17,
wallet_features=$18,
country_code=$19;
country_code=$19,
last_software_update_email = CASE
WHEN $20::bool IS TRUE THEN $16::timestamptz
WHEN $21::bool IS FALSE THEN NULL
END;
`,
// args $1 - $5
node.NodeID.Bytes(), node.Address.GetAddress(), node.LastNet, node.Address.GetTransport(), int(pb.NodeType_STORAGE),
Expand All @@ -1345,6 +1356,8 @@ func (cache *overlaycache) UpdateCheckIn(ctx context.Context, node overlay.NodeC
walletFeatures,
// args $19,
node.CountryCode.String(),
// args $20 - $21
node.SoftwareUpdateEmailSent, node.VersionBelowMin,
)
if err != nil {
return Error.Wrap(err)
Expand Down

0 comments on commit 2a25974

Please sign in to comment.