Merge pull request #22288 from ashley-cui/machmounttag

Fix machine volumes with long path
This commit is contained in:
openshift-merge-bot[bot]
2024-04-30 16:36:53 +00:00
committed by GitHub
5 changed files with 40 additions and 23 deletions

View File

@ -96,19 +96,19 @@ func GenerateSystemDFilesForVirtiofsMounts(mounts []machine.VirtIoFs) ([]ignitio
virtiofsAutomount := ignition.Unit{ virtiofsAutomount := ignition.Unit{
Enabled: ignition.BoolToPtr(true), Enabled: ignition.BoolToPtr(true),
Name: fmt.Sprintf("%s.automount", mnt.Tag), Name: fmt.Sprintf("%s.automount", parser.PathEscape(mnt.Target)),
Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnitFile, mnt.Target, mnt.Target)), Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnitFile, mnt.Tag, mnt.Target)),
} }
virtiofsMount := ignition.Unit{ virtiofsMount := ignition.Unit{
Enabled: ignition.BoolToPtr(true), 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)), Contents: ignition.StrToPtr(fmt.Sprintf(mountUnitFile, mnt.Tag, mnt.Target)),
} }
// This "unit" simulates something like systemctl enable virtiofs-mount-prepare@ // This "unit" simulates something like systemctl enable virtiofs-mount-prepare@
enablePrep := ignition.Unit{ enablePrep := ignition.Unit{
Enabled: ignition.BoolToPtr(true), 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) unitFiles = append(unitFiles, virtiofsAutomount, virtiofsMount, enablePrep)

View File

@ -207,7 +207,8 @@ var _ = Describe("podman machine init", func() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
_, err = os.CreateTemp(tmpDir, "example") _, err = os.CreateTemp(tmpDir, "example")
Expect(err).ToNot(HaveOccurred()) 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) }() defer func() { _ = utils.GuardedRemoveAll(tmpDir) }()
name := randomString() name := randomString()
@ -217,7 +218,7 @@ var _ = Describe("podman machine init", func() {
Expect(session).To(Exit(0)) Expect(session).To(Exit(0))
ssh := sshMachine{} 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(err).ToNot(HaveOccurred())
Expect(sshSession).To(Exit(0)) Expect(sshSession).To(Exit(0))
Expect(sshSession.outputToString()).To(ContainSubstring("example")) Expect(sshSession.outputToString()).To(ContainSubstring("example"))

View File

@ -1,7 +1,8 @@
package machine package machine
import ( import (
"strings" "crypto/sha256"
"encoding/hex"
"github.com/containers/podman/v5/pkg/machine/vmconfigs" "github.com/containers/podman/v5/pkg/machine/vmconfigs"
) )
@ -29,14 +30,13 @@ func (v VirtIoFs) Kind() string {
return string(VirtIOFsVk) return string(VirtIOFsVk)
} }
// unitName is the fq path where /'s are replaced with -'s // generateTag generates a tag for VirtIOFs mounts.
func (v VirtIoFs) unitName() string { // AppleHV requires tags to be 36 bytes or fewer.
// delete the leading - // SHA256 the path, then truncate to 36 bytes
unit := strings.ReplaceAll(v.Target, "/", "-") func (v VirtIoFs) generateTag() string {
if strings.HasPrefix(unit, "-") { sum := sha256.Sum256([]byte(v.Target))
return unit[1:] stringSum := hex.EncodeToString(sum[:])
} return stringSum[:36]
return unit
} }
func (v VirtIoFs) ToMount() vmconfigs.Mount { func (v VirtIoFs) ToMount() vmconfigs.Mount {
@ -58,7 +58,7 @@ func NewVirtIoFsMount(src, target string, readOnly bool) VirtIoFs {
Source: src, Source: src,
Target: target, Target: target,
} }
vfs.Tag = vfs.unitName() vfs.Tag = vfs.generateTag()
return vfs return vfs
} }

View File

@ -428,13 +428,17 @@ func splitString(s string, separators string, flags SplitFlags) ([]string, error
return splitStringAppend(make([]string, 0), s, separators, flags) return splitStringAppend(make([]string, 0), s, separators, flags)
} }
func charNeedEscape(c rune) bool { func charNeedEscape(c rune, isPath bool) bool {
if c > 128 { if c > 128 {
return false /* unicode is ok */ return false /* unicode is ok */
} }
pathRune := (isPath && c == '-') ||
(isPath && c == '/')
return unicode.IsSpace(c) || return unicode.IsSpace(c) ||
unicode.IsControl(c) || unicode.IsControl(c) ||
pathRune ||
c == '"' || c == '"' ||
c == '\'' || c == '\'' ||
c == '\\' c == '\\'
@ -442,18 +446,22 @@ func charNeedEscape(c rune) bool {
func wordNeedEscape(word string) bool { func wordNeedEscape(word string) bool {
for _, c := range word { for _, c := range word {
if charNeedEscape(c) { if charNeedEscape(c, false) {
return true return true
} }
} }
return false return false
} }
func appendEscapeWord(escaped *strings.Builder, word string) { func appendEscapeWord(escaped *strings.Builder, word string) {
escaped.WriteRune('"') escaped.WriteRune('"')
for _, c := range word { escapeString(escaped, word, false)
if charNeedEscape(c) { escaped.WriteRune('"')
}
func escapeString(escaped *strings.Builder, word string, isPath bool) {
for i, c := range word {
if charNeedEscape(c, isPath) {
switch c { switch c {
case '\a': case '\a':
escaped.WriteString("\\a") escaped.WriteString("\\a")
@ -477,6 +485,10 @@ func appendEscapeWord(escaped *strings.Builder, word string) {
escaped.WriteString("\\\"") escaped.WriteString("\\\"")
case '\'': case '\'':
escaped.WriteString("'") escaped.WriteString("'")
case '/':
if isPath && i != 0 {
escaped.WriteString("-")
}
default: default:
escaped.WriteString(fmt.Sprintf("\\x%.2x", c)) escaped.WriteString(fmt.Sprintf("\\x%.2x", c))
} }
@ -484,7 +496,6 @@ func appendEscapeWord(escaped *strings.Builder, word string) {
escaped.WriteRune(c) escaped.WriteRune(c)
} }
} }
escaped.WriteRune('"')
} }
func escapeWords(words []string) string { func escapeWords(words []string) string {
@ -500,6 +511,5 @@ func escapeWords(words []string) string {
escaped.WriteString(word) escaped.WriteString(word)
} }
} }
return escaped.String() return escaped.String()
} }

View File

@ -932,3 +932,9 @@ func (f *UnitFile) GetTemplateParts() (string, string) {
} }
return parts[0] + "@" + ext, parts[1] return parts[0] + "@" + ext, parts[1]
} }
func PathEscape(path string) string {
var escaped strings.Builder
escapeString(&escaped, path, true)
return escaped.String()
}