github.com/apptainer/singularity@v3.1.1+incompatible/pkg/build/types/bundle.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package types
     7  
     8  import (
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  
    13  	ocitypes "github.com/containers/image/types"
    14  	"github.com/sylabs/singularity/internal/pkg/sylog"
    15  )
    16  
    17  // Bundle is the temporary build environment used during the image
    18  // building process. A Bundle is the programmatic representation of
    19  // the directory structure which will constitute this environmenb.
    20  // /tmp/...:
    21  //     fs/ - A chroot filesystem
    22  //     .singularity.d/ - Container metadata (from 2.x image format)
    23  //     config.json (optional) - Contain information for OCI image bundle
    24  //     etc... - The Bundle dir can theoretically contain arbitrary directories,
    25  //              files, etc... which can be interpreted by the Chef
    26  type Bundle struct {
    27  	// FSObjects is a map of the filesystem objects contained in the Bundle. An object
    28  	// will be built as one section of a SIF file.
    29  	//
    30  	// Known FSObjects labels:
    31  	//   * rootfs -> root file system
    32  	//   * .singularity.d -> .singularity.d directory (includes image exec scripts)
    33  	//   * data -> directory containing data files
    34  	FSObjects   map[string]string `json:"fsObjects"`
    35  	JSONObjects map[string][]byte `json:"jsonObjects"`
    36  	Recipe      Definition        `json:"rawDeffile"`
    37  	BindPath    []string          `json:"bindPath"`
    38  	Path        string            `json:"bundlePath"`
    39  	Opts        Options           `json:"opts"`
    40  }
    41  
    42  // Options ...
    43  type Options struct {
    44  	// TmpDir specifies a non-standard temporary location to perform a build
    45  	TmpDir string
    46  	// sections are the parts of the definition to run during the build
    47  	Sections []string `json:"sections"`
    48  	// noTest indicates if build should skip running the test script
    49  	NoTest bool `json:"noTest"`
    50  	// force automatically deletes an existing container at build destination while performing build
    51  	Force bool `json:"force"`
    52  	// update detects and builds using an existing sandbox container at build destination
    53  	Update bool `json:"update"`
    54  	// noHTTPS
    55  	NoHTTPS bool `json:"noHTTPS"`
    56  	// contains docker credentials if specified
    57  	DockerAuthConfig *ocitypes.DockerAuthConfig
    58  	// NoCleanUp allows a user to prevent a bundle from being cleaned up after a failed build
    59  	// useful for debugging
    60  	NoCleanUp bool `json:"noCleanUp"`
    61  }
    62  
    63  // NewBundle creates a Bundle environment
    64  func NewBundle(bundleDir, bundlePrefix string) (b *Bundle, err error) {
    65  	b = &Bundle{}
    66  	b.JSONObjects = make(map[string][]byte)
    67  
    68  	if bundlePrefix == "" {
    69  		bundlePrefix = "sbuild-"
    70  	}
    71  
    72  	b.Path, err = ioutil.TempDir(bundleDir, bundlePrefix+"-")
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	sylog.Debugf("Created temporary directory for bundle %v\n", b.Path)
    77  
    78  	b.FSObjects = map[string]string{
    79  		"rootfs": "fs",
    80  	}
    81  
    82  	for _, fso := range b.FSObjects {
    83  		if err = os.MkdirAll(filepath.Join(b.Path, fso), 0755); err != nil {
    84  			return
    85  		}
    86  	}
    87  
    88  	return b, nil
    89  }
    90  
    91  // Rootfs give the path to the root filesystem in the Bundle
    92  func (b *Bundle) Rootfs() string {
    93  	return filepath.Join(b.Path, b.FSObjects["rootfs"])
    94  }
    95  
    96  // RunSection iterates through the sections specified in a bundle
    97  // and returns true if the given string, s, is a section of the
    98  // definition that should be executed during the build process
    99  func (b Bundle) RunSection(s string) bool {
   100  	for _, section := range b.Opts.Sections {
   101  		if section == "none" {
   102  			return false
   103  		}
   104  		if section == "all" || section == s {
   105  			return true
   106  		}
   107  	}
   108  	return false
   109  }