github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/arch/arch.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2015 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 arch 21 22 import ( 23 "log" 24 "runtime" 25 26 "github.com/snapcore/snapd/osutil" 27 ) 28 29 // ArchitectureType is the type for a supported snappy architecture 30 type ArchitectureType string 31 32 // arch is global to allow tools like ubuntu-device-flash to 33 // change the architecture. This is important to e.g. install 34 // armhf snaps onto a armhf image that is generated on an amd64 35 // machine 36 var arch = ArchitectureType(dpkgArchFromGoArch(runtime.GOARCH)) 37 38 // SetArchitecture allows overriding the auto detected Architecture 39 func SetArchitecture(newArch ArchitectureType) { 40 arch = newArch 41 } 42 43 // DpkgArchitecture returns the debian equivalent architecture for the 44 // currently running architecture. 45 // 46 // If the architecture does not map any debian architecture, the 47 // GOARCH is returned. 48 func DpkgArchitecture() string { 49 return string(arch) 50 } 51 52 // dpkgArchFromGoArch maps a go architecture string to the coresponding 53 // Debian equivalent architecture string. 54 // 55 // E.g. the go "386" architecture string maps to the ubuntu "i386" 56 // architecture. 57 func dpkgArchFromGoArch(goarch string) string { 58 goArchMapping := map[string]string{ 59 // go dpkg 60 "386": "i386", 61 "amd64": "amd64", 62 "arm": "armhf", 63 "arm64": "arm64", 64 "ppc": "powerpc", 65 "ppc64": "ppc64", // available in debian and other distros 66 "ppc64le": "ppc64el", 67 "riscv64": "riscv64", 68 "s390x": "s390x", 69 } 70 71 // If we are running on an ARM platform we need to have a 72 // closer look if we are on armhf or armel. If we're not 73 // on a armv6 platform we can continue to use the Go 74 // arch mapping. The Go arch sadly doesn't map this out 75 // for us so we have to fallback to uname here. 76 if goarch == "arm" { 77 if osutil.MachineName() == "armv6l" { 78 return "armel" 79 } 80 } 81 82 dpkgArch := goArchMapping[goarch] 83 if dpkgArch == "" { 84 log.Panicf("unknown goarch %q", goarch) 85 } 86 87 return dpkgArch 88 } 89 90 // DpkgKernelArchitecture returns the debian equivalent architecture 91 // for the current running kernel. This is usually the same as the 92 // DpkgArchitecture - however there maybe cases that you run e.g. 93 // a snapd:i386 on an amd64 kernel. 94 func DpkgKernelArchitecture() string { 95 return dpkgArchFromKernelArch(osutil.MachineName()) 96 } 97 98 // dpkgArchFromkernelArch maps the kernel architecture as reported 99 // via uname() to the dpkg architecture 100 func dpkgArchFromKernelArch(utsMachine string) string { 101 kernelArchMapping := map[string]string{ 102 // kernel dpkg 103 "aarch64": "arm64", 104 "armv7l": "armhf", 105 "armv8l": "arm64", 106 "i686": "i386", 107 "ppc": "powerpc", 108 "ppc64": "ppc64", // available in debian and other distros 109 "ppc64le": "ppc64el", 110 "riscv64": "riscv64", 111 "s390x": "s390x", 112 "x86_64": "amd64", 113 } 114 115 dpkgArch := kernelArchMapping[utsMachine] 116 if dpkgArch == "" { 117 log.Panicf("unknown kernel arch %q", utsMachine) 118 } 119 120 return dpkgArch 121 } 122 123 // IsSupportedArchitecture returns true if the system architecture is in the 124 // list of architectures. 125 func IsSupportedArchitecture(architectures []string) bool { 126 for _, a := range architectures { 127 if a == "all" || a == string(arch) { 128 return true 129 } 130 } 131 132 return false 133 }