@@ -5,8 +5,10 @@ import (
5
5
"encoding/json"
6
6
"errors"
7
7
"fmt"
8
+ "io"
8
9
"os"
9
10
"path/filepath"
11
+ "strings"
10
12
"sync"
11
13
"syscall"
12
14
"time"
@@ -32,6 +34,19 @@ const containerSizeToDiskSizeMultiplier = 2
32
34
const diskSizeMinimum = 10 * 1024 * 1024 * 1024 // 10GB
33
35
const imageMetaXattr = "user.bootc.meta"
34
36
37
+ // tempLosetupWrapperContents is a workaround for https://github.com/containers/bootc/pull/487/commits/89d34c7dbcb8a1fa161f812c6ba0a8b49ccbe00f
38
+ const tempLosetupWrapperContents = `#!/bin/bash
39
+ set -euo pipefail
40
+ args=()
41
+ for arg in "$@"; do
42
+ case $arg in
43
+ --direct-io=*) echo "ignoring: $arg" 1>&2;;
44
+ *) args+="$arg" ;;
45
+ esac
46
+ done
47
+ exec /usr/sbin/losetup "$@"
48
+ `
49
+
35
50
// DiskImageConfig defines configuration for the
36
51
type DiskImageConfig struct {
37
52
Filesystem string
@@ -278,7 +293,20 @@ func (p *BootcDisk) pullImage() (err error) {
278
293
279
294
// runInstallContainer runs the bootc installer in a container to create a disk image
280
295
func (p * BootcDisk ) runInstallContainer (quiet bool , config DiskImageConfig ) (err error ) {
281
- createResponse , err := p .createInstallContainer (config )
296
+ // Create a temporary external shell script with the contents of our losetup wrapper
297
+ losetupTemp , err := os .CreateTemp (p .Directory , "losetup-wrapper" )
298
+ if err != nil {
299
+ return fmt .Errorf ("temp losetup wrapper: %w" , err )
300
+ }
301
+ defer os .Remove (losetupTemp .Name ())
302
+ if _ , err := io .Copy (losetupTemp , strings .NewReader (tempLosetupWrapperContents )); err != nil {
303
+ return fmt .Errorf ("temp losetup wrapper copy: %w" , err )
304
+ }
305
+ if err := losetupTemp .Chmod (0o755 ); err != nil {
306
+ return fmt .Errorf ("temp losetup wrapper chmod: %w" , err )
307
+ }
308
+
309
+ createResponse , err := p .createInstallContainer (config , losetupTemp .Name ())
282
310
if err != nil {
283
311
return fmt .Errorf ("failed to create container: %w" , err )
284
312
}
@@ -360,7 +388,7 @@ func (p *BootcDisk) runInstallContainer(quiet bool, config DiskImageConfig) (err
360
388
}
361
389
362
390
// createInstallContainer creates a container to run the bootc installer
363
- func (p * BootcDisk ) createInstallContainer (config DiskImageConfig ) (createResponse types.ContainerCreateResponse , err error ) {
391
+ func (p * BootcDisk ) createInstallContainer (config DiskImageConfig , tempLosetup string ) (createResponse types.ContainerCreateResponse , err error ) {
364
392
privileged := true
365
393
autoRemove := true
366
394
labelNested := true
@@ -405,6 +433,13 @@ func (p *BootcDisk) createInstallContainer(config DiskImageConfig) (createRespon
405
433
Destination : "/output" ,
406
434
Type : "bind" ,
407
435
},
436
+ {
437
+ Source : tempLosetup ,
438
+ // Note that the default $PATH has /usr/local/sbin first
439
+ Destination : "/usr/local/sbin/losetup" ,
440
+ Type : "bind" ,
441
+ Options : []string {"ro" },
442
+ },
408
443
},
409
444
},
410
445
ContainerSecurityConfig : specgen.ContainerSecurityConfig {
0 commit comments