Skip to content

Commit e2ec64f

Browse files
Support --platform docker CLI argument to target the platform specific image architecture (#103)
Closes #97
1 parent 956adf0 commit e2ec64f

File tree

15 files changed

+61
-20
lines changed

15 files changed

+61
-20
lines changed

builder/docker/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ type Config struct {
112112
// running on a windows host. This is necessary for building Windows
113113
// containers, because our normal docker bindings do not work for them.
114114
WindowsContainer bool `mapstructure:"windows_container" required:"false"`
115+
// Set platform if server is multi-platform capable
116+
Platform string `mapstructure:"platform" required:"false"`
115117

116118
// This is used to login to dockerhub to pull a private base container. For
117119
// pushing to dockerhub, see the docker post-processors

builder/docker/config.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder/docker/driver.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Driver interface {
2020
Export(id string, dst io.Writer) error
2121

2222
// Import imports a container from a tar file
23-
Import(path string, changes []string, repo string) (string, error)
23+
Import(path string, changes []string, repo string, platform string) (string, error)
2424

2525
// IPAddress returns the address of the container that can be used
2626
// for external access.
@@ -40,10 +40,10 @@ type Driver interface {
4040
Logout(repo string) error
4141

4242
// Pull should pull down the given image.
43-
Pull(image string) error
43+
Pull(image string, platform string) error
4444

4545
// Push pushes an image to a Docker index/registry.
46-
Push(name string) error
46+
Push(name string, platform string) error
4747

4848
// Save an image with the given ID to the given writer.
4949
SaveImage(id string, dst io.Writer) error
@@ -79,6 +79,7 @@ type ContainerConfig struct {
7979
TmpFs []string
8080
Privileged bool
8181
Runtime string
82+
Platform string
8283
}
8384

8485
// This is the template that is used for the RunCommand in the ContainerConfig.

builder/docker/driver_docker.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (d *DockerDriver) Export(id string, dst io.Writer) error {
101101
return nil
102102
}
103103

104-
func (d *DockerDriver) Import(path string, changes []string, repo string) (string, error) {
104+
func (d *DockerDriver) Import(path string, changes []string, repo string, platform string) (string, error) {
105105
var stdout, stderr bytes.Buffer
106106

107107
args := []string{"import"}
@@ -110,6 +110,10 @@ func (d *DockerDriver) Import(path string, changes []string, repo string) (strin
110110
args = append(args, "--change", change)
111111
}
112112

113+
if platform != "" {
114+
args = append(args, "--platform", platform)
115+
}
116+
113117
args = append(args, "-")
114118
args = append(args, repo)
115119

@@ -275,15 +279,23 @@ func (d *DockerDriver) Logout(repo string) error {
275279
return err
276280
}
277281

278-
func (d *DockerDriver) Pull(image string) error {
282+
func (d *DockerDriver) Pull(image string, platform string) error {
279283
cmd := d.newCommandWithConfig("pull", image)
280284

285+
if platform != "" {
286+
cmd.Args = append(cmd.Args, "--platform", platform)
287+
}
288+
281289
return runAndStream(cmd, d.Ui)
282290
}
283291

284-
func (d *DockerDriver) Push(name string) error {
292+
func (d *DockerDriver) Push(name string, platform string) error {
285293
cmd := d.newCommandWithConfig("push", name)
286294

295+
if platform != "" {
296+
cmd.Args = append(cmd.Args, "--platform", platform)
297+
}
298+
287299
return runAndStream(cmd, d.Ui)
288300
}
289301

@@ -331,6 +343,9 @@ func (d *DockerDriver) StartContainer(config *ContainerConfig) (string, error) {
331343
if config.Runtime != "" {
332344
args = append(args, "--runtime", config.Runtime)
333345
}
346+
if config.Platform != "" {
347+
args = append(args, "--platform", config.Platform)
348+
}
334349
for _, v := range config.TmpFs {
335350
args = append(args, "--tmpfs", v)
336351
}

builder/docker/driver_mock.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ type MockDriver struct {
1717
DeleteImageId string
1818
DeleteImageErr error
1919

20-
ImportCalled bool
21-
ImportPath string
22-
ImportRepo string
23-
ImportId string
24-
ImportErr error
20+
ImportCalled bool
21+
ImportPath string
22+
ImportRepo string
23+
ImportId string
24+
ImportPlatform string
25+
ImportErr error
2526

2627
IPAddressCalled bool
2728
IPAddressID string
@@ -52,9 +53,10 @@ type MockDriver struct {
5253
LogoutRepo string
5354
LogoutErr error
5455

55-
PushCalled bool
56-
PushName string
57-
PushErr error
56+
PushCalled bool
57+
PushName string
58+
PushPlatform string
59+
PushErr error
5860

5961
SaveImageCalled bool
6062
SaveImageId string
@@ -79,6 +81,7 @@ type MockDriver struct {
7981
ExportID string
8082
PullCalled bool
8183
PullImage string
84+
PullPlatform string
8285
StartCalled bool
8386
StartConfig *ContainerConfig
8487
StopCalled bool
@@ -115,10 +118,11 @@ func (d *MockDriver) Export(id string, dst io.Writer) error {
115118
return d.ExportError
116119
}
117120

118-
func (d *MockDriver) Import(path string, changes []string, repo string) (string, error) {
121+
func (d *MockDriver) Import(path string, changes []string, repo string, platform string) (string, error) {
119122
d.ImportCalled = true
120123
d.ImportPath = path
121124
d.ImportRepo = repo
125+
d.ImportPlatform = platform
122126
return d.ImportId, d.ImportErr
123127
}
124128

@@ -154,15 +158,17 @@ func (d *MockDriver) Logout(r string) error {
154158
return d.LogoutErr
155159
}
156160

157-
func (d *MockDriver) Pull(image string) error {
161+
func (d *MockDriver) Pull(image string, platform string) error {
158162
d.PullCalled = true
159163
d.PullImage = image
164+
d.PullPlatform = platform
160165
return d.PullError
161166
}
162167

163-
func (d *MockDriver) Push(name string) error {
168+
func (d *MockDriver) Push(name string, platform string) error {
164169
d.PushCalled = true
165170
d.PushName = name
171+
d.PushPlatform = platform
166172
return d.PushErr
167173
}
168174

builder/docker/step_pull.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (s *StepPull) Run(ctx context.Context, state multistep.StateBag) multistep.
9393
}()
9494
}
9595

96-
if err := driver.Pull(config.Image); err != nil {
96+
if err := driver.Pull(config.Image, config.Platform); err != nil {
9797
err := fmt.Errorf("Error pulling Docker image: %s", err)
9898
state.Put("error", err)
9999
ui.Error(err.Error())

builder/docker/step_run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func (s *StepRun) Run(ctx context.Context, state multistep.StateBag) multistep.S
3232
CapDrop: config.CapDrop,
3333
Privileged: config.Privileged,
3434
Runtime: config.Runtime,
35+
Platform: config.Platform,
3536
}
3637

3738
for host, container := range config.Volumes {

docs-partials/builder/docker/Config-not-required.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
running on a windows host. This is necessary for building Windows
6666
containers, because our normal docker bindings do not work for them.
6767

68+
- `platform` (string) - Set platform if server is multi-platform capable
69+
6870
- `login` (bool) - This is used to login to dockerhub to pull a private base container. For
6971
pushing to dockerhub, see the docker post-processors
7072

docs/builders/docker.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ You must specify (only) one of `commit`, `discard`, or `export_path`.
296296
running on a windows host. This is necessary for building Windows
297297
containers, because our normal docker bindings do not work for them.
298298

299+
- `platform` (string) - Set platform if server is multi-platform capable.
300+
299301
- `login` (bool) - This is used to login to dockerhub to pull a private base container. For
300302
pushing to dockerhub, see the docker post-processors
301303

docs/post-processors/docker-import.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ is optional.
8888
- `keep_input_artifact` (boolean) - if true, do not delete the source tar
8989
after importing it to docker. Defaults to false.
9090

91+
- `platform` (string) - Set platform if server is multi-platform capable.
92+
9193
## Example
9294

9395
An example is shown below, showing only the post-processor configuration:

docs/post-processors/docker-push.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ This post-processor has only optional configuration:
4545
after pushing it to the cloud. Defaults to true, but can be set to false if
4646
you do not need to save your local copy of the docker container.
4747

48+
- `platform` (string) - Set platform if server is multi-platform capable.
49+
4850
- `login` (boolean) - Defaults to false. If true, the post-processor will
4951
login prior to pushing. For log into ECR see `ecr_login`.
5052

post-processor/docker-import/post-processor.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Config struct {
2222
Repository string `mapstructure:"repository"`
2323
Tag string `mapstructure:"tag"`
2424
Changes []string `mapstructure:"changes"`
25+
Platform string `mapstructure:"platform"`
2526

2627
ctx interpolate.Context
2728
}
@@ -73,7 +74,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packersdk.Ui, artifa
7374

7475
ui.Message("Importing image: " + artifact.Id())
7576
ui.Message("Repository: " + importRepo)
76-
id, err := driver.Import(artifact.Files()[0], p.config.Changes, importRepo)
77+
id, err := driver.Import(artifact.Files()[0], p.config.Changes, importRepo, p.config.Platform)
7778
if err != nil {
7879
return nil, false, false, err
7980
}

post-processor/docker-import/post-processor.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

post-processor/docker-push/post-processor.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Config struct {
2727
LoginPassword string `mapstructure:"login_password"`
2828
LoginServer string `mapstructure:"login_server"`
2929
EcrLogin bool `mapstructure:"ecr_login"`
30+
Platform string `mapstructure:"platform"`
3031
docker.AwsAccessConfig `mapstructure:",squash"`
3132

3233
ctx interpolate.Context
@@ -147,7 +148,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packersdk.Ui, artifa
147148
// Get the name.
148149
for _, name := range names {
149150
ui.Message("Pushing: " + name)
150-
if err := driver.Push(name); err != nil {
151+
if err := driver.Push(name, p.config.Platform); err != nil {
151152
return nil, false, false, err
152153
}
153154
}

post-processor/docker-push/post-processor.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)