diff --git a/internal/pkg/cli/job_init.go b/internal/pkg/cli/job_init.go index 6351f8f1ba7..88c8d77223e 100644 --- a/internal/pkg/cli/job_init.go +++ b/internal/pkg/cli/job_init.go @@ -194,6 +194,9 @@ func (o *initJobOpts) Execute() error { return err } o.platform = platform + if o.platform != nil { + log.Warningf("Your architecture type is currently unsupported. Setting platform to %s in your manifest.\n", dockerengine.DockerBuildPlatform(dockerengine.LinuxOS, dockerengine.Amd64Arch)) + } manifestPath, err := o.init.Job(&initialize.JobProps{ WorkloadProps: initialize.WorkloadProps{ @@ -202,7 +205,9 @@ func (o *initJobOpts) Execute() error { Type: o.wkldType, DockerfilePath: o.dockerfilePath, Image: o.image, - Platform: o.platform, + Platform: manifest.PlatformArgsOrString{ + PlatformString: o.platform, + }, }, Schedule: o.schedule, diff --git a/internal/pkg/cli/job_init_test.go b/internal/pkg/cli/job_init_test.go index dfd42d3755e..3076568f729 100644 --- a/internal/pkg/cli/job_init_test.go +++ b/internal/pkg/cli/job_init_test.go @@ -525,7 +525,7 @@ func TestJobInitOpts_Execute(t *testing.T) { Name: "mailer", Type: "Scheduled Job", DockerfilePath: "./Dockerfile", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, Schedule: "@hourly", HealthCheck: manifest.ContainerHealthCheck{ diff --git a/internal/pkg/cli/svc_init.go b/internal/pkg/cli/svc_init.go index 7c37b59bf03..01e5452ee8d 100644 --- a/internal/pkg/cli/svc_init.go +++ b/internal/pkg/cli/svc_init.go @@ -260,7 +260,7 @@ func (o *initSvcOpts) Execute() error { } o.platform = platform if o.platform != nil { - log.Warningf(`Your architecture type is currently unsupported. Setting platform %s instead.\n`, dockerengine.DockerBuildPlatform(dockerengine.LinuxOS, dockerengine.Amd64Arch)) + log.Warningf("Your architecture type is currently unsupported. Setting platform %s instead.\n", dockerengine.DockerBuildPlatform(dockerengine.LinuxOS, dockerengine.Amd64Arch)) if o.wkldType != manifest.RequestDrivenWebServiceType { log.Warning("See 'platform' field in your manifest.\n") } @@ -273,8 +273,10 @@ func (o *initSvcOpts) Execute() error { Type: o.wkldType, DockerfilePath: o.dockerfilePath, Image: o.image, - Platform: o.platform, - Topics: o.topics, + Platform: manifest.PlatformArgsOrString{ + PlatformString: o.platform, + }, + Topics: o.topics, }, Port: o.port, HealthCheck: hc, diff --git a/internal/pkg/cli/svc_init_test.go b/internal/pkg/cli/svc_init_test.go index 4eff88e6cae..9348244f9ce 100644 --- a/internal/pkg/cli/svc_init_test.go +++ b/internal/pkg/cli/svc_init_test.go @@ -623,7 +623,7 @@ func TestSvcInitOpts_Execute(t *testing.T) { Name: "frontend", Type: "Load Balanced Web Service", DockerfilePath: "./Dockerfile", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, Port: 80, }).Return("manifest/path", nil) @@ -650,7 +650,7 @@ func TestSvcInitOpts_Execute(t *testing.T) { Name: "frontend", Type: "Backend Service", DockerfilePath: "./Dockerfile", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, }).Return("manifest/path", nil) }, @@ -676,7 +676,7 @@ func TestSvcInitOpts_Execute(t *testing.T) { Name: "frontend", Type: "Worker Service", DockerfilePath: "./Dockerfile", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, }).Return("manifest/path", nil) }, @@ -715,7 +715,7 @@ func TestSvcInitOpts_Execute(t *testing.T) { Name: "backend", Type: "Backend Service", Image: "nginx:latest", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, }).Return("manifest/path", nil) }, @@ -740,7 +740,7 @@ func TestSvcInitOpts_Execute(t *testing.T) { Name: "frontend", Type: "Load Balanced Web Service", Image: "nginx:latest", - Platform: nil, + Platform: manifest.PlatformArgsOrString{}, }, }).Return("manifest/path", nil) }, diff --git a/internal/pkg/initialize/workload.go b/internal/pkg/initialize/workload.go index 13a943ff832..2bf0c5880c1 100644 --- a/internal/pkg/initialize/workload.go +++ b/internal/pkg/initialize/workload.go @@ -66,7 +66,7 @@ type WorkloadProps struct { Name string DockerfilePath string Image string - Platform *string + Platform manifest.PlatformArgsOrString Topics []manifest.TopicSubscription } @@ -271,6 +271,7 @@ func newJobManifest(i *JobProps) (encoding.BinaryMarshaler, error) { Image: i.Image, }, HealthCheck: i.HealthCheck, + Platform: i.Platform, Schedule: i.Schedule, Timeout: i.Timeout, Retries: i.Retries, @@ -305,6 +306,7 @@ func (w *WorkloadInitializer) newLoadBalancedWebServiceManifest(i *ServiceProps) }, Port: i.Port, HealthCheck: i.HealthCheck, + Platform: i.Platform, Path: "/", } existingSvcs, err := w.Store.ListServices(i.App) @@ -329,7 +331,8 @@ func (w *WorkloadInitializer) newRequestDrivenWebServiceManifest(i *ServiceProps Dockerfile: i.DockerfilePath, Image: i.Image, }, - Port: i.Port, + Port: i.Port, + Platform: i.Platform, } return manifest.NewRequestDrivenWebService(props) } @@ -343,6 +346,7 @@ func newBackendServiceManifest(i *ServiceProps) (*manifest.BackendService, error }, Port: i.Port, HealthCheck: i.HealthCheck, + Platform: i.Platform, }), nil } @@ -354,6 +358,7 @@ func newWorkerServiceManifest(i *ServiceProps) (*manifest.WorkerService, error) Image: i.Image, }, HealthCheck: i.HealthCheck, + Platform: i.Platform, Topics: i.Topics, }), nil } diff --git a/internal/pkg/manifest/backend_svc.go b/internal/pkg/manifest/backend_svc.go index 7970aab2b4b..c0fc74e1479 100644 --- a/internal/pkg/manifest/backend_svc.go +++ b/internal/pkg/manifest/backend_svc.go @@ -40,6 +40,7 @@ type BackendServiceProps struct { WorkloadProps Port uint16 HealthCheck ContainerHealthCheck // Optional healthcheck configuration. + Platform PlatformArgsOrString // Optional platform configuration. } // NewBackendService applies the props to a default backend service configuration with @@ -52,6 +53,7 @@ func NewBackendService(props BackendServiceProps) *BackendService { svc.BackendServiceConfig.ImageConfig.Build.BuildArgs.Dockerfile = stringP(props.Dockerfile) svc.BackendServiceConfig.ImageConfig.Port = uint16P(props.Port) svc.BackendServiceConfig.ImageConfig.HealthCheck = props.HealthCheck + svc.BackendServiceConfig.Platform = props.Platform svc.parser = template.New() return svc } diff --git a/internal/pkg/manifest/job.go b/internal/pkg/manifest/job.go index 7ddca5c985a..cfc55671e74 100644 --- a/internal/pkg/manifest/job.go +++ b/internal/pkg/manifest/job.go @@ -65,6 +65,7 @@ type ScheduledJobProps struct { Schedule string Timeout string HealthCheck ContainerHealthCheck // Optional healthcheck configuration. + Platform PlatformArgsOrString // Optional platform configuration. Retries int } @@ -81,6 +82,7 @@ func NewScheduledJob(props *ScheduledJobProps) *ScheduledJob { job.Retries = aws.Int(props.Retries) } job.Timeout = stringP(props.Timeout) + job.Platform = props.Platform job.parser = template.New() return job } diff --git a/internal/pkg/manifest/lb_web_svc.go b/internal/pkg/manifest/lb_web_svc.go index 0f3ce43a56e..bccfacb3cf9 100644 --- a/internal/pkg/manifest/lb_web_svc.go +++ b/internal/pkg/manifest/lb_web_svc.go @@ -62,6 +62,7 @@ type LoadBalancedWebServiceProps struct { Path string Port uint16 HealthCheck ContainerHealthCheck // Optional healthcheck configuration. + Platform PlatformArgsOrString // Optional platform configuration. } // NewLoadBalancedWebService creates a new public load balanced web service, receives all the requests from the load balancer, @@ -74,7 +75,7 @@ func NewLoadBalancedWebService(props *LoadBalancedWebServiceProps) *LoadBalanced svc.LoadBalancedWebServiceConfig.ImageConfig.Build.BuildArgs.Dockerfile = stringP(props.Dockerfile) svc.LoadBalancedWebServiceConfig.ImageConfig.Port = aws.Uint16(props.Port) svc.LoadBalancedWebServiceConfig.ImageConfig.HealthCheck = props.HealthCheck - + svc.LoadBalancedWebServiceConfig.Platform = props.Platform svc.RoutingRule.Path = aws.String(props.Path) svc.parser = template.New() return svc diff --git a/internal/pkg/manifest/rd_web_svc.go b/internal/pkg/manifest/rd_web_svc.go index 686e6736d15..1cfba6e6a40 100644 --- a/internal/pkg/manifest/rd_web_svc.go +++ b/internal/pkg/manifest/rd_web_svc.go @@ -39,15 +39,16 @@ type RequestDrivenWebServiceHttpConfig struct { // AppRunnerInstanceConfig contains the instance configuration properties for an App Runner service. type AppRunnerInstanceConfig struct { - CPU *int `yaml:"cpu"` - Memory *int `yaml:"memory"` - Platform *PlatformArgsOrString `yaml:"platform,omitempty"` + CPU *int `yaml:"cpu"` + Memory *int `yaml:"memory"` + Platform PlatformArgsOrString `yaml:"platform,omitempty"` } // RequestDrivenWebServiceProps contains properties for creating a new request-driven web service manifest. type RequestDrivenWebServiceProps struct { *WorkloadProps - Port uint16 + Port uint16 + Platform PlatformArgsOrString } // NewRequestDrivenWebService creates a new Request-Driven Web Service manifest with default values. @@ -57,6 +58,7 @@ func NewRequestDrivenWebService(props *RequestDrivenWebServiceProps) *RequestDri svc.RequestDrivenWebServiceConfig.ImageConfig.Image.Location = stringP(props.Image) svc.RequestDrivenWebServiceConfig.ImageConfig.Build.BuildArgs.Dockerfile = stringP(props.Dockerfile) svc.RequestDrivenWebServiceConfig.ImageConfig.Port = aws.Uint16(props.Port) + svc.RequestDrivenWebServiceConfig.InstanceConfig.Platform = props.Platform svc.parser = template.New() return svc } @@ -89,7 +91,7 @@ func (s *RequestDrivenWebService) BuildRequired() (bool, error) { // TaskPlatform returns the platform for the service. func (s *RequestDrivenWebService) TaskPlatform() (*string, error) { - if s.InstanceConfig.Platform == nil { + if s.InstanceConfig.Platform.PlatformString == nil { return nil, nil } return s.InstanceConfig.Platform.PlatformString, nil diff --git a/internal/pkg/manifest/svc_test.go b/internal/pkg/manifest/svc_test.go index b3e684db907..61ab5e00baa 100644 --- a/internal/pkg/manifest/svc_test.go +++ b/internal/pkg/manifest/svc_test.go @@ -104,9 +104,8 @@ environments: }, }, TaskConfig: TaskConfig{ - CPU: aws.Int(512), - Memory: aws.Int(1024), - Platform: nil, + CPU: aws.Int(512), + Memory: aws.Int(1024), Count: Count{ Value: aws.Int(1), }, @@ -243,9 +242,8 @@ secrets: }, }, TaskConfig: TaskConfig{ - CPU: aws.Int(1024), - Memory: aws.Int(1024), - Platform: nil, + CPU: aws.Int(1024), + Memory: aws.Int(1024), Count: Count{ Value: aws.Int(1), }, @@ -307,9 +305,8 @@ subscribe: }, }, TaskConfig: TaskConfig{ - CPU: aws.Int(1024), - Memory: aws.Int(1024), - Platform: nil, + CPU: aws.Int(1024), + Memory: aws.Int(1024), Count: Count{ Value: aws.Int(1), }, diff --git a/internal/pkg/manifest/worker_svc.go b/internal/pkg/manifest/worker_svc.go index fb258c2aeb1..2d0efbd3a7d 100644 --- a/internal/pkg/manifest/worker_svc.go +++ b/internal/pkg/manifest/worker_svc.go @@ -71,7 +71,9 @@ func (q *DeadLetterQueue) IsEmpty() bool { // WorkerServiceProps represents the configuration needed to create a worker service. type WorkerServiceProps struct { WorkloadProps + HealthCheck ContainerHealthCheck // Optional healthcheck configuration. + Platform PlatformArgsOrString // Optional platform configuration. Topics []TopicSubscription // Optional topics for subscriptions } @@ -85,6 +87,7 @@ func NewWorkerService(props WorkerServiceProps) *WorkerService { svc.WorkerServiceConfig.ImageConfig.Build.BuildArgs.Dockerfile = stringP(props.Dockerfile) svc.WorkerServiceConfig.ImageConfig.HealthCheck = props.HealthCheck svc.WorkerServiceConfig.Subscribe.Topics = props.Topics + svc.WorkerServiceConfig.Platform = props.Platform svc.parser = template.New() return svc } diff --git a/internal/pkg/manifest/worker_svc_test.go b/internal/pkg/manifest/worker_svc_test.go index 27a0b9714d5..9c231e6cb27 100644 --- a/internal/pkg/manifest/worker_svc_test.go +++ b/internal/pkg/manifest/worker_svc_test.go @@ -131,6 +131,13 @@ func TestWorkerSvc_MarshalBinary(t *testing.T) { Name: "testers", Dockerfile: "./testers/Dockerfile", }, + Platform: PlatformArgsOrString{ + PlatformString: nil, + PlatformArgs: PlatformArgs{ + OSFamily: nil, + Arch: nil, + }, + }, }, wantedTestdata: "worker-svc-nosubscribe.yml", }, @@ -140,6 +147,13 @@ func TestWorkerSvc_MarshalBinary(t *testing.T) { Name: "testers", Dockerfile: "./testers/Dockerfile", }, + Platform: PlatformArgsOrString{ + PlatformString: nil, + PlatformArgs: PlatformArgs{ + OSFamily: nil, + Arch: nil, + }, + }, Topics: []TopicSubscription{ { Name: "testTopic", diff --git a/internal/pkg/manifest/workload.go b/internal/pkg/manifest/workload.go index 0263b977655..42eafae3586 100644 --- a/internal/pkg/manifest/workload.go +++ b/internal/pkg/manifest/workload.go @@ -422,19 +422,19 @@ type SidecarConfig struct { // TaskConfig represents the resource boundaries and environment variables for the containers in the task. type TaskConfig struct { - CPU *int `yaml:"cpu"` - Memory *int `yaml:"memory"` - Platform *PlatformArgsOrString `yaml:"platform,omitempty"` - Count Count `yaml:"count"` - ExecuteCommand ExecuteCommand `yaml:"exec"` - Variables map[string]string `yaml:"variables"` - Secrets map[string]string `yaml:"secrets"` - Storage Storage `yaml:"storage"` + CPU *int `yaml:"cpu"` + Memory *int `yaml:"memory"` + Platform PlatformArgsOrString `yaml:"platform,omitempty"` + Count Count `yaml:"count"` + ExecuteCommand ExecuteCommand `yaml:"exec"` + Variables map[string]string `yaml:"variables"` + Secrets map[string]string `yaml:"secrets"` + Storage Storage `yaml:"storage"` } // TaskPlatform returns the platform for the service. func (t *TaskConfig) TaskPlatform() (*string, error) { - if t.Platform == nil { + if t.Platform.PlatformString == nil { return nil, nil } return t.Platform.PlatformString, nil diff --git a/internal/pkg/manifest/workload_test.go b/internal/pkg/manifest/workload_test.go index b65f96f4bd1..0503726cb9c 100644 --- a/internal/pkg/manifest/workload_test.go +++ b/internal/pkg/manifest/workload_test.go @@ -355,15 +355,7 @@ func TestPlatformArgsOrString_UnmarshalYAML(t *testing.T) { } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - p := TaskConfig{ - Platform: &PlatformArgsOrString{ - PlatformString: nil, - PlatformArgs: PlatformArgs{ - OSFamily: nil, - Arch: nil, - }, - }, - } + p := TaskConfig{} err := yaml.Unmarshal(tc.inContent, &p) if tc.wantedError != nil { require.EqualError(t, err, tc.wantedError.Error()) diff --git a/internal/pkg/template/templates/workloads/jobs/scheduled-job/manifest.yml b/internal/pkg/template/templates/workloads/jobs/scheduled-job/manifest.yml index eb989fbead5..bc588d8cf0b 100644 --- a/internal/pkg/template/templates/workloads/jobs/scheduled-job/manifest.yml +++ b/internal/pkg/template/templates/workloads/jobs/scheduled-job/manifest.yml @@ -34,8 +34,8 @@ image: cpu: {{.CPU}} # Number of CPU units for the task. memory: {{.Memory}} # Amount of memory in MiB used by the task. -{{- if .Platform}} -platform: {{.Platform}} # See https://aws.github.io/copilot-cli/docs/manifest/scheduled-job/#platform +{{- if .Platform.PlatformString}} +platform: {{.Platform.PlatformString}} # See https://aws.github.io/copilot-cli/docs/manifest/scheduled-job/#platform {{- end}} # Optional fields for more advanced use-cases. diff --git a/internal/pkg/template/templates/workloads/services/backend/manifest.yml b/internal/pkg/template/templates/workloads/services/backend/manifest.yml index ab165d0e477..0e566cc63ba 100644 --- a/internal/pkg/template/templates/workloads/services/backend/manifest.yml +++ b/internal/pkg/template/templates/workloads/services/backend/manifest.yml @@ -36,8 +36,8 @@ image: cpu: {{.CPU}} # Number of CPU units for the task. memory: {{.Memory}} # Amount of memory in MiB used by the task. -{{- if .Platform}} -platform: {{.Platform}} # See https://aws.github.io/copilot-cli/docs/manifest/backend-service/#platform +{{- if .Platform.PlatformString}} +platform: {{.Platform.PlatformString}} # See https://aws.github.io/copilot-cli/docs/manifest/backend-service/#platform {{- end}} count: {{.Count.Value}} # Number of tasks that should be running in your service. exec: true # Enable running commands in your container. diff --git a/internal/pkg/template/templates/workloads/services/lb-web/manifest.yml b/internal/pkg/template/templates/workloads/services/lb-web/manifest.yml index 8639805471a..1ec56751edc 100644 --- a/internal/pkg/template/templates/workloads/services/lb-web/manifest.yml +++ b/internal/pkg/template/templates/workloads/services/lb-web/manifest.yml @@ -28,8 +28,8 @@ image: cpu: {{.CPU}} # Number of CPU units for the task. memory: {{.Memory}} # Amount of memory in MiB used by the task. -{{- if .Platform}} # See https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#platform -platform: {{.Platform}} +{{- if .Platform.PlatformString}} +platform: {{.Platform.PlatformString}} # See https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#platform {{- end}} count: {{.Count.Value}} # Number of tasks that should be running in your service. exec: true # Enable running commands in your container. diff --git a/internal/pkg/template/templates/workloads/services/worker/manifest.yml b/internal/pkg/template/templates/workloads/services/worker/manifest.yml index 32284bfc498..f3ba60b0703 100644 --- a/internal/pkg/template/templates/workloads/services/worker/manifest.yml +++ b/internal/pkg/template/templates/workloads/services/worker/manifest.yml @@ -27,8 +27,8 @@ image: cpu: {{.CPU}} # Number of CPU units for the task. memory: {{.Memory}} # Amount of memory in MiB used by the task. -{{- if .Platform}} -platform: {{.Platform}} +{{- if .Platform.PlatformString}} +platform: {{.Platform.PlatformString}} # See https://aws.github.io/copilot-cli/docs/manifest/worker-service/#platform {{- end}} count: {{.Count.Value}} # Number of tasks that should be running in your service. exec: true # Enable running commands in your container.