Repository: lima-vm/lima
Pull request #2630 (2024-09-18 15:03:52)

Update selinux label for rosetta from nfs_t to bin_t
With recent integration with systemd-binfmt,the existing nfs_t selinux label for Rosetta is causing issues while registering it. This behaviour needs to be fixed by setting the label as bin_t.

Fixes: https://github.com/lima-vm/lima/issues/2627


hasan4791: Wondering whats causing the test failure!!!
Locally this works but not in CI 

Patch:
diff --git a/cmd/limactl/copy.go b/cmd/limactl/copy.go
index cbee6d21..3d4ec4a7 100644
--- a/cmd/limactl/copy.go
+++ b/cmd/limactl/copy.go
@@ -65,7 +65,10 @@ func copyAction(cmd *cobra.Command, args []string) error {
 	if recursive {
 		scpFlags = append(scpFlags, "-r")
 	}
-	legacySSH := sshutil.DetectOpenSSHVersion().LessThan(*semver.New("8.0.0"))
+	legacySSH := false
+	if sshutil.DetectOpenSSHVersion().LessThan(*semver.New("8.0.0")) {
+		legacySSH = true
+	}
 	for _, arg := range args {
 		path := strings.Split(arg, ":")
 		switch len(path) {
diff --git a/examples/buildkit.yaml b/examples/buildkit.yaml
index 125c33be..6d27c80a 100644
--- a/examples/buildkit.yaml
+++ b/examples/buildkit.yaml
@@ -5,11 +5,11 @@
 # $ export BUILDKIT_HOST=$(limactl list buildkit --format 'unix://{{.Dir}}/sock/buildkitd.sock')
 # $ buildctl debug workers
 message: |
-  To run `buildkit` on the host (assumes buildctl is installed), run the following commands:
-  -------
-  export BUILDKIT_HOST="unix://{{.Dir}}/sock/buildkitd.sock"
-  buildctl debug workers
-  -------
+ To run `buildkit` on the host (assumes buildctl is installed), run the following commands:
+ -------
+ export BUILDKIT_HOST="unix://{{.Dir}}/sock/buildkitd.sock"
+ buildctl debug workers
+ -------
 images:
 # Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
 - location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-amd64.img"
diff --git a/examples/default.yaml b/examples/default.yaml
index d071d889..5b269ff7 100644
--- a/examples/default.yaml
+++ b/examples/default.yaml
@@ -264,10 +264,10 @@ containerd:
 # Setting of instructions is supported like this: "qemu64,+ssse3".
 # 🟢 Builtin default: hard-coded arch map with type (see the output of `limactl info | jq .defaultTemplate.cpuType`)
 cpuType:
-#   aarch64: "cortex-a72" # (or "host" when running on aarch64 host)
-#   armv7l: "cortex-a7" # (or "host" when running on armv7l host)
-#   riscv64: "rv64" # (or "host" when running on riscv64 host)
-#   x86_64: "qemu64" # (or "host,-pdpe1gb" when running on x86_64 host)
+  # aarch64: "cortex-a72" # (or "host" when running on aarch64 host)
+  # armv7l: "cortex-a7" # (or "host" when running on armv7l host)
+  # riscv64: "rv64" # (or "host" when running on riscv64 host)
+  # x86_64: "qemu64" # (or "host,-pdpe1gb" when running on x86_64 host)
 
 rosetta:
   # Enable Rosetta for Linux (EXPERIMENTAL; will graduate from experimental in Lima v1.0).
@@ -456,8 +456,8 @@ hostResolver:
   # predefined to specify the gateway address to the host.
   # 🟢 Builtin default: null
   hosts:
-  #   guest.name: 127.1.1.1
-  #   host.name: host.lima.internal
+    # guest.name: 127.1.1.1
+    # host.name: host.lima.internal
 
 # If hostResolver.enabled is false, then the following rules apply for configuring dns:
 # Explicitly set DNS addresses for qemu user-mode networking. By default qemu picks *one*
diff --git a/go.mod b/go.mod
index a751c787..6096dc5a 100644
--- a/go.mod
+++ b/go.mod
@@ -43,11 +43,12 @@ require (
 	golang.org/x/sync v0.8.0
 	golang.org/x/sys v0.25.0
 	golang.org/x/text v0.18.0
-	google.golang.org/grpc v1.66.2
+	google.golang.org/grpc v1.66.0
 	google.golang.org/protobuf v1.34.2
 	gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
+	gopkg.in/yaml.v3 v3.0.1
 	gotest.tools/v3 v3.5.1
-	inet.af/tcpproxy v0.0.0-20221017015627-91f861402626 // replaced to github.com/inetaf/tcpproxy (see the bottom of this go.mod file)
+	inet.af/tcpproxy v0.0.0-20221017015627-91f861402626
 	k8s.io/api v0.31.0
 	k8s.io/apimachinery v0.31.0
 	k8s.io/client-go v0.31.0
@@ -125,7 +126,6 @@ require (
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gvisor.dev/gvisor v0.0.0-20231023213702-2691a8f9b1cf // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
@@ -134,8 +134,3 @@ require (
 	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
 	sigs.k8s.io/yaml v1.4.0 // indirect
 )
-
-// The inet.af domain was lost: https://github.com/inetaf/tcpproxy/issues/39
-// We can't just `require` github.com/inetaf/tcpproxy, as gvisor-tap-vsock
-// still imports inet.af/tcpproxy: https://github.com/containers/gvisor-tap-vsock/pull/399
-replace inet.af/tcpproxy => github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c
diff --git a/go.sum b/go.sum
index c69383d7..02472d8b 100644
--- a/go.sum
+++ b/go.sum
@@ -137,8 +137,6 @@ github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
 github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c h1:gYfYE403/nlrGNYj6BEOs9ucLCAGB9gstlSk92DttTg=
-github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c/go.mod h1:Di7LXRyUcnvAcLicFhtM9/MlZl/TNgRSDHORM2c6CMI=
 github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9 h1:LZJWucZz7ztCqY6Jsu7N9g124iJ2kt/O62j3+UchZFg=
 github.com/insomniacslk/dhcp v0.0.0-20240710054256-ddd8a41251c9/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic=
 github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
@@ -410,8 +408,8 @@ golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3j
 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
-google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
-google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
+google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
 google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
 google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -437,6 +435,8 @@ gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
 gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
 gvisor.dev/gvisor v0.0.0-20231023213702-2691a8f9b1cf h1:0A28IFBR6VcMacM0m6Rn5/nr8pk8xa2TyIkjSaFAOPc=
 gvisor.dev/gvisor v0.0.0-20231023213702-2691a8f9b1cf/go.mod h1:8hmigyCdYtw5xJGfQDJzSH5Ju8XEIDBnpyi8+O6GRt8=
+inet.af/tcpproxy v0.0.0-20221017015627-91f861402626 h1:2dMP3Ox/Wh5BiItwOt4jxRsfzkgyBrHzx2nW28Yg6nc=
+inet.af/tcpproxy v0.0.0-20221017015627-91f861402626/go.mod h1:Tojt5kmHpDIR2jMojxzZK2w2ZR7OILODmUo2gaSwjrk=
 k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
 k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
 k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
diff --git a/hack/inject-cmdline-to-template.sh b/hack/inject-cmdline-to-template.sh
index 04431e7d..0ff941d6 100755
--- a/hack/inject-cmdline-to-template.sh
+++ b/hack/inject-cmdline-to-template.sh
@@ -36,17 +36,12 @@ readonly yq_filter="
 parsed=$(yq eval "${yq_filter}" "${template}")
 
 # 3. get the image location
-function check_location() {
-	local location=$1 http_code
-	http_code=$(curl -sIL -w "%{http_code}" "${location}" -o /dev/null)
-	[[ ${http_code} -eq 200 ]]
-}
 while IFS= read -r line; do arr+=("${line}"); done <<<"${parsed}"
 readonly locations=("${arr[@]}")
 for ((i = 0; i < ${#locations[@]}; i++)); do
 	[[ ${locations[i]} != "null" ]] || continue
-	# shellcheck disable=SC2310
-	if check_location "${locations[i]}"; then
+	http_code=$(curl -sIL -w "%{http_code}" "${locations[i]}" -o /dev/null)
+	if [[ ${http_code} -eq 200 ]]; then
 		location=${locations[i]}
 		index=${i}
 		break
@@ -83,18 +78,14 @@ initrd_digest=$(awk "/${initrd_basename}/{print \"sha256:\"\$1}" <<<"${sha256sum
 initrd_location="${location_dirname}/${initrd_basename}"
 
 # 6. inject the kernel and initrd location, digest, and cmdline to the template
-function inject_to() {
-	# shellcheck disable=SC2034
-	local template=$1 arch=$2 index=$3 key=$4 location=$5 digest=$6 cmdline=${7:-} fields=() IFS=,
-	# shellcheck disable=SC2310
-	check_location "${location}" || return 0
-	for field_name in location digest cmdline; do
-		[[ -z ${!field_name} ]] || fields+=("\"${field_name}\": \"${!field_name}\"")
-	done
-	yq -i -I 2 eval "setpath([(.images[] | select(.arch == \"${arch}\") | path)].[${index}] + \"${key}\"; { ${fields[*]}})" "${template}"
-}
-inject_to "${template}" "${arch}" "${index}" "kernel" "${kernel_location}" "${kernel_digest}" "${cmdline}"
-inject_to "${template}" "${arch}" "${index}" "initrd" "${initrd_location}" "${initrd_digest}"
+yq -i eval "
+    [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"kernel\" as \$path|
+    setpath(\$path; { \"location\": \"${kernel_location}\", \"digest\": \"${kernel_digest}\", \"cmdline\": \"${cmdline}\" })
+" "${template}"
+yq -i eval "
+    [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"initrd\" as \$path|
+    setpath(\$path ; { \"location\": \"${initrd_location}\", \"digest\": \"${initrd_digest}\" })
+" "${template}"
 
 # 7. output kernel_location, kernel_digest, cmdline, initrd_location, initrd_digest
 readonly outputs=(kernel_location kernel_digest cmdline initrd_location initrd_digest)
diff --git a/pkg/cidata/cidata.TEMPLATE.d/boot/05-lima-mounts.sh b/pkg/cidata/cidata.TEMPLATE.d/boot/05-lima-mounts.sh
index a18db95e..47298c75 100755
--- a/pkg/cidata/cidata.TEMPLATE.d/boot/05-lima-mounts.sh
+++ b/pkg/cidata/cidata.TEMPLATE.d/boot/05-lima-mounts.sh
@@ -10,9 +10,13 @@ fi
 # Update fstab entries and unmount/remount the volumes with secontext options
 # when selinux is enabled in kernel
 if [ -d /sys/fs/selinux ]; then
+	LABEL_BIN="system_u:object_r:bin_t:s0"
+	LABEL_NFS="system_u:object_r:nfs_t:s0"
 	# shellcheck disable=SC2013
 	for line in $(grep -n virtiofs </etc/fstab | cut -d':' -f1); do
 		OPTIONS=$(awk -v line="$line" 'NR==line {print $4}' /etc/fstab)
+		TAG=$(awk -v line="$line" 'NR==line {print $1}' /etc/fstab)
+		MOUNT_OPTIONS=$(mount | grep "${TAG}" | awk '{print $6}')
 		if [[ ${OPTIONS} != *"context"* ]]; then
 			##########################################################################################
 			## When using vz & virtiofs, initially container_file_t selinux label
@@ -22,13 +26,33 @@ if [ -d /sys/fs/selinux ]; then
 			## so keeping the label as nfs_t fits right. Package container-selinux by
 			## default adds rules for nfs_t context which allows container workloads to work as well.
 			## https://github.com/lima-vm/lima/pull/1965
+			##
+			## With integration[https://github.com/lima-vm/lima/pull/2474] with systemd-binfmt,
+			## the existing "nfs_t" selinux label for Rosetta is causing issues while registering it.
+			## This behaviour needs to be fixed by setting the label as "bin_t"
+			## https://github.com/lima-vm/lima/pull/2630
 			##########################################################################################
-			sed -i -e "$line""s/comment=cloudconfig/comment=cloudconfig,context=\"system_u:object_r:nfs_t:s0\"/g" /etc/fstab
-			TAG=$(awk -v line="$line" 'NR==line {print $1}' /etc/fstab)
-			MOUNT_POINT=$(awk -v line="$line" 'NR==line {print $2}' /etc/fstab)
-			OPTIONS=$(awk -v line="$line" 'NR==line {print $4}' /etc/fstab)
-			umount "${TAG}"
-			mount -t virtiofs "${TAG}" "${MOUNT_POINT}" -o "${OPTIONS}"
+			if [[ ${TAG} == *"rosetta"* ]]; then
+				label=${LABEL_BIN}
+			else
+				label=${LABEL_NFS}
+			fi
+			sed -i -e "$line""s/comment=cloudconfig/comment=cloudconfig,context=\"$label\"/g" /etc/fstab
+			if [[ ${MOUNT_OPTIONS} != *"$label"* ]]; then
+				MOUNT_POINT=$(awk -v line="$line" 'NR==line {print $2}' /etc/fstab)
+				OPTIONS=$(awk -v line="$line" 'NR==line {print $4}' /etc/fstab)
+
+				#########################################################
+				## We need to migrate existing users of Fedora having
+				## Rosetta mounted from nfs_t to bin_t by unregistering
+				## it from binfmt before remounting
+				#########################################################
+				if [[ ${TAG} == *"rosetta"* && ${MOUNT_OPTIONS} == *"${LABEL_NFS}"* ]]; then
+					[ ! -f "/proc/sys/fs/binfmt_misc/rosetta" ] || echo -1 >/proc/sys/fs/binfmt_misc/rosetta
+				fi
+				umount "${TAG}"
+				mount -t virtiofs "${TAG}" "${MOUNT_POINT}" -o "${OPTIONS}"
+			fi
 		fi
 	done
 fi
diff --git a/pkg/downloader/downloader.go b/pkg/downloader/downloader.go
index a03fea0d..bccb1670 100644
--- a/pkg/downloader/downloader.go
+++ b/pkg/downloader/downloader.go
@@ -229,7 +229,6 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
 	}
 	if _, err := os.Stat(shadData); err == nil {
 		logrus.Debugf("file %q is cached as %q", localPath, shadData)
-		useCache := true
 		if _, err := os.Stat(shadDigest); err == nil {
 			logrus.Debugf("Comparing digest %q with the cached digest file %q, not computing the actual digest of %q",
 				o.expectedDigest, shadDigest, shadData)
@@ -240,27 +239,18 @@ func Download(ctx context.Context, local, remote string, opts ...Opt) (*Result,
 				return nil, err
 			}
 		} else {
-			if match, lmCached, lmRemote, err := matchLastModified(ctx, shadTime, remote); err != nil {
-				logrus.WithError(err).Info("Failed to retrieve last-modified for cached digest-less image; using cached image.")
-			} else if match {
-				if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, o.description, o.expectedDigest); err != nil {
-					return nil, err
-				}
-			} else {
-				logrus.Infof("Re-downloading digest-less image: last-modified mismatch (cached: %q, remote: %q)", lmCached, lmRemote)
-				useCache = false
+			if err := copyLocal(ctx, localPath, shadData, ext, o.decompress, o.description, o.expectedDigest); err != nil {
+				return nil, err
 			}
 		}
-		if useCache {
-			res := &Result{
-				Status:          StatusUsedCache,
-				CachePath:       shadData,
-				LastModified:    readTime(shadTime),
-				ContentType:     readFile(shadType),
-				ValidatedDigest: o.expectedDigest != "",
-			}
-			return res, nil
+		res := &Result{
+			Status:          StatusUsedCache,
+			CachePath:       shadData,
+			LastModified:    readTime(shadTime),
+			ContentType:     readFile(shadType),
+			ValidatedDigest: o.expectedDigest != "",
 		}
+		return res, nil
 	}
 	if err := os.RemoveAll(shad); err != nil {
 		return nil, err
@@ -418,10 +408,6 @@ func copyLocal(ctx context.Context, dst, src, ext string, decompress bool, descr
 		if command != "" {
 			return decompressLocal(ctx, command, dstPath, srcPath, ext, description)
 		}
-		commandByMagic := decompressorByMagic(srcPath)
-		if commandByMagic != "" {
-			return decompressLocal(ctx, commandByMagic, dstPath, srcPath, ext, description)
-		}
 	}
 	// TODO: progress bar for copy
 	return fs.CopyFile(dstPath, srcPath)
@@ -442,34 +428,6 @@ func decompressor(ext string) string {
 	}
 }
 
-func decompressorByMagic(file string) string {
-	f, err := os.Open(file)
-	if err != nil {
-		return ""
-	}
-	defer f.Close()
-	header := make([]byte, 6)
-	if _, err := f.Read(header); err != nil {
-		return ""
-	}
-	if _, err := f.Seek(0, io.SeekStart); err != nil {
-		return ""
-	}
-	if bytes.HasPrefix(header, []byte{0x1f, 0x8b}) {
-		return "gzip"
-	}
-	if bytes.HasPrefix(header, []byte{0x42, 0x5a}) {
-		return "bzip2"
-	}
-	if bytes.HasPrefix(header, []byte{0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00}) {
-		return "xz"
-	}
-	if bytes.HasPrefix(header, []byte{0x28, 0xb5, 0x2f, 0xfd}) {
-		return "zstd"
-	}
-	return ""
-}
-
 func decompressLocal(ctx context.Context, decompressCmd, dst, src, ext, description string) error {
 	logrus.Infof("decompressing %s with %v", ext, decompressCmd)
 
@@ -558,43 +516,6 @@ func validateLocalFileDigest(localPath string, expectedDigest digest.Digest) err
 	return nil
 }
 
-// mathLastModified takes params:
-//   - ctx: context for calling httpclientutil.Head
-//   - lastModifiedPath: path of the cached last-modified time file
-//   - url: URL to fetch the last-modified time
-//
-// returns:
-//   - matched: whether the last-modified time matches
-//   - lmCached: last-modified time string from the lastModifiedPath
-//   - lmRemote: last-modified time string from the URL
-//   - err: error if fetching the last-modified time from the URL fails
-func matchLastModified(ctx context.Context, lastModifiedPath, url string) (matched bool, lmCached, lmRemote string, err error) {
-	lmCached = readFile(lastModifiedPath)
-	if lmCached == "" {
-		return false, "<not cached>", "<not checked>", nil
-	}
-	resp, err := httpclientutil.Head(ctx, http.DefaultClient, url)
-	if err != nil {
-		return false, lmCached, "<failed to fetch remote>", err
-	}
-	defer resp.Body.Close()
-	lmRemote = resp.Header.Get("Last-Modified")
-	if lmRemote == "" {
-		return false, lmCached, "<missing Last-Modified header>", nil
-	}
-	lmCachedTime, errParsingCachedTime := time.Parse(http.TimeFormat, lmCached)
-	lmRemoteTime, errParsingRemoteTime := time.Parse(http.TimeFormat, lmRemote)
-	if errParsingCachedTime != nil && errParsingRemoteTime != nil {
-		// both time strings are failed to parse, so compare them as strings
-		return lmCached == lmRemote, lmCached, lmRemote, nil
-	} else if errParsingCachedTime == nil && errParsingRemoteTime == nil {
-		// both time strings are successfully parsed, so compare them as times
-		return lmRemoteTime.Equal(lmCachedTime), lmCached, lmRemote, nil
-	}
-	// ignore parsing errors for either time string and assume they are different
-	return false, lmCached, lmRemote, nil
-}
-
 func downloadHTTP(ctx context.Context, localPath, lastModified, contentType, url, description string, expectedDigest digest.Digest) error {
 	if localPath == "" {
 		return fmt.Errorf("downloadHTTP: got empty localPath")
diff --git a/pkg/guestagent/iptables/iptables.go b/pkg/guestagent/iptables/iptables.go
index 0f4fe1ad..12416c04 100644
--- a/pkg/guestagent/iptables/iptables.go
+++ b/pkg/guestagent/iptables/iptables.go
@@ -72,7 +72,10 @@ func parsePortsFromRules(rules []string) ([]Entry, error) {
 					return nil, err
 				}
 
-				istcp := found[2] == "tcp"
+				istcp := false
+				if found[2] == "tcp" {
+					istcp = true
+				}
 
 				// When no IP is present the rule applies to all interfaces.
 				ip := found[1]
diff --git a/pkg/hostagent/hostagent.go b/pkg/hostagent/hostagent.go
index 32998b5d..7fc3cbb5 100644
--- a/pkg/hostagent/hostagent.go
+++ b/pkg/hostagent/hostagent.go
@@ -153,22 +153,6 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
 		AdditionalArgs: sshutil.SSHArgsFromOpts(sshOpts),
 	}
 
-	ignoreTCP := false
-	ignoreUDP := false
-	for _, rule := range y.PortForwards {
-		if rule.Ignore && rule.GuestPortRange[0] == 1 && rule.GuestPortRange[1] == 65535 {
-			switch rule.Proto {
-			case limayaml.TCP:
-				ignoreTCP = true
-				logrus.Info("TCP port forwarding is disabled (except for SSH)")
-			case limayaml.UDP:
-				ignoreUDP = true
-				logrus.Info("UDP port forwarding is disabled")
-			}
-		} else {
-			break
-		}
-	}
 	rules := make([]limayaml.PortForward, 0, 3+len(y.PortForwards))
 	// Block ports 22 and sshLocalPort on all IPs
 	for _, port := range []int{sshGuestPort, sshLocalPort} {
@@ -204,8 +188,8 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt
 		instName:          instName,
 		instSSHAddress:    inst.SSHAddress,
 		sshConfig:         sshConfig,
-		portForwarder:     newPortForwarder(sshConfig, sshLocalPort, rules, ignoreTCP, inst.VMType),
-		grpcPortForwarder: portfwd.NewPortForwarder(rules, ignoreTCP, ignoreUDP),
+		portForwarder:     newPortForwarder(sshConfig, sshLocalPort, rules, inst.VMType),
+		grpcPortForwarder: portfwd.NewPortForwarder(rules),
 		driver:            limaDriver,
 		signalCh:          signalCh,
 		eventEnc:          json.NewEncoder(stdout),
diff --git a/pkg/hostagent/port.go b/pkg/hostagent/port.go
index 10b34703..4c39b953 100644
--- a/pkg/hostagent/port.go
+++ b/pkg/hostagent/port.go
@@ -14,7 +14,6 @@ type portForwarder struct {
 	sshConfig   *ssh.SSHConfig
 	sshHostPort int
 	rules       []limayaml.PortForward
-	ignore      bool
 	vmType      limayaml.VMType
 }
 
@@ -22,12 +21,11 @@ const sshGuestPort = 22
 
 var IPv4loopback1 = limayaml.IPv4loopback1
 
-func newPortForwarder(sshConfig *ssh.SSHConfig, sshHostPort int, rules []limayaml.PortForward, ignore bool, vmType limayaml.VMType) *portForwarder {
+func newPortForwarder(sshConfig *ssh.SSHConfig, sshHostPort int, rules []limayaml.PortForward, vmType limayaml.VMType) *portForwarder {
 	return &portForwarder{
 		sshConfig:   sshConfig,
 		sshHostPort: sshHostPort,
 		rules:       rules,
-		ignore:      ignore,
 		vmType:      vmType,
 	}
 }
@@ -96,9 +94,7 @@ func (pf *portForwarder) OnEvent(ctx context.Context, ev *api.Event) {
 		}
 		local, remote := pf.forwardingAddresses(f)
 		if local == "" {
-			if !pf.ignore {
-				logrus.Infof("Not forwarding TCP %s", remote)
-			}
+			logrus.Infof("Not forwarding TCP %s", remote)
 			continue
 		}
 		logrus.Infof("Forwarding TCP from %s to %s", remote, local)
diff --git a/pkg/httpclientutil/httpclientutil.go b/pkg/httpclientutil/httpclientutil.go
index 59854545..819da445 100644
--- a/pkg/httpclientutil/httpclientutil.go
+++ b/pkg/httpclientutil/httpclientutil.go
@@ -32,22 +32,6 @@ func Get(ctx context.Context, c *http.Client, url string) (*http.Response, error
 	return resp, nil
 }
 
-func Head(ctx context.Context, c *http.Client, url string) (*http.Response, error) {
-	req, err := http.NewRequestWithContext(ctx, "HEAD", url, http.NoBody)
-	if err != nil {
-		return nil, err
-	}
-	resp, err := c.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	if err := Successful(resp); err != nil {
-		resp.Body.Close()
-		return nil, err
-	}
-	return resp, nil
-}
-
 func Post(ctx context.Context, c *http.Client, url string, body io.Reader) (*http.Response, error) {
 	req, err := http.NewRequestWithContext(ctx, "POST", url, body)
 	if err != nil {
diff --git a/pkg/instance/start.go b/pkg/instance/start.go
index edd5168b..f3ec3064 100644
--- a/pkg/instance/start.go
+++ b/pkg/instance/start.go
@@ -97,10 +97,11 @@ func Prepare(ctx context.Context, inst *store.Instance) (*Prepared, error) {
 	}
 
 	// Check if the instance has been created (the base disk already exists)
+	created := false
 	baseDisk := filepath.Join(inst.Dir, filenames.BaseDisk)
-	_, err = os.Stat(baseDisk)
-	created := err == nil
-
+	if _, err := os.Stat(baseDisk); err == nil {
+		created = true
+	}
 	if err := limaDriver.CreateDisk(ctx); err != nil {
 		return nil, err
 	}
diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go
index f932e6aa..4b3bc1cd 100644
--- a/pkg/limayaml/limayaml.go
+++ b/pkg/limayaml/limayaml.go
@@ -214,7 +214,6 @@ type Proto = string
 
 const (
 	TCP Proto = "tcp"
-	UDP Proto = "udp"
 )
 
 type PortForward struct {
diff --git a/pkg/limayaml/load.go b/pkg/limayaml/load.go
index 7aeba343..20670eb6 100644
--- a/pkg/limayaml/load.go
+++ b/pkg/limayaml/load.go
@@ -9,8 +9,8 @@ import (
 	"github.com/goccy/go-yaml"
 	"github.com/lima-vm/lima/pkg/store/dirnames"
 	"github.com/lima-vm/lima/pkg/store/filenames"
-	"github.com/lima-vm/lima/pkg/yqutil"
 	"github.com/sirupsen/logrus"
+	yamlv3 "gopkg.in/yaml.v3"
 )
 
 func unmarshalDisk(dst *Disk, b []byte) error {
@@ -22,13 +22,24 @@ func unmarshalDisk(dst *Disk, b []byte) error {
 	return yaml.Unmarshal(b, dst)
 }
 
+func (d *Disk) UnmarshalYAML(value *yamlv3.Node) error {
+	var v interface{}
+	if err := value.Decode(&v); err != nil {
+		return err
+	}
+	if s, ok := v.(string); ok {
+		*d = Disk{Name: s}
+	}
+	return nil
+}
+
 func unmarshalYAML(data []byte, v interface{}, comment string) error {
 	if err := yaml.UnmarshalWithOptions(data, v, yaml.DisallowDuplicateKey(), yaml.CustomUnmarshaler[Disk](unmarshalDisk)); err != nil {
 		return fmt.Errorf("failed to unmarshal YAML (%s): %w", comment, err)
 	}
 	// the go-yaml library doesn't catch all markup errors, unfortunately
 	// make sure to get a "second opinion", using the same library as "yq"
-	if err := yqutil.ValidateContent(data); err != nil {
+	if err := yamlv3.Unmarshal(data, v); err != nil {
 		return fmt.Errorf("failed to unmarshal YAML (%s): %w", comment, err)
 	}
 	if err := yaml.UnmarshalWithOptions(data, v, yaml.Strict(), yaml.CustomUnmarshaler[Disk](unmarshalDisk)); err != nil {
diff --git a/pkg/portfwd/forward.go b/pkg/portfwd/forward.go
index c6bad28e..cf616d8d 100644
--- a/pkg/portfwd/forward.go
+++ b/pkg/portfwd/forward.go
@@ -15,30 +15,18 @@ var IPv4loopback1 = limayaml.IPv4loopback1
 
 type Forwarder struct {
 	rules             []limayaml.PortForward
-	ignoreTCP         bool
-	ignoreUDP         bool
 	closableListeners *ClosableListeners
 }
 
-func NewPortForwarder(rules []limayaml.PortForward, ignoreTCP, ignoreUDP bool) *Forwarder {
-	return &Forwarder{
-		rules:             rules,
-		ignoreTCP:         ignoreTCP,
-		ignoreUDP:         ignoreUDP,
-		closableListeners: NewClosableListener(),
-	}
+func NewPortForwarder(rules []limayaml.PortForward) *Forwarder {
+	return &Forwarder{rules: rules, closableListeners: NewClosableListener()}
 }
 
 func (fw *Forwarder) OnEvent(ctx context.Context, client *guestagentclient.GuestAgentClient, ev *api.Event) {
 	for _, f := range ev.LocalPortsAdded {
 		local, remote := fw.forwardingAddresses(f)
 		if local == "" {
-			if !fw.ignoreTCP && f.Protocol == "tcp" {
-				logrus.Infof("Not forwarding TCP %s", remote)
-			}
-			if !fw.ignoreUDP && f.Protocol == "udp" {
-				logrus.Infof("Not forwarding UDP %s", remote)
-			}
+			logrus.Infof("Not forwarding %s %s", strings.ToUpper(f.Protocol), remote)
 			continue
 		}
 		logrus.Infof("Forwarding %s from %s to %s", strings.ToUpper(f.Protocol), remote, local)
diff --git a/pkg/vz/disk.go b/pkg/vz/disk.go
index f465d6d7..0ee62d38 100644
--- a/pkg/vz/disk.go
+++ b/pkg/vz/disk.go
@@ -23,9 +23,6 @@ func EnsureDisk(ctx context.Context, driver *driver.BaseDriver) error {
 	}
 
 	baseDisk := filepath.Join(driver.Instance.Dir, filenames.BaseDisk)
-	kernel := filepath.Join(driver.Instance.Dir, filenames.Kernel)
-	kernelCmdline := filepath.Join(driver.Instance.Dir, filenames.KernelCmdline)
-	initrd := filepath.Join(driver.Instance.Dir, filenames.Initrd)
 	if _, err := os.Stat(baseDisk); errors.Is(err, os.ErrNotExist) {
 		var ensuredBaseDisk bool
 		errs := make([]error, len(driver.Yaml.Images))
@@ -34,25 +31,6 @@ func EnsureDisk(ctx context.Context, driver *driver.BaseDriver) error {
 				errs[i] = err
 				continue
 			}
-			if f.Kernel != nil {
-				// ensure decompress kernel because vz expects it to be decompressed
-				if _, err := fileutils.DownloadFile(ctx, kernel, f.Kernel.File, true, "the kernel", *driver.Yaml.Arch); err != nil {
-					errs[i] = err
-					continue
-				}
-				if f.Kernel.Cmdline != "" {
-					if err := os.WriteFile(kernelCmdline, []byte(f.Kernel.Cmdline), 0o644); err != nil {
-						errs[i] = err
-						continue
-					}
-				}
-			}
-			if f.Initrd != nil {
-				if _, err := fileutils.DownloadFile(ctx, initrd, *f.Initrd, false, "the initrd", *driver.Yaml.Arch); err != nil {
-					errs[i] = err
-					continue
-				}
-			}
 			ensuredBaseDisk = true
 			break
 		}
diff --git a/pkg/vz/network_darwin.go b/pkg/vz/network_darwin.go
index 1aceb8e2..fb458ad1 100644
--- a/pkg/vz/network_darwin.go
+++ b/pkg/vz/network_darwin.go
@@ -13,7 +13,7 @@ import (
 	"github.com/balajiv113/fd"
 
 	"github.com/sirupsen/logrus"
-	"inet.af/tcpproxy" // replaced to github.com/inetaf/tcpproxy in go.mod
+	"inet.af/tcpproxy"
 )
 
 func PassFDToUnix(unixSock string) (*os.File, error) {
diff --git a/pkg/vz/vm_darwin.go b/pkg/vz/vm_darwin.go
index 4599e6f0..74151f36 100644
--- a/pkg/vz/vm_darwin.go
+++ b/pkg/vz/vm_darwin.go
@@ -203,7 +203,12 @@ func createVM(driver *driver.BaseDriver) (*vz.VirtualMachine, error) {
 }
 
 func createInitialConfig(driver *driver.BaseDriver) (*vz.VirtualMachineConfiguration, error) {
-	bootLoader, err := bootLoader(driver)
+	efiVariableStore, err := getEFI(driver)
+	if err != nil {
+		return nil, err
+	}
+
+	bootLoader, err := vz.NewEFIBootLoader(vz.WithEFIVariableStore(efiVariableStore))
 	if err != nil {
 		return nil, err
 	}
@@ -681,47 +686,6 @@ func getMachineIdentifier(driver *driver.BaseDriver) (*vz.GenericMachineIdentifi
 	return vz.NewGenericMachineIdentifierWithDataPath(identifier)
 }
 
-func bootLoader(driver *driver.BaseDriver) (vz.BootLoader, error) {
-	linuxBootLoder, err := linuxBootLoader(driver)
-	if linuxBootLoder != nil {
-		return linuxBootLoder, nil
-	} else if !errors.Is(err, os.ErrNotExist) {
-		return nil, err
-	}
-
-	efiVariableStore, err := getEFI(driver)
-	if err != nil {
-		return nil, err
-	}
-	logrus.Debugf("Using EFI Boot Loader")
-	return vz.NewEFIBootLoader(vz.WithEFIVariableStore(efiVariableStore))
-}
-
-func linuxBootLoader(driver *driver.BaseDriver) (*vz.LinuxBootLoader, error) {
-	kernel := filepath.Join(driver.Instance.Dir, filenames.Kernel)
-	kernelCmdline := filepath.Join(driver.Instance.Dir, filenames.KernelCmdline)
-	initrd := filepath.Join(driver.Instance.Dir, filenames.Initrd)
-	if _, err := os.Stat(kernel); err != nil {
-		if errors.Is(err, os.ErrNotExist) {
-			logrus.Debugf("Kernel file %q not found", kernel)
-		} else {
-			logrus.WithError(err).Debugf("Error while checking kernel file %q", kernel)
-		}
-		return nil, err
-	}
-	var opt []vz.LinuxBootLoaderOption
-	if b, err := os.ReadFile(kernelCmdline); err == nil {
-		logrus.Debugf("Using kernel command line %q", string(b))
-		opt = append(opt, vz.WithCommandLine(string(b)))
-	}
-	if _, err := os.Stat(initrd); err == nil {
-		logrus.Debugf("Using initrd %q", initrd)
-		opt = append(opt, vz.WithInitrd(initrd))
-	}
-	logrus.Debugf("Using Linux Boot Loader with kernel %q", kernel)
-	return vz.NewLinuxBootLoader(kernel, opt...)
-}
-
 func getEFI(driver *driver.BaseDriver) (*vz.EFIVariableStore, error) {
 	efi := filepath.Join(driver.Instance.Dir, filenames.VzEfi)
 	if _, err := os.Stat(efi); os.IsNotExist(err) {
diff --git a/pkg/yqutil/yqutil.go b/pkg/yqutil/yqutil.go
index 69910840..139d9fcb 100644
--- a/pkg/yqutil/yqutil.go
+++ b/pkg/yqutil/yqutil.go
@@ -2,63 +2,26 @@ package yqutil
 
 import (
 	"bytes"
-	"errors"
 	"fmt"
-	"io"
 	"os"
 	"strings"
 
-	"github.com/google/yamlfmt"
 	"github.com/google/yamlfmt/formatters/basic"
 	"github.com/mikefarah/yq/v4/pkg/yqlib"
 	"github.com/sirupsen/logrus"
 	logging "gopkg.in/op/go-logging.v1"
 )
 
-// ValidateContent decodes the content yaml, to check it for syntax errors.
-func ValidateContent(content []byte) error {
-	memory := logging.NewMemoryBackend(0)
-	backend := logging.AddModuleLevel(memory)
-	logging.SetBackend(backend)
-	yqlib.InitExpressionParser()
-
-	decoder := yqlib.NewYamlDecoder(yqlib.ConfiguredYamlPreferences)
-
-	reader := bytes.NewReader(content)
-	err := decoder.Init(reader)
-	if err != nil {
-		return err
-	}
-	_, err = decoder.Decode()
-	if errors.Is(err, io.EOF) {
-		return nil
-	}
-	return err
-}
-
 // EvaluateExpression evaluates the yq expression, and returns the modified yaml.
 func EvaluateExpression(expression string, content []byte) ([]byte, error) {
 	logrus.Debugf("Evaluating yq expression: %q", expression)
-	formatter, err := yamlfmtBasicFormatter()
-	if err != nil {
-		return nil, err
-	}
-	// `ApplyFeatures()` is being called directly before passing content to `yqlib`.
-	// This results in `ApplyFeatures()` being called twice with `FeatureApplyBefore`:
-	// once here and once inside `formatter.Format`.
-	// Currently, calling `ApplyFeatures()` with `FeatureApplyBefore` twice is not an issue,
-	// but future changes to `yamlfmt` might cause problems if it is called twice.
-	contentModified, err := formatter.Features.ApplyFeatures(content, yamlfmt.FeatureApplyBefore)
-	if err != nil {
-		return nil, err
-	}
 	tmpYAMLFile, err := os.CreateTemp("", "lima-yq-*.yaml")
 	if err != nil {
 		return nil, err
 	}
 	tmpYAMLPath := tmpYAMLFile.Name()
 	defer os.RemoveAll(tmpYAMLPath)
-	_, err = tmpYAMLFile.Write(contentModified)
+	_, err = tmpYAMLFile.Write(content)
 	if err != nil {
 		tmpYAMLFile.Close()
 		return nil, err
@@ -107,7 +70,7 @@ func EvaluateExpression(expression string, content []byte) ([]byte, error) {
 		return nil, err
 	}
 
-	return formatter.Format(out.Bytes())
+	return yamlfmt(out.Bytes())
 }
 
 func Join(yqExprs []string) string {
@@ -117,23 +80,17 @@ func Join(yqExprs []string) string {
 	return strings.Join(yqExprs, " | ")
 }
 
-func yamlfmtBasicFormatter() (*basic.BasicFormatter, error) {
+func yamlfmt(content []byte) ([]byte, error) {
 	factory := basic.BasicFormatterFactory{}
 	config := map[string]interface{}{
-		"indentless_arrays":         true,
-		"line_ending":               "lf", // prefer LF even on Windows
-		"pad_line_comments":         2,
-		"retain_line_breaks":        true,
-		"retain_line_breaks_single": false,
+		"indentless_arrays":  true,
+		"line_ending":        "lf", // prefer LF even on Windows
+		"pad_line_comments":  2,
+		"retain_line_breaks": true, // does not affect to the output because yq removes empty lines before formatting
 	}
-
 	formatter, err := factory.NewFormatter(config)
 	if err != nil {
 		return nil, err
 	}
-	basicFormatter, ok := formatter.(*basic.BasicFormatter)
-	if !ok {
-		return nil, fmt.Errorf("unexpected formatter type: %T", formatter)
-	}
-	return basicFormatter, nil
+	return formatter.Format(content)
 }


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7d012d73..f503fd79 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -90,10 +90,6 @@ jobs:
       run: make
     - name: Install
       run: sudo make install
-    - name: Verify templates match `limactl edit` format
-      run: |
-        find examples -name '*.yaml' -exec limactl edit --set 'del(.nothing)' {} \;
-        git diff-index --exit-code HEAD
     - name: Uninstall
       run: sudo make uninstall
 
diff --git a/hack/test-selinux.sh b/hack/test-selinux.sh
index 84ce5942..8ec318c2 100755
--- a/hack/test-selinux.sh
+++ b/hack/test-selinux.sh
@@ -20,8 +20,14 @@ NAME="$1"
 ## so keeping the label as nfs_t fits right. Package container-selinux by
 ## default adds rules for nfs_t context which allows container workloads to work as well.
 ## https://github.com/lima-vm/lima/pull/1965
+##
+## With integration[https://github.com/lima-vm/lima/pull/2474] with systemd-binfmt,
+## the existing "nfs_t" selinux label for Rosetta is causing issues while registering it.
+## This behaviour needs to be fixed by setting the label as "bin_t"
+## https://github.com/lima-vm/lima/pull/2630
 ##########################################################################################
-expected="context=system_u:object_r:nfs_t:s0"
+INFO "Testing secontext is set for rosetta"
+expected="context=system_u:object_r:bin_t:s0"
 #Skip Rosetta checks for x86 GHA mac runners
 if [[ "$(uname)" == "Darwin" && "$(arch)" == "arm64" ]]; then
 	INFO "Testing secontext is set for rosetta mounts"
@@ -33,6 +39,7 @@ if [[ "$(uname)" == "Darwin" && "$(arch)" == "arm64" ]]; then
 	fi
 fi
 INFO "Testing secontext is set for bind mounts"
+expected="context=system_u:object_r:nfs_t:s0"
 INFO "Checking in mounts"
 got=$(limactl shell "$NAME" mount | grep "$HOME" | awk '{print $6}')
 INFO "secontext ${HOME}: expected=${expected}, got=${got}"
diff --git a/pkg/downloader/downloader_test.go b/pkg/downloader/downloader_test.go
index 136de343..d2111200 100644
--- a/pkg/downloader/downloader_test.go
+++ b/pkg/downloader/downloader_test.go
@@ -121,69 +121,6 @@ func TestDownloadRemote(t *testing.T) {
 	})
 }
 
-func TestRedownloadRemote(t *testing.T) {
-	remoteDir, err := os.MkdirTemp("", "redownloadRemote")
-	assert.NilError(t, err)
-	t.Cleanup(func() { _ = os.RemoveAll(remoteDir) })
-	ts := httptest.NewServer(http.FileServer(http.Dir(remoteDir)))
-	t.Cleanup(ts.Close)
-
-	cacheDir, err := os.MkdirTemp("", "redownloadCache")
-	assert.NilError(t, err)
-	t.Cleanup(func() { _ = os.RemoveAll(cacheDir) })
-
-	downloadDir, err := os.MkdirTemp("", "redownloadLocal")
-	assert.NilError(t, err)
-	t.Cleanup(func() { _ = os.RemoveAll(downloadDir) })
-
-	cacheOpt := WithCacheDir(cacheDir)
-
-	t.Run("digest-less", func(t *testing.T) {
-		remoteFile := filepath.Join(remoteDir, "digest-less.txt")
-		assert.NilError(t, os.WriteFile(remoteFile, []byte("digest-less"), 0o644))
-		assert.NilError(t, os.Chtimes(remoteFile, time.Now(), time.Now().Add(-time.Hour)))
-		opt := []Opt{cacheOpt}
-
-		r, err := Download(context.Background(), filepath.Join(downloadDir, "digest-less1.txt"), ts.URL+"/digest-less.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusDownloaded, r.Status)
-		r, err = Download(context.Background(), filepath.Join(downloadDir, "digest-less2.txt"), ts.URL+"/digest-less.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusUsedCache, r.Status)
-
-		// modifying remote file will cause redownload
-		assert.NilError(t, os.Chtimes(remoteFile, time.Now(), time.Now()))
-		r, err = Download(context.Background(), filepath.Join(downloadDir, "digest-less3.txt"), ts.URL+"/digest-less.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusDownloaded, r.Status)
-	})
-
-	t.Run("has-digest", func(t *testing.T) {
-		remoteFile := filepath.Join(remoteDir, "has-digest.txt")
-		bytes := []byte("has-digest")
-		assert.NilError(t, os.WriteFile(remoteFile, bytes, 0o644))
-		assert.NilError(t, os.Chtimes(remoteFile, time.Now(), time.Now().Add(-time.Hour)))
-
-		digester := digest.SHA256.Digester()
-		_, err := digester.Hash().Write(bytes)
-		assert.NilError(t, err)
-		opt := []Opt{cacheOpt, WithExpectedDigest(digester.Digest())}
-
-		r, err := Download(context.Background(), filepath.Join(downloadDir, "has-digest1.txt"), ts.URL+"/has-digest.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusDownloaded, r.Status)
-		r, err = Download(context.Background(), filepath.Join(downloadDir, "has-digest2.txt"), ts.URL+"/has-digest.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusUsedCache, r.Status)
-
-		// modifying remote file won't cause redownload because expected digest is provided
-		assert.NilError(t, os.Chtimes(remoteFile, time.Now(), time.Now()))
-		r, err = Download(context.Background(), filepath.Join(downloadDir, "has-digest3.txt"), ts.URL+"/has-digest.txt", opt...)
-		assert.NilError(t, err)
-		assert.Equal(t, StatusUsedCache, r.Status)
-	})
-}
-
 func TestDownloadLocal(t *testing.T) {
 	const emptyFileDigest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
 	const testDownloadLocalDigest = "sha256:0c1e0fba69e8919b306d030bf491e3e0c46cf0a8140ff5d7516ba3a83cbea5b3"
diff --git a/pkg/limayaml/load_test.go b/pkg/limayaml/load_test.go
index a4a489f1..0a7c09fe 100644
--- a/pkg/limayaml/load_test.go
+++ b/pkg/limayaml/load_test.go
@@ -28,7 +28,7 @@ provision:
     echo three
 `
 	_, err := Load([]byte(s), "error.yaml")
-	assert.ErrorContains(t, err, "did not find expected key")
+	assert.ErrorContains(t, err, "failed to unmarshal YAML")
 }
 
 func TestLoadDiskString(t *testing.T) {
diff --git a/pkg/yqutil/yqutil_test.go b/pkg/yqutil/yqutil_test.go
index ad19c40f..fcf1260e 100644
--- a/pkg/yqutil/yqutil_test.go
+++ b/pkg/yqutil/yqutil_test.go
@@ -6,25 +6,6 @@ import (
 	"gotest.tools/v3/assert"
 )
 
-func TestValidateContent(t *testing.T) {
-	content := `
-# comment
-foo: bar
-`
-	err := ValidateContent([]byte(content))
-	assert.NilError(t, err)
-}
-
-func TestValidateContentError(t *testing.T) {
-	content := `
-- foo: bar
-  foo
-  bar
-`
-	err := ValidateContent([]byte(content))
-	assert.ErrorContains(t, err, "could not find expected")
-}
-
 func TestEvaluateExpressionSimple(t *testing.T) {
 	expression := `.cpus = 2 | .memory = "2GiB"`
 	content := `
@@ -38,7 +19,6 @@ memory: null
 	expected := `
 # CPUs
 cpus: 2
-
 # Memory size
 memory: 2GiB
 `