Skip to content

Commit 02d316e

Browse files
fix(updates): consume verified release snapshots
1 parent 032f6c5 commit 02d316e

3 files changed

Lines changed: 38 additions & 8 deletions

File tree

deployment-files/docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ services:
1616
DB_DSN: "${DB_DSN:-}"
1717
ENCRYPT_SERVICE_MASTER_KEY: "${ENCRYPT_SERVICE_MASTER_KEY}"
1818
SESSION_COOKIE_SECURE: "${SESSION_COOKIE_SECURE:-true}"
19+
UPDATES_GITHUB_TOKEN: "${UPDATES_GITHUB_TOKEN:-}"
1920
PLUGINS_DIR: "/app/plugins"
2021
PLUGINS_ENABLED: "true"
2122
ENABLE_VIRTUAL_MINERS: "${ENABLE_VIRTUAL_MINERS:-false}"

server/cmd/fleetd/main_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,32 @@ encrypt:
173173
require.Equal(t, allowlist, config.Infrastructure.OTControlSubnets)
174174
}
175175

176+
func TestFleetdUpdatesGitHubTokenEnvironment(t *testing.T) {
177+
const token = "release-check-token"
178+
t.Setenv("UPDATES_GITHUB_TOKEN", token)
179+
180+
configPath := writeFleetdConfigFile(t, `
181+
auth:
182+
client:
183+
expiration-period: "1h"
184+
secret-key: "test-client-secret"
185+
miner-token-expiration-period: "30m"
186+
encrypt:
187+
service-master-key: "test-master-key"
188+
`)
189+
config := &Config{}
190+
parser, err := kong.New(
191+
config,
192+
kong.Name("fleetd"),
193+
kong.Configuration(kongyaml.Loader, configPath),
194+
)
195+
require.NoError(t, err)
196+
197+
_, err = parser.Parse(nil)
198+
require.NoError(t, err)
199+
require.Equal(t, token, config.Updates.GitHubToken)
200+
}
201+
176202
func TestFleetdRejectsInvalidInfrastructureOTControlSubnetsBeforeStartup(t *testing.T) {
177203
config := &Config{}
178204
config.Infrastructure.OTControlSubnets = "sensitive-control-subnet"

server/internal/domain/updates/service.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,13 @@ func (s *Service) releaseChannel(ctx context.Context, organizationID int64) (Cha
162162
// when stable discovery is unavailable, but an incomplete RC view makes that
163163
// broader channel unavailable.
164164
func channelStatusAvailable(channel Channel, snap Snapshot) bool {
165+
_, stableAvailable := snap.EligibleStable()
166+
rc, rcAvailable := snap.EligibleRC()
165167
switch channel {
166168
case ChannelStable:
167-
return snap.StableAvailable
169+
return stableAvailable
168170
case ChannelStableAndRC:
169-
return snap.RCAvailable && (snap.StableAvailable || snap.LatestRC != nil)
171+
return rcAvailable && (stableAvailable || rc != nil)
170172
default:
171173
return false
172174
}
@@ -176,13 +178,10 @@ func channelStatusAvailable(channel Channel, snap Snapshot) bool {
176178
// stable sees the latest available stable; stable_and_rc takes the semver max
177179
// of that stable and the latest available RC.
178180
func eligibleCandidate(channel Channel, snap Snapshot) *Release {
179-
var candidate *Release
180-
if snap.StableAvailable {
181-
candidate = snap.LatestStable
182-
}
181+
candidate, _ := snap.EligibleStable()
183182
if channel == ChannelStableAndRC {
184-
if snap.RCAvailable {
185-
candidate = semverMax(candidate, snap.LatestRC)
183+
if rc, available := snap.EligibleRC(); available {
184+
candidate = semverMax(candidate, rc)
186185
}
187186
}
188187
return candidate
@@ -201,6 +200,10 @@ func semverMax(a, b *Release) *Release {
201200
return a
202201
}
203202

203+
func isCanonicalReleaseTag(tag string) bool {
204+
return isCanonicalStableTag(tag) || isCanonicalRCTag(tag)
205+
}
206+
204207
// installCommand composes the copy-paste upgrade invocation from two
205208
// independently constrained values. The configured base must exactly match
206209
// the trusted Proto Fleet release path, and the GitHub-sourced tag must be

0 commit comments

Comments
 (0)