mirror of https://github.com/docker/compose.git
				
				
				
			add support of platforms in build section
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
This commit is contained in:
		
							parent
							
								
									06ae6d82cb
								
							
						
					
					
						commit
						8b1b70833e
					
				|  | @ -0,0 +1,35 @@ | ||||||
|  | /* | ||||||
|  |    Copyright 2020 Docker Compose CLI authors | ||||||
|  | 
 | ||||||
|  |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |    you may not use this file except in compliance with the License. | ||||||
|  |    You may obtain a copy of the License at | ||||||
|  | 
 | ||||||
|  |        http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | 
 | ||||||
|  |    Unless required by applicable law or agreed to in writing, software | ||||||
|  |    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |    See the License for the specific language governing permissions and | ||||||
|  |    limitations under the License. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package compose | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/moby/buildkit/util/tracing/detect" | ||||||
|  | 	"go.opentelemetry.io/otel" | ||||||
|  | 
 | ||||||
|  | 	_ "github.com/moby/buildkit/util/tracing/detect/delegated" //nolint:revive
 | ||||||
|  | 	_ "github.com/moby/buildkit/util/tracing/env"              //nolint:revive
 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	detect.ServiceName = "compose" | ||||||
|  | 	// do not log tracing errors to stdio
 | ||||||
|  | 	otel.SetErrorHandler(skipErrors{}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type skipErrors struct{} | ||||||
|  | 
 | ||||||
|  | func (skipErrors) Handle(err error) {} | ||||||
							
								
								
									
										12
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										12
									
								
								go.mod
								
								
								
								
							|  | @ -101,7 +101,7 @@ require ( | ||||||
| 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect | 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect | ||||||
| 	go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.29.0 // indirect | 	go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.29.0 // indirect | ||||||
| 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect | 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.29.0 // indirect | ||||||
| 	go.opentelemetry.io/otel v1.4.1 // indirect | 	go.opentelemetry.io/otel v1.4.1 | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect | ||||||
| 	go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect | 	go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/metric v0.27.0 // indirect | 	go.opentelemetry.io/otel/metric v0.27.0 // indirect | ||||||
|  | @ -122,7 +122,7 @@ require ( | ||||||
| 	gopkg.in/inf.v0 v0.9.1 // indirect | 	gopkg.in/inf.v0 v0.9.1 // indirect | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
| 	k8s.io/apimachinery v0.24.1 // indirect; see replace for the actual version used | 	k8s.io/apimachinery v0.24.1 // indirect; see replace for the actual version used | ||||||
| 	k8s.io/client-go v0.24.1 // indirect; see replace for the actual version used | 	k8s.io/client-go v0.24.1 // see replace for the actual version used | ||||||
| 	k8s.io/klog/v2 v2.60.1 // indirect | 	k8s.io/klog/v2 v2.60.1 // indirect | ||||||
| 	k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect | 	k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect | ||||||
| 	sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect | 	sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect | ||||||
|  | @ -130,9 +130,17 @@ require ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
|  | 	github.com/cenkalti/backoff/v4 v4.1.2 // indirect | ||||||
| 	github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 // indirect | 	github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 // indirect | ||||||
|  | 	github.com/googleapis/gnostic v0.5.5 // indirect | ||||||
|  | 	github.com/moby/spdystream v0.2.0 // indirect | ||||||
|  | 	github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect | ||||||
| 	github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c // indirect | 	github.com/zmap/zcrypto v0.0.0-20220605182715-4dfcec6e9a8c // indirect | ||||||
| 	github.com/zmap/zlint v1.1.0 // indirect | 	github.com/zmap/zlint v1.1.0 // indirect | ||||||
|  | 	go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 // indirect | ||||||
|  | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 // indirect | ||||||
|  | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1 // indirect | ||||||
|  | 	k8s.io/api v0.24.1 // indirect | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| replace ( | replace ( | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										9
									
								
								go.sum
								
								
								
								
							|  | @ -246,6 +246,7 @@ github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMS | ||||||
| github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= | github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= | ||||||
| github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= | github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= | ||||||
| github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= | github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= | ||||||
|  | github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= | ||||||
| github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= | github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||||
|  | @ -498,6 +499,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m | ||||||
| github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= | ||||||
| github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= | ||||||
| github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= | ||||||
|  | github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8= | ||||||
| github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= | github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= | ||||||
| github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= | github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= | ||||||
| github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= | ||||||
|  | @ -761,6 +763,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC | ||||||
| github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= | github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= | ||||||
| github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= | github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= | ||||||
| github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= | github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= | ||||||
|  | github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= | ||||||
| github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= | github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= | ||||||
| github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= | github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= | ||||||
| github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= | github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= | ||||||
|  | @ -1022,6 +1025,7 @@ github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4= | ||||||
| github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug= | github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug= | ||||||
| github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= | github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= | ||||||
| github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= | github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= | ||||||
|  | github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= | ||||||
| github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= | github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= | ||||||
| github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= | github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= | ||||||
| github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= | github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74= | ||||||
|  | @ -1235,6 +1239,7 @@ github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989/go.mod h1:i9l/TNj+y | ||||||
| github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= | github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= | ||||||
| github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | ||||||
| github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= | ||||||
|  | github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 h1:ka9QPuQg2u4LGipiZGsgkg3rJCo4iIUCy75FddM0GRQ= | ||||||
| github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= | github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= | ||||||
| github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= | github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= | ||||||
| github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= | github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= | ||||||
|  | @ -1465,13 +1470,16 @@ go.opentelemetry.io/otel v1.4.1/go.mod h1:StM6F/0fSwpd8dKWDCdRr7uRvEPYdW0hBSlbdT | ||||||
| go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI= | go.opentelemetry.io/otel/exporters/jaeger v1.4.1/go.mod h1:ZW7vkOu9nC1CxsD8bHNHCia5JUbwP39vxgd1q4Z5rCI= | ||||||
| go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= | go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= | go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= | ||||||
|  | go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1 h1:imIM3vRDMyZK1ypQlQlO+brE22I9lRhJsBDXpDWjlz8= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= | go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.4.1/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 h1:WPpPsAAs8I2rA47v5u0558meKmmwm1Dj99ZbqCV8sZ8= | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 h1:WPpPsAAs8I2rA47v5u0558meKmmwm1Dj99ZbqCV8sZ8= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8= | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1/go.mod h1:o5RW5o2pKpJLD5dNTCmjF1DorYwMeFJmb/rKr5sLaa8= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= | ||||||
|  | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1 h1:AxqDiGk8CorEXStMDZF5Hz9vo9Z7ZZ+I5m8JRl/ko40= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.4.1/go.mod h1:c6E4V3/U+miqjs/8l950wggHGL1qzlp0Ypj9xoGrPqo= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= | ||||||
|  | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1 h1:8qOago/OqoFclMUUj/184tZyRdDZFpcejSjbk5Jrl6Y= | ||||||
| go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1/go.mod h1:VwYo0Hak6Efuy0TXsZs8o1hnV3dHDPNtDbycG0hI8+M= | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.4.1/go.mod h1:VwYo0Hak6Efuy0TXsZs8o1hnV3dHDPNtDbycG0hI8+M= | ||||||
| go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk= | go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk= | ||||||
| go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw= | go.opentelemetry.io/otel/internal/metric v0.27.0/go.mod h1:n1CVxRqKqYZtqyTh9U/onvKapPGv7y/rpyOTI+LFNzw= | ||||||
|  | @ -1498,6 +1506,7 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||||
| go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | ||||||
| go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= | go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= | ||||||
|  | go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= | ||||||
| go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= | go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= | ||||||
| go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= | ||||||
| go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= | ||||||
|  |  | ||||||
|  | @ -81,6 +81,14 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti | ||||||
| 				Attrs: map[string]string{"ref": image}, | 				Attrs: map[string]string{"ref": image}, | ||||||
| 			}) | 			}) | ||||||
| 		} | 		} | ||||||
|  | 		if len(buildOptions.Platforms) > 1 { | ||||||
|  | 			buildOptions.Exports = []bclient.ExportEntry{{ | ||||||
|  | 				Type: "image", | ||||||
|  | 				Attrs: map[string]string{ | ||||||
|  | 					"push": "true", | ||||||
|  | 				}, | ||||||
|  | 			}} | ||||||
|  | 		} | ||||||
| 		opts[imageName] = buildOptions | 		opts[imageName] = buildOptions | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -162,6 +170,11 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
|  | 			if len(opt.Platforms) > 1 { | ||||||
|  | 				opt.Exports = []bclient.ExportEntry{{ | ||||||
|  | 					Type: "docker", | ||||||
|  | 				}} | ||||||
|  | 			} | ||||||
| 			opts[imageName] = opt | 			opts[imageName] = opt | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  | @ -206,7 +219,7 @@ func (s *composeService) doBuild(ctx context.Context, project *types.Project, op | ||||||
| 	if buildkitEnabled, err := s.dockerCli.BuildKitEnabled(); err != nil || !buildkitEnabled { | 	if buildkitEnabled, err := s.dockerCli.BuildKitEnabled(); err != nil || !buildkitEnabled { | ||||||
| 		return s.doBuildClassic(ctx, project, opts) | 		return s.doBuildClassic(ctx, project, opts) | ||||||
| 	} | 	} | ||||||
| 	return s.doBuildBuildkit(ctx, project, opts, mode) | 	return s.doBuildBuildkit(ctx, opts, mode) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (s *composeService) toBuildOptions(project *types.Project, service types.ServiceConfig, imageTag string, sshKeys []types.SSHKey) (build.Options, error) { | func (s *composeService) toBuildOptions(project *types.Project, service types.ServiceConfig, imageTag string, sshKeys []types.SSHKey) (build.Options, error) { | ||||||
|  | @ -215,20 +228,9 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se | ||||||
| 
 | 
 | ||||||
| 	buildArgs := flatten(service.Build.Args.Resolve(envResolver(project.Environment))) | 	buildArgs := flatten(service.Build.Args.Resolve(envResolver(project.Environment))) | ||||||
| 
 | 
 | ||||||
| 	var plats []specs.Platform | 	plats, err := addPlatforms(project, service) | ||||||
| 	if platform, ok := project.Environment["DOCKER_DEFAULT_PLATFORM"]; ok { | 	if err != nil { | ||||||
| 		p, err := platforms.Parse(platform) | 		return build.Options{}, err | ||||||
| 		if err != nil { |  | ||||||
| 			return build.Options{}, err |  | ||||||
| 		} |  | ||||||
| 		plats = append(plats, p) |  | ||||||
| 	} |  | ||||||
| 	if service.Platform != "" { |  | ||||||
| 		p, err := platforms.Parse(service.Platform) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return build.Options{}, err |  | ||||||
| 		} |  | ||||||
| 		plats = append(plats, p) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	cacheFrom, err := buildflags.ParseCacheEntry(service.Build.CacheFrom) | 	cacheFrom, err := buildflags.ParseCacheEntry(service.Build.CacheFrom) | ||||||
|  | @ -352,3 +354,26 @@ func addSecretsConfig(project *types.Project, service types.ServiceConfig) (sess | ||||||
| 	} | 	} | ||||||
| 	return secretsprovider.NewSecretProvider(store), nil | 	return secretsprovider.NewSecretProvider(store), nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func addPlatforms(project *types.Project, service types.ServiceConfig) ([]specs.Platform, error) { | ||||||
|  | 	var plats []specs.Platform | ||||||
|  | 	if platform, ok := project.Environment["DOCKER_DEFAULT_PLATFORM"]; ok { | ||||||
|  | 		p, err := platforms.Parse(platform) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		plats = append(plats, p) | ||||||
|  | 	} | ||||||
|  | 	if service.Platform != "" && !utils.StringContains(service.Build.Platforms, service.Platform) { | ||||||
|  | 		return nil, fmt.Errorf("service.platform should be part of the service.build.platforms: %q", service.Platform) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, buildPlatform := range service.Build.Platforms { | ||||||
|  | 		p, err := platforms.Parse(buildPlatform) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		plats = append(plats, p) | ||||||
|  | 	} | ||||||
|  | 	return plats, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -18,27 +18,36 @@ package compose | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/url" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	ctxkube "github.com/docker/buildx/driver/kubernetes/context" | ||||||
|  | 	"github.com/docker/buildx/store" | ||||||
|  | 	"github.com/docker/buildx/store/storeutil" | ||||||
|  | 	"github.com/docker/cli/cli/command" | ||||||
|  | 	"github.com/docker/cli/cli/context/docker" | ||||||
|  | 	ctxstore "github.com/docker/cli/cli/context/store" | ||||||
|  | 	dockerclient "github.com/docker/docker/client" | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | 	"golang.org/x/sync/errgroup" | ||||||
|  | 	"k8s.io/client-go/tools/clientcmd" | ||||||
| 
 | 
 | ||||||
| 	"github.com/compose-spec/compose-go/types" |  | ||||||
| 	"github.com/docker/buildx/build" | 	"github.com/docker/buildx/build" | ||||||
| 	"github.com/docker/buildx/driver" | 	"github.com/docker/buildx/driver" | ||||||
|  | 	_ "github.com/docker/buildx/driver/docker"           //nolint:revive
 | ||||||
|  | 	_ "github.com/docker/buildx/driver/docker-container" //nolint:revive
 | ||||||
|  | 	_ "github.com/docker/buildx/driver/kubernetes"       //nolint:revive
 | ||||||
| 	xprogress "github.com/docker/buildx/util/progress" | 	xprogress "github.com/docker/buildx/util/progress" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Project, opts map[string]build.Options, mode string) (map[string]string, error) { | func (s *composeService) doBuildBuildkit(ctx context.Context, opts map[string]build.Options, mode string) (map[string]string, error) { | ||||||
| 	const drivername = "default" | 	dis, err := s.getDrivers(ctx) | ||||||
| 	d, err := driver.GetDriver(ctx, drivername, nil, s.apiClient(), s.configFile(), nil, nil, nil, nil, nil, project.WorkingDir) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	driverInfo := []build.DriverInfo{ |  | ||||||
| 		{ |  | ||||||
| 			Name:   drivername, |  | ||||||
| 			Driver: d, |  | ||||||
| 		}, |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// Progress needs its own context that lives longer than the
 | 	// Progress needs its own context that lives longer than the
 | ||||||
| 	// build one otherwise it won't read all the messages from
 | 	// build one otherwise it won't read all the messages from
 | ||||||
|  | @ -48,7 +57,7 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Pro | ||||||
| 	w := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode) | 	w := xprogress.NewPrinter(progressCtx, s.stdout(), os.Stdout, mode) | ||||||
| 
 | 
 | ||||||
| 	// We rely on buildx "docker" builder integrated in docker engine, so don't need a DockerAPI here
 | 	// We rely on buildx "docker" builder integrated in docker engine, so don't need a DockerAPI here
 | ||||||
| 	response, err := build.Build(ctx, driverInfo, opts, nil, filepath.Dir(s.configFile().Filename), w) | 	response, err := build.Build(ctx, dis, opts, nil, filepath.Dir(s.configFile().Filename), w) | ||||||
| 	errW := w.Wait() | 	errW := w.Wait() | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		err = errW | 		err = errW | ||||||
|  | @ -71,3 +80,175 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Pro | ||||||
| 
 | 
 | ||||||
| 	return imagesBuilt, err | 	return imagesBuilt, err | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (s *composeService) getDrivers(ctx context.Context) ([]build.DriverInfo, error) { //nolint:gocyclo
 | ||||||
|  | 	txn, release, err := storeutil.GetStore(s.dockerCli) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	defer release() | ||||||
|  | 
 | ||||||
|  | 	ng, err := storeutil.GetCurrentInstance(txn, s.dockerCli) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	dis := make([]build.DriverInfo, len(ng.Nodes)) | ||||||
|  | 	var f driver.Factory | ||||||
|  | 	if ng.Driver != "" { | ||||||
|  | 		factories := driver.GetFactories() | ||||||
|  | 		for _, fac := range factories { | ||||||
|  | 			if fac.Name() == ng.Driver { | ||||||
|  | 				f = fac | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		f = driver.GetFactory(ng.Driver, true) | ||||||
|  | 		if f == nil { | ||||||
|  | 			return nil, fmt.Errorf("failed to find buildx driver %q", ng.Driver) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		ep := ng.Nodes[0].Endpoint | ||||||
|  | 		dockerapi, err := clientForEndpoint(s.dockerCli, ep) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		f, err = driver.GetDefaultFactory(ctx, dockerapi, false) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		ng.Driver = f.Name() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	imageopt, err := storeutil.GetImageConfig(s.dockerCli, ng) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	eg, _ := errgroup.WithContext(ctx) | ||||||
|  | 	for i, n := range ng.Nodes { | ||||||
|  | 		func(i int, n store.Node) { | ||||||
|  | 			eg.Go(func() error { | ||||||
|  | 				di := build.DriverInfo{ | ||||||
|  | 					Name:        n.Name, | ||||||
|  | 					Platform:    n.Platforms, | ||||||
|  | 					ProxyConfig: storeutil.GetProxyConfig(s.dockerCli), | ||||||
|  | 				} | ||||||
|  | 				defer func() { | ||||||
|  | 					dis[i] = di | ||||||
|  | 				}() | ||||||
|  | 
 | ||||||
|  | 				dockerapi, err := clientForEndpoint(s.dockerCli, n.Endpoint) | ||||||
|  | 				if err != nil { | ||||||
|  | 					di.Err = err | ||||||
|  | 					return nil | ||||||
|  | 				} | ||||||
|  | 				// TODO: replace the following line with dockerclient.WithAPIVersionNegotiation option in clientForEndpoint
 | ||||||
|  | 				dockerapi.NegotiateAPIVersion(ctx) | ||||||
|  | 
 | ||||||
|  | 				contextStore := s.dockerCli.ContextStore() | ||||||
|  | 
 | ||||||
|  | 				var kcc driver.KubeClientConfig | ||||||
|  | 				kcc, err = configFromContext(n.Endpoint, contextStore) | ||||||
|  | 				if err != nil { | ||||||
|  | 					// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
 | ||||||
|  | 					// try again with name="default".
 | ||||||
|  | 					// FIXME: n should retain real context name.
 | ||||||
|  | 					kcc, err = configFromContext("default", contextStore) | ||||||
|  | 					if err != nil { | ||||||
|  | 						logrus.Error(err) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				tryToUseKubeConfigInCluster := false | ||||||
|  | 				if kcc == nil { | ||||||
|  | 					tryToUseKubeConfigInCluster = true | ||||||
|  | 				} else { | ||||||
|  | 					if _, err := kcc.ClientConfig(); err != nil { | ||||||
|  | 						tryToUseKubeConfigInCluster = true | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if tryToUseKubeConfigInCluster { | ||||||
|  | 					kccInCluster := driver.KubeClientConfigInCluster{} | ||||||
|  | 					if _, err := kccInCluster.ClientConfig(); err == nil { | ||||||
|  | 						logrus.Debug("using kube config in cluster") | ||||||
|  | 						kcc = kccInCluster | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.Platforms, "") | ||||||
|  | 				if err != nil { | ||||||
|  | 					di.Err = err | ||||||
|  | 					return nil | ||||||
|  | 				} | ||||||
|  | 				di.Driver = d | ||||||
|  | 				di.ImageOpt = imageopt | ||||||
|  | 				return nil | ||||||
|  | 			}) | ||||||
|  | 		}(i, n) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := eg.Wait(); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return dis, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func clientForEndpoint(dockerCli command.Cli, name string) (dockerclient.APIClient, error) { | ||||||
|  | 	list, err := dockerCli.ContextStore().List() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	for _, l := range list { | ||||||
|  | 		if l.Name != name { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		dep, ok := l.Endpoints["docker"] | ||||||
|  | 		if !ok { | ||||||
|  | 			return nil, fmt.Errorf("context %q does not have a Docker endpoint", name) | ||||||
|  | 		} | ||||||
|  | 		epm, ok := dep.(docker.EndpointMeta) | ||||||
|  | 		if !ok { | ||||||
|  | 			return nil, fmt.Errorf("endpoint %q is not of type EndpointMeta, %T", dep, dep) | ||||||
|  | 		} | ||||||
|  | 		ep, err := docker.WithTLSData(dockerCli.ContextStore(), name, epm) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		clientOpts, err := ep.ClientOpts() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		return dockerclient.NewClientWithOpts(clientOpts...) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ep := docker.Endpoint{ | ||||||
|  | 		EndpointMeta: docker.EndpointMeta{ | ||||||
|  | 			Host: name, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	clientOpts, err := ep.ClientOpts() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return dockerclient.NewClientWithOpts(clientOpts...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func configFromContext(endpointName string, s ctxstore.Reader) (clientcmd.ClientConfig, error) { | ||||||
|  | 	if strings.HasPrefix(endpointName, "kubernetes://") { | ||||||
|  | 		u, _ := url.Parse(endpointName) | ||||||
|  | 		if kubeconfig := u.Query().Get("kubeconfig"); kubeconfig != "" { | ||||||
|  | 			_ = os.Setenv(clientcmd.RecommendedConfigPathEnvVar, kubeconfig) | ||||||
|  | 		} | ||||||
|  | 		rules := clientcmd.NewDefaultClientConfigLoadingRules() | ||||||
|  | 		apiConfig, err := rules.Load() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		return clientcmd.NewDefaultClientConfig(*apiConfig, &clientcmd.ConfigOverrides{}), nil | ||||||
|  | 	} | ||||||
|  | 	return ctxkube.ConfigFromContext(endpointName, s) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -89,6 +89,10 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if len(options.Platforms) > 1 { | ||||||
|  | 		return "", errors.Errorf("this builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use multi-arch builder") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	switch { | 	switch { | ||||||
| 	case isLocalDir(specifiedContext): | 	case isLocalDir(specifiedContext): | ||||||
| 		contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName) | 		contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName) | ||||||
|  |  | ||||||
|  | @ -243,3 +243,73 @@ func TestBuildImageDependencies(t *testing.T) { | ||||||
| 		t.Skip("See https://github.com/docker/compose/issues/9232") | 		t.Skip("See https://github.com/docker/compose/issues/9232") | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestBuildPlatformsWithCorrectBuildxConfig(t *testing.T) { | ||||||
|  | 	c := NewParallelCLI(t) | ||||||
|  | 
 | ||||||
|  | 	// declare builder
 | ||||||
|  | 	result := c.RunDockerCmd(t, "buildx", "create", "--name", "build-platform", "--use", "--bootstrap", "--driver-opt", | ||||||
|  | 		"network=host", "--buildkitd-flags", "--allow-insecure-entitlement network.host") | ||||||
|  | 	assert.NilError(t, result.Error) | ||||||
|  | 
 | ||||||
|  | 	// start local registry
 | ||||||
|  | 	result = c.RunDockerCmd(t, "run", "-d", "-p", "5001:5000", "--restart=always", | ||||||
|  | 		"--name", "registry", "registry:2") | ||||||
|  | 	assert.NilError(t, result.Error) | ||||||
|  | 
 | ||||||
|  | 	t.Cleanup(func() { | ||||||
|  | 		_ = c.RunDockerCmd(t, "buildx", "rm", "-f", "build-platform") | ||||||
|  | 		_ = c.RunDockerCmd(t, "rm", "-f", "registry") | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("platform not supported by builder", func(t *testing.T) { | ||||||
|  | 		res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms", | ||||||
|  | 			"-f", "fixtures/build-test/platforms/compose-unsupported-platform.yml", "build") | ||||||
|  | 		res.Assert(t, icmd.Expected{ | ||||||
|  | 			ExitCode: 17, | ||||||
|  | 			Err:      "failed to solve: alpine: no match for platform in", | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("multi-arch build ok", func(t *testing.T) { | ||||||
|  | 		res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms", "build") | ||||||
|  | 		assert.NilError(t, res.Error, res.Stderr()) | ||||||
|  | 		res = c.RunDockerCmd(t, "manifest", "inspect", "--insecure", "localhost:5001/build-test-platform:test") | ||||||
|  | 		res.Assert(t, icmd.Expected{Out: `"architecture": "amd64",`}) | ||||||
|  | 		res.Assert(t, icmd.Expected{Out: `"architecture": "arm64",`}) | ||||||
|  | 
 | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestBuildPlatformsStandardErrors(t *testing.T) { | ||||||
|  | 	c := NewParallelCLI(t) | ||||||
|  | 
 | ||||||
|  | 	t.Run("no platform support with Classic Builder", func(t *testing.T) { | ||||||
|  | 		cmd := c.NewDockerComposeCmd(t, "--project-directory", "fixtures/build-test/platforms", "build") | ||||||
|  | 
 | ||||||
|  | 		res := icmd.RunCmd(cmd, func(cmd *icmd.Cmd) { | ||||||
|  | 			cmd.Env = append(cmd.Env, "DOCKER_BUILDKIT=0") | ||||||
|  | 		}) | ||||||
|  | 		res.Assert(t, icmd.Expected{ | ||||||
|  | 			ExitCode: 1, | ||||||
|  | 			Err:      "this builder doesn't support multi-arch build, set DOCKER_BUILDKIT=1 to use multi-arch builder", | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("builder does not support multi-arch", func(t *testing.T) { | ||||||
|  | 		res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms", "build") | ||||||
|  | 		res.Assert(t, icmd.Expected{ | ||||||
|  | 			ExitCode: 17, | ||||||
|  | 			Err:      `multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")`, | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	t.Run("service platform not defined in platforms build section", func(t *testing.T) { | ||||||
|  | 		res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/build-test/platforms", | ||||||
|  | 			"-f", "fixtures/build-test/platforms/compose-service-platform-not-in-build-platforms.yaml", "build") | ||||||
|  | 		res.Assert(t, icmd.Expected{ | ||||||
|  | 			ExitCode: 1, | ||||||
|  | 			Err:      `service.platform should be part of the service.build.platforms: "linux/riscv64"`, | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | #   Copyright 2020 Docker Compose CLI authors | ||||||
|  | 
 | ||||||
|  | #   Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | #   you may not use this file except in compliance with the License. | ||||||
|  | #   You may obtain a copy of the License at | ||||||
|  | 
 | ||||||
|  | #       http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | 
 | ||||||
|  | #   Unless required by applicable law or agreed to in writing, software | ||||||
|  | #   distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | #   See the License for the specific language governing permissions and | ||||||
|  | #   limitations under the License. | ||||||
|  | 
 | ||||||
|  | FROM alpine | ||||||
|  | 
 | ||||||
|  | RUN echo "SUCCESS" | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | services: | ||||||
|  |   platforms: | ||||||
|  |     image: build-test-platform:test | ||||||
|  |     platform: linux/riscv64 | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       platforms: | ||||||
|  |         - linux/amd64 | ||||||
|  |         - linux/arm64 | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | services: | ||||||
|  |   platforms: | ||||||
|  |     image: build-test-platform:test | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       platforms: | ||||||
|  |         - unsupported/unsupported | ||||||
|  |         - linux/amd64 | ||||||
|  | @ -0,0 +1,10 @@ | ||||||
|  | services: | ||||||
|  |   platforms: | ||||||
|  |     image: localhost:5001/build-test-platform:test | ||||||
|  |     platform: linux/amd64 | ||||||
|  |     build: | ||||||
|  |       context: . | ||||||
|  |       platforms: | ||||||
|  |         - linux/amd64 | ||||||
|  |         - linux/arm64 | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue