mirror of
https://github.com/containers/podman.git
synced 2025-06-30 07:26:39 +08:00
Merge pull request #22288 from ashley-cui/machmounttag
Fix machine volumes with long path
This commit is contained in:
@ -96,19 +96,19 @@ func GenerateSystemDFilesForVirtiofsMounts(mounts []machine.VirtIoFs) ([]ignitio
|
||||
|
||||
virtiofsAutomount := ignition.Unit{
|
||||
Enabled: ignition.BoolToPtr(true),
|
||||
Name: fmt.Sprintf("%s.automount", mnt.Tag),
|
||||
Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnitFile, mnt.Target, mnt.Target)),
|
||||
Name: fmt.Sprintf("%s.automount", parser.PathEscape(mnt.Target)),
|
||||
Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnitFile, mnt.Tag, mnt.Target)),
|
||||
}
|
||||
virtiofsMount := ignition.Unit{
|
||||
Enabled: ignition.BoolToPtr(true),
|
||||
Name: fmt.Sprintf("%s.mount", mnt.Tag),
|
||||
Name: fmt.Sprintf("%s.mount", parser.PathEscape(mnt.Target)),
|
||||
Contents: ignition.StrToPtr(fmt.Sprintf(mountUnitFile, mnt.Tag, mnt.Target)),
|
||||
}
|
||||
|
||||
// This "unit" simulates something like systemctl enable virtiofs-mount-prepare@
|
||||
enablePrep := ignition.Unit{
|
||||
Enabled: ignition.BoolToPtr(true),
|
||||
Name: fmt.Sprintf("virtiofs-mount-prepare@%s.service", mnt.Tag),
|
||||
Name: fmt.Sprintf("virtiofs-mount-prepare@%s.service", parser.PathEscape(mnt.Target)),
|
||||
}
|
||||
|
||||
unitFiles = append(unitFiles, virtiofsAutomount, virtiofsMount, enablePrep)
|
||||
|
@ -207,7 +207,8 @@ var _ = Describe("podman machine init", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = os.CreateTemp(tmpDir, "example")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
mount := tmpDir + ":/testmountdir"
|
||||
// Test long target path, see https://github.com/containers/podman/issues/22226
|
||||
mount := tmpDir + ":/very-long-test-mount-dir-path-more-than-thirty-six-bytes"
|
||||
defer func() { _ = utils.GuardedRemoveAll(tmpDir) }()
|
||||
|
||||
name := randomString()
|
||||
@ -217,7 +218,7 @@ var _ = Describe("podman machine init", func() {
|
||||
Expect(session).To(Exit(0))
|
||||
|
||||
ssh := sshMachine{}
|
||||
sshSession, err := mb.setName(name).setCmd(ssh.withSSHCommand([]string{"ls /testmountdir"})).run()
|
||||
sshSession, err := mb.setName(name).setCmd(ssh.withSSHCommand([]string{"ls /very-long-test-mount-dir-path-more-than-thirty-six-bytes"})).run()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(sshSession).To(Exit(0))
|
||||
Expect(sshSession.outputToString()).To(ContainSubstring("example"))
|
||||
|
@ -1,7 +1,8 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||
)
|
||||
@ -29,14 +30,13 @@ func (v VirtIoFs) Kind() string {
|
||||
return string(VirtIOFsVk)
|
||||
}
|
||||
|
||||
// unitName is the fq path where /'s are replaced with -'s
|
||||
func (v VirtIoFs) unitName() string {
|
||||
// delete the leading -
|
||||
unit := strings.ReplaceAll(v.Target, "/", "-")
|
||||
if strings.HasPrefix(unit, "-") {
|
||||
return unit[1:]
|
||||
}
|
||||
return unit
|
||||
// generateTag generates a tag for VirtIOFs mounts.
|
||||
// AppleHV requires tags to be 36 bytes or fewer.
|
||||
// SHA256 the path, then truncate to 36 bytes
|
||||
func (v VirtIoFs) generateTag() string {
|
||||
sum := sha256.Sum256([]byte(v.Target))
|
||||
stringSum := hex.EncodeToString(sum[:])
|
||||
return stringSum[:36]
|
||||
}
|
||||
|
||||
func (v VirtIoFs) ToMount() vmconfigs.Mount {
|
||||
@ -58,7 +58,7 @@ func NewVirtIoFsMount(src, target string, readOnly bool) VirtIoFs {
|
||||
Source: src,
|
||||
Target: target,
|
||||
}
|
||||
vfs.Tag = vfs.unitName()
|
||||
vfs.Tag = vfs.generateTag()
|
||||
return vfs
|
||||
}
|
||||
|
||||
|
@ -428,13 +428,17 @@ func splitString(s string, separators string, flags SplitFlags) ([]string, error
|
||||
return splitStringAppend(make([]string, 0), s, separators, flags)
|
||||
}
|
||||
|
||||
func charNeedEscape(c rune) bool {
|
||||
func charNeedEscape(c rune, isPath bool) bool {
|
||||
if c > 128 {
|
||||
return false /* unicode is ok */
|
||||
}
|
||||
|
||||
pathRune := (isPath && c == '-') ||
|
||||
(isPath && c == '/')
|
||||
|
||||
return unicode.IsSpace(c) ||
|
||||
unicode.IsControl(c) ||
|
||||
pathRune ||
|
||||
c == '"' ||
|
||||
c == '\'' ||
|
||||
c == '\\'
|
||||
@ -442,18 +446,22 @@ func charNeedEscape(c rune) bool {
|
||||
|
||||
func wordNeedEscape(word string) bool {
|
||||
for _, c := range word {
|
||||
if charNeedEscape(c) {
|
||||
if charNeedEscape(c, false) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func appendEscapeWord(escaped *strings.Builder, word string) {
|
||||
escaped.WriteRune('"')
|
||||
for _, c := range word {
|
||||
if charNeedEscape(c) {
|
||||
escapeString(escaped, word, false)
|
||||
escaped.WriteRune('"')
|
||||
}
|
||||
|
||||
func escapeString(escaped *strings.Builder, word string, isPath bool) {
|
||||
for i, c := range word {
|
||||
if charNeedEscape(c, isPath) {
|
||||
switch c {
|
||||
case '\a':
|
||||
escaped.WriteString("\\a")
|
||||
@ -477,6 +485,10 @@ func appendEscapeWord(escaped *strings.Builder, word string) {
|
||||
escaped.WriteString("\\\"")
|
||||
case '\'':
|
||||
escaped.WriteString("'")
|
||||
case '/':
|
||||
if isPath && i != 0 {
|
||||
escaped.WriteString("-")
|
||||
}
|
||||
default:
|
||||
escaped.WriteString(fmt.Sprintf("\\x%.2x", c))
|
||||
}
|
||||
@ -484,7 +496,6 @@ func appendEscapeWord(escaped *strings.Builder, word string) {
|
||||
escaped.WriteRune(c)
|
||||
}
|
||||
}
|
||||
escaped.WriteRune('"')
|
||||
}
|
||||
|
||||
func escapeWords(words []string) string {
|
||||
@ -500,6 +511,5 @@ func escapeWords(words []string) string {
|
||||
escaped.WriteString(word)
|
||||
}
|
||||
}
|
||||
|
||||
return escaped.String()
|
||||
}
|
||||
|
@ -932,3 +932,9 @@ func (f *UnitFile) GetTemplateParts() (string, string) {
|
||||
}
|
||||
return parts[0] + "@" + ext, parts[1]
|
||||
}
|
||||
|
||||
func PathEscape(path string) string {
|
||||
var escaped strings.Builder
|
||||
escapeString(&escaped, path, true)
|
||||
return escaped.String()
|
||||
}
|
||||
|
Reference in New Issue
Block a user