diff --git a/nodeup/pkg/bootstrap/install.go b/nodeup/pkg/bootstrap/install.go index 35309b0d65f1b..19dd53b577882 100644 --- a/nodeup/pkg/bootstrap/install.go +++ b/nodeup/pkg/bootstrap/install.go @@ -17,6 +17,7 @@ limitations under the License. package bootstrap import ( + "context" "fmt" "os" "strings" @@ -37,6 +38,8 @@ type Installation struct { } func (i *Installation) Run() error { + ctx := context.TODO() + _, err := distributions.FindDistribution("/") if err != nil { return fmt.Errorf("error determining OS distribution: %v", err) @@ -72,7 +75,7 @@ func (i *Installation) Run() error { } checkExisting := true - context, err := fi.NewContext(target, nil, cloud, keyStore, secretStore, configBase, checkExisting, tasks) + context, err := fi.NewContext(ctx, target, nil, cloud, keyStore, secretStore, configBase, checkExisting, tasks) if err != nil { return fmt.Errorf("error building context: %v", err) } diff --git a/pkg/testutils/integrationtestharness.go b/pkg/testutils/integrationtestharness.go index 1a60a3de0be4c..6750909732c89 100644 --- a/pkg/testutils/integrationtestharness.go +++ b/pkg/testutils/integrationtestharness.go @@ -77,7 +77,7 @@ type IntegrationTestHarness struct { func NewIntegrationTestHarness(t *testing.T) *IntegrationTestHarness { featureflag.ParseFlags("-ImageDigest") - h := &IntegrationTestHarness{} + h := &IntegrationTestHarness{T: t} tempDir, err := os.MkdirTemp("", "test") if err != nil { t.Fatalf("failed to create temp dir: %v", err) diff --git a/upup/pkg/fi/cloudup/apply_cluster.go b/upup/pkg/fi/cloudup/apply_cluster.go index b007883d0a1a7..dd7fcf345583b 100644 --- a/upup/pkg/fi/cloudup/apply_cluster.go +++ b/upup/pkg/fi/cloudup/apply_cluster.go @@ -699,7 +699,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error { return fmt.Errorf("unknown cloudprovider %q", cluster.Spec.GetCloudProvider()) } } - c.TaskMap, err = l.BuildTasks(c.LifecycleOverrides) + c.TaskMap, err = l.BuildTasks(ctx, c.LifecycleOverrides) if err != nil { return fmt.Errorf("error building tasks: %v", err) } @@ -783,7 +783,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error { } } - context, err := fi.NewContext(target, cluster, cloud, keyStore, secretStore, configBase, checkExisting, c.TaskMap) + context, err := fi.NewContext(ctx, target, cluster, cloud, keyStore, secretStore, configBase, checkExisting, c.TaskMap) if err != nil { return fmt.Errorf("error building context: %v", err) } diff --git a/upup/pkg/fi/cloudup/awstasks/egressonlyinternetgateway_test.go b/upup/pkg/fi/cloudup/awstasks/egressonlyinternetgateway_test.go index 41aabfce2266f..9b2010f318770 100644 --- a/upup/pkg/fi/cloudup/awstasks/egressonlyinternetgateway_test.go +++ b/upup/pkg/fi/cloudup/awstasks/egressonlyinternetgateway_test.go @@ -17,6 +17,7 @@ limitations under the License. package awstasks import ( + "context" "reflect" "testing" @@ -28,6 +29,8 @@ import ( ) func TestSharedEgressOnlyInternetGatewayDoesNotRename(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -95,7 +98,7 @@ func TestSharedEgressOnlyInternetGatewayDoesNotRename(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -139,6 +142,6 @@ func TestSharedEgressOnlyInternetGatewayDoesNotRename(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/awstasks/elastic_ip_test.go b/upup/pkg/fi/cloudup/awstasks/elastic_ip_test.go index 68c4484c91c95..f4f625b1db122 100644 --- a/upup/pkg/fi/cloudup/awstasks/elastic_ip_test.go +++ b/upup/pkg/fi/cloudup/awstasks/elastic_ip_test.go @@ -18,6 +18,7 @@ package awstasks import ( "bytes" + "context" "os" "reflect" "testing" @@ -38,6 +39,8 @@ var testRunTasksOptions = fi.RunTasksOptions{ } func TestElasticIPCreate(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -78,7 +81,7 @@ func TestElasticIPCreate(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -115,11 +118,11 @@ func TestElasticIPCreate(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } -func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) { +func checkNoChanges(t *testing.T, ctx context.Context, cloud fi.Cloud, allTasks map[string]fi.Task) { cluster := &kops.Cluster{ Spec: kops.ClusterSpec{ KubernetesVersion: "v1.9.0", @@ -127,7 +130,7 @@ func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) { } assetBuilder := assets.NewAssetBuilder(cluster, false) target := fi.NewDryRunTarget(assetBuilder, os.Stderr) - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } diff --git a/upup/pkg/fi/cloudup/awstasks/internetgateway_test.go b/upup/pkg/fi/cloudup/awstasks/internetgateway_test.go index bbfeb21816434..3669b28756d97 100644 --- a/upup/pkg/fi/cloudup/awstasks/internetgateway_test.go +++ b/upup/pkg/fi/cloudup/awstasks/internetgateway_test.go @@ -17,6 +17,7 @@ limitations under the License. package awstasks import ( + "context" "reflect" "testing" @@ -28,6 +29,8 @@ import ( ) func TestSharedInternetGatewayDoesNotRename(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -111,7 +114,7 @@ func TestSharedInternetGatewayDoesNotRename(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -155,6 +158,6 @@ func TestSharedInternetGatewayDoesNotRename(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/awstasks/securitygroup_test.go b/upup/pkg/fi/cloudup/awstasks/securitygroup_test.go index 301bdd30d3eac..0c392808bef34 100644 --- a/upup/pkg/fi/cloudup/awstasks/securitygroup_test.go +++ b/upup/pkg/fi/cloudup/awstasks/securitygroup_test.go @@ -17,6 +17,7 @@ limitations under the License. package awstasks import ( + "context" "reflect" "testing" @@ -94,6 +95,8 @@ func testNotMatches(t *testing.T, rule *PortRemovalRule, permission *ec2.Securit } func TestSecurityGroupCreate(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -129,7 +132,7 @@ func TestSecurityGroupCreate(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -167,6 +170,6 @@ func TestSecurityGroupCreate(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/awstasks/subnet_test.go b/upup/pkg/fi/cloudup/awstasks/subnet_test.go index d322dfd581f0e..1cc4cd54176a1 100644 --- a/upup/pkg/fi/cloudup/awstasks/subnet_test.go +++ b/upup/pkg/fi/cloudup/awstasks/subnet_test.go @@ -17,6 +17,7 @@ limitations under the License. package awstasks import ( + "context" "fmt" "reflect" "testing" @@ -64,6 +65,8 @@ func Test_Subnet_CannotChangeSubnet(t *testing.T) { } func TestSubnetCreate(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -99,7 +102,7 @@ func TestSubnetCreate(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -142,11 +145,13 @@ func TestSubnetCreate(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } func TestSubnetCreateIPv6(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -190,7 +195,7 @@ func TestSubnetCreateIPv6(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -242,11 +247,13 @@ func TestSubnetCreateIPv6(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } func TestSubnetCreateIPv6NetNum(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -289,7 +296,7 @@ func TestSubnetCreateIPv6NetNum(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -341,11 +348,13 @@ func TestSubnetCreateIPv6NetNum(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } func TestSharedSubnetCreateDoesNotCreateNew(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -422,7 +431,7 @@ func TestSharedSubnetCreateDoesNotCreateNew(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -470,6 +479,6 @@ func TestSharedSubnetCreateDoesNotCreateNew(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/awstasks/vpc_test.go b/upup/pkg/fi/cloudup/awstasks/vpc_test.go index 0ec0944be731a..22d6cb6827315 100644 --- a/upup/pkg/fi/cloudup/awstasks/vpc_test.go +++ b/upup/pkg/fi/cloudup/awstasks/vpc_test.go @@ -17,6 +17,7 @@ limitations under the License. package awstasks import ( + "context" "reflect" "testing" @@ -28,6 +29,8 @@ import ( ) func TestVPCCreate(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} cloud.MockEC2 = c @@ -53,7 +56,7 @@ func TestVPCCreate(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -91,7 +94,7 @@ func TestVPCCreate(t *testing.T) { { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } @@ -132,6 +135,8 @@ func Test4758(t *testing.T) { } func TestSharedVPCAdditionalCIDR(t *testing.T) { + ctx := context.TODO() + cloud := awsup.BuildMockAWSCloud("us-east-1", "abc") c := &mockec2.MockEC2{} c.CreateVpcWithId(&ec2.CreateVpcInput{ @@ -177,7 +182,7 @@ func TestSharedVPCAdditionalCIDR(t *testing.T) { Cloud: cloud, } - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } diff --git a/upup/pkg/fi/cloudup/gcetasks/projectiambinding_test.go b/upup/pkg/fi/cloudup/gcetasks/projectiambinding_test.go index 0c8c9a904ce40..aaf5f6102ffd9 100644 --- a/upup/pkg/fi/cloudup/gcetasks/projectiambinding_test.go +++ b/upup/pkg/fi/cloudup/gcetasks/projectiambinding_test.go @@ -17,6 +17,7 @@ limitations under the License. package gcetasks import ( + "context" "testing" gcemock "k8s.io/kops/cloudmock/gce" @@ -24,6 +25,8 @@ import ( ) func TestProjectIAMBinding(t *testing.T) { + ctx := context.TODO() + project := "testproject" region := "us-test1" @@ -46,16 +49,16 @@ func TestProjectIAMBinding(t *testing.T) { { allTasks := buildTasks() - checkHasChanges(t, cloud, allTasks) + checkHasChanges(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - runTasks(t, cloud, allTasks) + runTasks(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/gcetasks/serviceaccount_test.go b/upup/pkg/fi/cloudup/gcetasks/serviceaccount_test.go index e80654ee6b20b..ab3b9aad691dd 100644 --- a/upup/pkg/fi/cloudup/gcetasks/serviceaccount_test.go +++ b/upup/pkg/fi/cloudup/gcetasks/serviceaccount_test.go @@ -18,6 +18,7 @@ package gcetasks import ( "bytes" + "context" "os" "testing" "time" @@ -30,6 +31,8 @@ import ( ) func TestServiceAccount(t *testing.T) { + ctx := context.TODO() + project := "testproject" region := "us-test1" @@ -53,17 +56,17 @@ func TestServiceAccount(t *testing.T) { { allTasks := buildTasks() - checkHasChanges(t, cloud, allTasks) + checkHasChanges(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - runTasks(t, cloud, allTasks) + runTasks(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } @@ -74,8 +77,8 @@ var testRunTasksOptions = fi.RunTasksOptions{ } // TODO: Dedup with awstasks -func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) { - target := doDryRun(t, cloud, allTasks) +func checkNoChanges(t *testing.T, ctx context.Context, cloud fi.Cloud, allTasks map[string]fi.Task) { + target := doDryRun(t, ctx, cloud, allTasks) if target.HasChanges() { var b bytes.Buffer @@ -86,18 +89,18 @@ func checkNoChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) { } } -func checkHasChanges(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) { - target := doDryRun(t, cloud, allTasks) +func checkHasChanges(t *testing.T, ctx context.Context, cloud fi.Cloud, allTasks map[string]fi.Task) { + target := doDryRun(t, ctx, cloud, allTasks) if !target.HasChanges() { t.Fatalf("expected dry-run to have changes") } } -func runTasks(t *testing.T, cloud gce.GCECloud, allTasks map[string]fi.Task) { +func runTasks(t *testing.T, ctx context.Context, cloud gce.GCECloud, allTasks map[string]fi.Task) { target := gce.NewGCEAPITarget(cloud) - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } @@ -108,7 +111,8 @@ func runTasks(t *testing.T, cloud gce.GCECloud, allTasks map[string]fi.Task) { } } -func doDryRun(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) *fi.DryRunTarget { +func doDryRun(t *testing.T, ctx context.Context, cloud fi.Cloud, allTasks map[string]fi.Task) *fi.DryRunTarget { + cluster := &kops.Cluster{ Spec: kops.ClusterSpec{ KubernetesVersion: "v1.23.0", @@ -116,7 +120,7 @@ func doDryRun(t *testing.T, cloud fi.Cloud, allTasks map[string]fi.Task) *fi.Dry } assetBuilder := assets.NewAssetBuilder(cluster, false) target := fi.NewDryRunTarget(assetBuilder, os.Stderr) - context, err := fi.NewContext(target, nil, cloud, nil, nil, nil, true, allTasks) + context, err := fi.NewContext(ctx, target, nil, cloud, nil, nil, nil, true, allTasks) if err != nil { t.Fatalf("error building context: %v", err) } diff --git a/upup/pkg/fi/cloudup/gcetasks/storagebucketiam_test.go b/upup/pkg/fi/cloudup/gcetasks/storagebucketiam_test.go index 826ba3e1a9178..3bf52b5f8cf4e 100644 --- a/upup/pkg/fi/cloudup/gcetasks/storagebucketiam_test.go +++ b/upup/pkg/fi/cloudup/gcetasks/storagebucketiam_test.go @@ -17,6 +17,7 @@ limitations under the License. package gcetasks import ( + "context" "testing" gcemock "k8s.io/kops/cloudmock/gce" @@ -24,6 +25,8 @@ import ( ) func TestStorageBucketIAM(t *testing.T) { + ctx := context.TODO() + project := "testproject" region := "us-test1" @@ -46,16 +49,16 @@ func TestStorageBucketIAM(t *testing.T) { { allTasks := buildTasks() - checkHasChanges(t, cloud, allTasks) + checkHasChanges(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - runTasks(t, cloud, allTasks) + runTasks(t, ctx, cloud, allTasks) } { allTasks := buildTasks() - checkNoChanges(t, cloud, allTasks) + checkNoChanges(t, ctx, cloud, allTasks) } } diff --git a/upup/pkg/fi/cloudup/loader.go b/upup/pkg/fi/cloudup/loader.go index e0809a1f3b0f4..c620ecd576344 100644 --- a/upup/pkg/fi/cloudup/loader.go +++ b/upup/pkg/fi/cloudup/loader.go @@ -17,6 +17,7 @@ limitations under the License. package cloudup import ( + "context" "fmt" "reflect" @@ -36,12 +37,13 @@ func (l *Loader) Init() { l.tasks = make(map[string]fi.Task) } -func (l *Loader) BuildTasks(lifecycleOverrides map[string]fi.Lifecycle) (map[string]fi.Task, error) { +func (l *Loader) BuildTasks(ctx context.Context, lifecycleOverrides map[string]fi.Lifecycle) (map[string]fi.Task, error) { for _, builder := range l.Builders { context := &fi.ModelBuilderContext{ Tasks: l.tasks, LifecycleOverrides: lifecycleOverrides, } + context = context.WithContext(ctx) err := builder.Build(context) if err != nil { return nil, err diff --git a/upup/pkg/fi/context.go b/upup/pkg/fi/context.go index 2afe7119d5861..82b74d4408273 100644 --- a/upup/pkg/fi/context.go +++ b/upup/pkg/fi/context.go @@ -18,6 +18,7 @@ package fi import ( "bytes" + "context" "fmt" "os" "reflect" @@ -30,6 +31,8 @@ import ( ) type Context struct { + ctx context.Context + Tmpdir string Target Target @@ -47,14 +50,19 @@ type Context struct { warnings []*Warning } +func (c *Context) Context() context.Context { + return c.ctx +} + // Warning holds the details of a warning encountered during validation/creation type Warning struct { Task Task Message string } -func NewContext(target Target, cluster *kops.Cluster, cloud Cloud, keystore Keystore, secretStore SecretStore, clusterConfigBase vfs.Path, checkExisting bool, tasks map[string]Task) (*Context, error) { +func NewContext(ctx context.Context, target Target, cluster *kops.Cluster, cloud Cloud, keystore Keystore, secretStore SecretStore, clusterConfigBase vfs.Path, checkExisting bool, tasks map[string]Task) (*Context, error) { c := &Context{ + ctx: ctx, Cloud: cloud, Cluster: cluster, Target: target, diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 5c8ffdd5f0799..43abc0fc9ac9c 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -384,7 +384,7 @@ func (c *NodeUpCommand) Run(out io.Writer) error { return fmt.Errorf("unsupported target type %q", c.Target) } - context, err := fi.NewContext(target, c.cluster, cloud, keyStore, secretStore, configBase, checkExisting, taskMap) + context, err := fi.NewContext(ctx, target, c.cluster, cloud, keyStore, secretStore, configBase, checkExisting, taskMap) if err != nil { klog.Exitf("error building context: %v", err) } diff --git a/upup/pkg/fi/task.go b/upup/pkg/fi/task.go index a7dc2439001d6..a034e21cafc01 100644 --- a/upup/pkg/fi/task.go +++ b/upup/pkg/fi/task.go @@ -17,6 +17,7 @@ limitations under the License. package fi import ( + "context" "fmt" "reflect" "strings" @@ -71,10 +72,29 @@ type HasDeletions interface { // ModelBuilderContext is a context object that holds state we want to pass to ModelBuilder type ModelBuilderContext struct { + // ctx holds the context.Context, ideally we would pass this in to every handler, + // but that is a fairly large refactor, and arguably ModelBuilderContext has a similar + // lifecycle to a context.Context + ctx context.Context + Tasks map[string]Task LifecycleOverrides map[string]Lifecycle } +func (c *ModelBuilderContext) WithContext(ctx context.Context) *ModelBuilderContext { + c2 := *c + c2.ctx = ctx + return &c2 +} + +func (c *ModelBuilderContext) Context() context.Context { + ctx := c.ctx + if ctx == nil { + ctx = context.TODO() + } + return ctx +} + func (c *ModelBuilderContext) AddTask(task Task) { task = c.setLifecycleOverride(task) key := buildTaskKey(task) diff --git a/util/pkg/vfs/context.go b/util/pkg/vfs/context.go index 55b13fa26c11f..6ece6add0a203 100644 --- a/util/pkg/vfs/context.go +++ b/util/pkg/vfs/context.go @@ -39,11 +39,18 @@ import ( // VFSContext is a 'context' for VFS, that is normally a singleton // but allows us to configure S3 credentials, for example type VFSContext struct { + // mutex guards state + mutex sync.Mutex + + // vfsContextState makes it easier to copy the state + vfsContextState +} + +type vfsContextState struct { s3Context *S3Context k8sContext *KubernetesContext memfsContext *MemFSContext - // mutex guards gcsClient - mutex sync.Mutex + // The google cloud storage client, if initialized gcsClient *storage.Service // swiftClient is the openstack swift client @@ -52,9 +59,43 @@ type VFSContext struct { azureClient *azureClient } -var Context = VFSContext{ - s3Context: NewS3Context(), - k8sContext: NewKubernetesContext(), +// Context holds the global VFS state. +// Deprecated: prefer FromContext. +var Context = NewVFSContext() + +// NewVFSContext builds a new VFSContext +func NewVFSContext() *VFSContext { + v := &VFSContext{} + v.s3Context = NewS3Context() + v.k8sContext = NewKubernetesContext() + return v +} + +func (v *VFSContext) WithGCSClient(gcsClient *storage.Service) *VFSContext { + v.mutex.Lock() + defer v.mutex.Unlock() + + v2 := &VFSContext{ + vfsContextState: v.vfsContextState, + } + v2.gcsClient = gcsClient + return v2 +} + +type contextKeyType int + +var contextKey contextKeyType + +func FromContext(ctx context.Context) *VFSContext { + o := ctx.Value(contextKey) + if o != nil { + return o.(*VFSContext) + } + return Context +} + +func WithContext(parent context.Context, vfsContext *VFSContext) context.Context { + return context.WithValue(parent, contextKey, vfsContext) } type vfsOptions struct {