github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/osutil/squashfs/fstype.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package squashfs 21 22 import ( 23 "os/exec" 24 "strings" 25 26 "github.com/snapcore/snapd/osutil" 27 ) 28 29 var needsFuseImpl = func() bool { 30 if !osutil.FileExists("/dev/fuse") { 31 return false 32 } 33 34 if !osutil.ExecutableExists("squashfuse") && !osutil.ExecutableExists("snapfuse") { 35 return false 36 } 37 38 out, err := exec.Command("systemd-detect-virt", "--container").Output() 39 if err != nil { 40 return false 41 } 42 43 virt := strings.TrimSpace(string(out)) 44 if virt != "none" { 45 return true 46 } 47 48 return false 49 } 50 51 // MockNeedsFuse is exported so NeedsFuse can be overridden by testing. 52 func MockNeedsFuse(r bool) func() { 53 oldNeedsFuseImpl := needsFuseImpl 54 needsFuseImpl = func() bool { 55 return r 56 } 57 return func() { needsFuseImpl = oldNeedsFuseImpl } 58 } 59 60 // NeedsFuse returns true if the given system needs fuse to mount snaps 61 func NeedsFuse() bool { 62 return needsFuseImpl() 63 } 64 65 // StandardOptions returns base squashfs options. 66 func StandardOptions() []string { 67 return []string{"ro", "x-gdu.hide", "x-gvfs-hide"} 68 } 69 70 // FsType returns what fstype to use for squashfs mounts and what 71 // mount options 72 func FsType() (fstype string, options []string) { 73 fstype = "squashfs" 74 options = StandardOptions() 75 76 if NeedsFuse() { 77 options = append(options, "allow_other") 78 switch { 79 case osutil.ExecutableExists("squashfuse"): 80 fstype = "fuse.squashfuse" 81 case osutil.ExecutableExists("snapfuse"): 82 fstype = "fuse.snapfuse" 83 default: 84 panic("cannot happen because NeedsFuse() ensures one of the two executables is there") 85 } 86 } 87 88 return fstype, options 89 }