@@ -1414,6 +1414,12 @@ func (b *Builder) setupMounts(mountPoint string, spec *specs.Spec, bundlePath st
14141414 mounts = append (mounts , mount )
14151415 }
14161416
1417+ // Some mounts require env vars to be set, do these here
1418+ spec .Process .Env = append (spec .Process .Env , mountArtifacts .SecretEnvVars ... )
1419+ if mountArtifacts .SSHAuthSock != "" {
1420+ spec .Process .Env = append (spec .Process .Env , "SSH_AUTH_SOCK=" + mountArtifacts .SSHAuthSock )
1421+ }
1422+
14171423 // Set the list in the spec.
14181424 spec .Mounts = mounts
14191425 succeeded = true
@@ -1503,6 +1509,7 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
15031509 intermediateMounts := make ([]string , 0 , len (mounts ))
15041510 finalMounts := make ([]specs.Mount , 0 , len (mounts ))
15051511 agents := make ([]* sshagent.AgentServer , 0 , len (mounts ))
1512+ var secretEnvVars []string
15061513 defaultSSHSock := ""
15071514 targetLocks := []* lockfile.LockFile {}
15081515 var overlayDirs []string
@@ -1542,11 +1549,7 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
15421549 }
15431550 }()
15441551 for _ , mount := range mounts {
1545- var mountSpec * specs.Mount
1546- var err error
1547- var envFile , image , bundleMountsDir , overlayDir , intermediateMount string
1548- var agent * sshagent.AgentServer
1549- var tl * lockfile.LockFile
1552+ var bundleMountsDir string
15501553
15511554 tokens := strings .Split (mount , "," )
15521555
@@ -1564,18 +1567,21 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
15641567 }
15651568 switch mountType {
15661569 case "secret" :
1567- mountSpec , envFile , err = b .getSecretMount (tokens , sources .Secrets , idMaps , sources .WorkDir )
1570+ mountOrEnvSpec , err : = b .getSecretMount (tokens , sources .Secrets , idMaps , sources .WorkDir )
15681571 if err != nil {
15691572 return nil , nil , err
15701573 }
1571- if mountSpec != nil {
1572- finalMounts = append (finalMounts , * mountSpec )
1573- if envFile != "" {
1574- tmpFiles = append (tmpFiles , envFile )
1575- }
1574+ if mountOrEnvSpec .Mount != nil {
1575+ finalMounts = append (finalMounts , * mountOrEnvSpec .Mount )
1576+ }
1577+ if mountOrEnvSpec .EnvFile != "" {
1578+ tmpFiles = append (tmpFiles , mountOrEnvSpec .EnvFile )
1579+ }
1580+ if mountOrEnvSpec .EnvVariable != "" {
1581+ secretEnvVars = append (secretEnvVars , mountOrEnvSpec .EnvVariable )
15761582 }
15771583 case "ssh" :
1578- mountSpec , agent , err = b .getSSHMount (tokens , len (agents ), sources .SSHSources , idMaps )
1584+ mountSpec , agent , err : = b .getSSHMount (tokens , len (agents ), sources .SSHSources , idMaps )
15791585 if err != nil {
15801586 return nil , nil , err
15811587 }
@@ -1588,11 +1594,12 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
15881594 }
15891595 case define .TypeBind :
15901596 if bundleMountsDir == "" {
1597+ var err error
15911598 if bundleMountsDir , err = os .MkdirTemp (bundlePath , "mounts" ); err != nil {
15921599 return nil , nil , err
15931600 }
15941601 }
1595- mountSpec , image , intermediateMount , overlayDir , err = b .getBindMount (tokens , sources .SystemContext , sources .ContextDir , sources .StageMountPoints , idMaps , sources .WorkDir , bundleMountsDir )
1602+ mountSpec , image , intermediateMount , overlayDir , err : = b .getBindMount (tokens , sources .SystemContext , sources .ContextDir , sources .StageMountPoints , idMaps , sources .WorkDir , bundleMountsDir )
15961603 if err != nil {
15971604 return nil , nil , err
15981605 }
@@ -1607,18 +1614,19 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
16071614 }
16081615 finalMounts = append (finalMounts , * mountSpec )
16091616 case "tmpfs" :
1610- mountSpec , err = b .getTmpfsMount (tokens , idMaps , sources .WorkDir )
1617+ mountSpec , err : = b .getTmpfsMount (tokens , idMaps , sources .WorkDir )
16111618 if err != nil {
16121619 return nil , nil , err
16131620 }
16141621 finalMounts = append (finalMounts , * mountSpec )
16151622 case "cache" :
16161623 if bundleMountsDir == "" {
1624+ var err error
16171625 if bundleMountsDir , err = os .MkdirTemp (bundlePath , "mounts" ); err != nil {
16181626 return nil , nil , err
16191627 }
16201628 }
1621- mountSpec , image , intermediateMount , overlayDir , tl , err = b .getCacheMount (tokens , sources .SystemContext , sources .StageMountPoints , idMaps , sources .WorkDir , bundleMountsDir )
1629+ mountSpec , image , intermediateMount , overlayDir , tl , err : = b .getCacheMount (tokens , sources .SystemContext , sources .StageMountPoints , idMaps , sources .WorkDir , bundleMountsDir )
16221630 if err != nil {
16231631 return nil , nil , err
16241632 }
@@ -1647,6 +1655,7 @@ func (b *Builder) runSetupRunMounts(bundlePath string, mounts []string, sources
16471655 SSHAuthSock : defaultSSHSock ,
16481656 TargetLocks : targetLocks ,
16491657 IntermediateMounts : intermediateMounts ,
1658+ SecretEnvVars : secretEnvVars ,
16501659 }
16511660 return finalMounts , artifacts , nil
16521661}
@@ -1712,13 +1721,17 @@ func (b *Builder) getTmpfsMount(tokens []string, idMaps IDMaps, workDir string)
17121721 return & volumes [0 ], nil
17131722}
17141723
1715- func (b * Builder ) getSecretMount (tokens []string , secrets map [string ]define.Secret , idMaps IDMaps , workdir string ) (_ * specs.Mount , _ string , retErr error ) {
1716- errInvalidSyntax := errors .New ("secret should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint" )
1724+ func (b * Builder ) getSecretMount (tokens []string , secrets map [string ]define.Secret , idMaps IDMaps , workdir string ) (rv struct {
1725+ Mount * specs.Mount // set if mount created
1726+ EnvFile string // set if caller mount created from temp created env file
1727+ EnvVariable string // set if caller should add to env variable list
1728+ }, retErr error ,
1729+ ) {
1730+ errInvalidSyntax := errors .New ("secret should have syntax id=id[,target=path,required=bool,mode=uint,uid=uint,gid=uint,env=dstVarName" )
17171731 if len (tokens ) == 0 {
1718- return nil , "" , errInvalidSyntax
1732+ return rv , errInvalidSyntax
17191733 }
1720- var err error
1721- var id , target string
1734+ var id , target , env string
17221735 var required bool
17231736 var uid , gid uint32
17241737 var mode uint32 = 0o400
@@ -1738,110 +1751,123 @@ func (b *Builder) getSecretMount(tokens []string, secrets map[string]define.Secr
17381751 case "required" :
17391752 required = true
17401753 if len (kv ) > 1 {
1754+ var err error
17411755 required , err = strconv .ParseBool (kv [1 ])
17421756 if err != nil {
1743- return nil , "" , errInvalidSyntax
1757+ return rv , errInvalidSyntax
17441758 }
17451759 }
17461760 case "mode" :
17471761 mode64 , err := strconv .ParseUint (kv [1 ], 8 , 32 )
17481762 if err != nil {
1749- return nil , "" , errInvalidSyntax
1763+ return rv , errInvalidSyntax
17501764 }
17511765 mode = uint32 (mode64 )
17521766 case "uid" :
17531767 uid64 , err := strconv .ParseUint (kv [1 ], 10 , 32 )
17541768 if err != nil {
1755- return nil , "" , errInvalidSyntax
1769+ return rv , errInvalidSyntax
17561770 }
17571771 uid = uint32 (uid64 )
17581772 case "gid" :
17591773 gid64 , err := strconv .ParseUint (kv [1 ], 10 , 32 )
17601774 if err != nil {
1761- return nil , "" , errInvalidSyntax
1775+ return rv , errInvalidSyntax
17621776 }
17631777 gid = uint32 (gid64 )
1778+ case "env" :
1779+ if kv [1 ] == "" {
1780+ return rv , errInvalidSyntax
1781+ }
1782+ env = kv [1 ]
17641783 default :
1765- return nil , "" , errInvalidSyntax
1784+ return rv , errInvalidSyntax
17661785 }
17671786 }
17681787
17691788 if id == "" {
1770- return nil , "" , errInvalidSyntax
1771- }
1772- // Default location for secrets is /run/secrets/id
1773- if target == "" {
1774- target = "/run/secrets/" + id
1789+ return rv , errInvalidSyntax
17751790 }
17761791
1792+ // first fetch the secret data
17771793 secr , ok := secrets [id ]
17781794 if ! ok {
17791795 if required {
1780- return nil , "" , fmt .Errorf ("secret required but no secret with id %q found" , id )
1796+ return rv , fmt .Errorf ("secret required but no secret with id %q found" , id )
17811797 }
1782- return nil , "" , nil
1798+ return rv , nil
1799+ }
1800+ data , err := secr .ResolveValue ()
1801+ if err != nil {
1802+ return rv , err
1803+ }
1804+
1805+ // if env is set, then we can return now
1806+ if env != "" {
1807+ rv .EnvVariable = env + "=" + string (data )
1808+ return rv , nil
1809+ }
1810+ // else we fallback to default behaviour of creating mount
1811+
1812+ // Default location for secrets is /run/secrets/id
1813+ if target == "" {
1814+ target = "/run/secrets/" + id
17831815 }
1784- var data []byte
1785- var envFile string
1816+
17861817 var ctrFileOnHost string
17871818
17881819 switch secr .SourceType {
17891820 case "env" :
1790- data = []byte (os .Getenv (secr .Source ))
17911821 tmpFile , err := os .CreateTemp (tmpdir .GetTempDir (), "buildah*" )
17921822 if err != nil {
1793- return nil , "" , err
1823+ return rv , err
17941824 }
17951825 defer func () {
17961826 if retErr != nil {
17971827 os .Remove (tmpFile .Name ())
17981828 }
17991829 }()
1800- envFile = tmpFile .Name ()
1830+ rv . EnvFile = tmpFile .Name ()
18011831 ctrFileOnHost = tmpFile .Name ()
18021832 case "file" :
18031833 containerWorkingDir , err := b .store .ContainerDirectory (b .ContainerID )
18041834 if err != nil {
1805- return nil , "" , err
1806- }
1807- data , err = os .ReadFile (secr .Source )
1808- if err != nil {
1809- return nil , "" , err
1835+ return rv , err
18101836 }
18111837 ctrFileOnHost = filepath .Join (containerWorkingDir , "secrets" , digest .FromString (id ).Encoded ()[:16 ])
18121838 default :
1813- return nil , "" , errors .New ("invalid source secret type" )
1839+ return rv , errors .New ("invalid source secret type" )
18141840 }
18151841
18161842 // Copy secrets to container working dir (or tmp dir if it's an env), since we need to chmod,
18171843 // chown and relabel it for the container user and we don't want to mess with the original file
18181844 if err := os .MkdirAll (filepath .Dir (ctrFileOnHost ), 0o755 ); err != nil {
1819- return nil , "" , err
1845+ return rv , err
18201846 }
18211847 if err := os .WriteFile (ctrFileOnHost , data , 0o644 ); err != nil {
1822- return nil , "" , err
1848+ return rv , err
18231849 }
18241850
18251851 if err := relabel (ctrFileOnHost , b .MountLabel , false ); err != nil {
1826- return nil , "" , err
1852+ return rv , err
18271853 }
18281854 hostUID , hostGID , err := util .GetHostIDs (idMaps .uidmap , idMaps .gidmap , uid , gid )
18291855 if err != nil {
1830- return nil , "" , err
1856+ return rv , err
18311857 }
18321858 if err := os .Lchown (ctrFileOnHost , int (hostUID ), int (hostGID )); err != nil {
1833- return nil , "" , err
1859+ return rv , err
18341860 }
18351861 if err := os .Chmod (ctrFileOnHost , os .FileMode (mode )); err != nil {
1836- return nil , "" , err
1862+ return rv , err
18371863 }
1838- newMount := specs.Mount {
1864+ rv . Mount = & specs.Mount {
18391865 Destination : target ,
18401866 Type : define .TypeBind ,
18411867 Source : ctrFileOnHost ,
18421868 Options : append (define .BindOptions , "rprivate" , "ro" ),
18431869 }
1844- return & newMount , envFile , nil
1870+ return rv , nil
18451871}
18461872
18471873// getSSHMount parses the --mount type=ssh flag in the Containerfile, checks if there's an ssh source provided, and creates and starts an ssh-agent to be forwarded into the container
0 commit comments