feat: add prebuilds configuration & bootstrapping (#17527)

Closes https://github.com/coder/internal/issues/508

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Cian Johnston <cian@coder.com>
This commit is contained in:
Danny Kopping
2025-04-25 11:07:15 +02:00
committed by GitHub
parent e562e3c882
commit 08ad910171
14 changed files with 328 additions and 46 deletions

View File

@ -28,10 +28,15 @@ import (
"github.com/coder/coder/v2/agent"
"github.com/coder/coder/v2/agent/agenttest"
"github.com/coder/coder/v2/coderd/httpapi"
agplprebuilds "github.com/coder/coder/v2/coderd/prebuilds"
"github.com/coder/coder/v2/coderd/rbac/policy"
"github.com/coder/coder/v2/coderd/util/ptr"
"github.com/coder/coder/v2/enterprise/coderd/prebuilds"
"github.com/coder/coder/v2/tailnet/tailnettest"
"github.com/coder/retry"
"github.com/coder/serpent"
agplaudit "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
@ -50,8 +55,6 @@ import (
"github.com/coder/coder/v2/enterprise/dbcrypt"
"github.com/coder/coder/v2/enterprise/replicasync"
"github.com/coder/coder/v2/testutil"
"github.com/coder/retry"
"github.com/coder/serpent"
)
func TestMain(m *testing.M) {
@ -253,6 +256,90 @@ func TestEntitlements_HeaderWarnings(t *testing.T) {
})
}
func TestEntitlements_Prebuilds(t *testing.T) {
t.Parallel()
cases := []struct {
name string
experimentEnabled bool
featureEnabled bool
expectedEnabled bool
}{
{
name: "Fully enabled",
featureEnabled: true,
experimentEnabled: true,
expectedEnabled: true,
},
{
name: "Feature disabled",
featureEnabled: false,
experimentEnabled: true,
expectedEnabled: false,
},
{
name: "Experiment disabled",
featureEnabled: true,
experimentEnabled: false,
expectedEnabled: false,
},
{
name: "Fully disabled",
featureEnabled: false,
experimentEnabled: false,
expectedEnabled: false,
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var prebuildsEntitled int64
if tc.featureEnabled {
prebuildsEntitled = 1
}
_, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
Options: &coderdtest.Options{
DeploymentValues: coderdtest.DeploymentValues(t, func(values *codersdk.DeploymentValues) {
if tc.experimentEnabled {
values.Experiments = serpent.StringArray{string(codersdk.ExperimentWorkspacePrebuilds)}
}
}),
},
EntitlementsUpdateInterval: time.Second,
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureWorkspacePrebuilds: prebuildsEntitled,
},
},
})
// The entitlements will need to refresh before the reconciler is set.
require.Eventually(t, func() bool {
return api.AGPL.PrebuildsReconciler.Load() != nil
}, testutil.WaitSuperLong, testutil.IntervalFast)
reconciler := api.AGPL.PrebuildsReconciler.Load()
claimer := api.AGPL.PrebuildsClaimer.Load()
require.NotNil(t, reconciler)
require.NotNil(t, claimer)
if tc.expectedEnabled {
require.IsType(t, &prebuilds.StoreReconciler{}, *reconciler)
require.IsType(t, prebuilds.EnterpriseClaimer{}, *claimer)
} else {
require.Equal(t, &agplprebuilds.DefaultReconciler, reconciler)
require.Equal(t, &agplprebuilds.DefaultClaimer, claimer)
}
})
}
}
func TestAuditLogging(t *testing.T) {
t.Parallel()
t.Run("Enabled", func(t *testing.T) {