providers/linux/arch_linux.go (51 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package linux import ( "fmt" "os" "strings" "syscall" ) const ( procSysKernelArch = "/proc/sys/kernel/arch" procVersion = "/proc/version" arch8664 = "x86_64" archAmd64 = "amd64" archArm64 = "arm64" archAarch64 = "aarch64" ) func Architecture() (string, error) { var uname syscall.Utsname if err := syscall.Uname(&uname); err != nil { return "", fmt.Errorf("architecture: %w", err) } data := make([]byte, 0, len(uname.Machine)) for _, v := range uname.Machine { if v == 0 { break } data = append(data, byte(v)) } return string(data), nil } func NativeArchitecture() (string, error) { // /proc/sys/kernel/arch was introduced in Kernel 6.1 // https://www.kernel.org/doc/html/v6.1/admin-guide/sysctl/kernel.html#arch // It's the same as uname -m, except that for a process running in emulation // machine returned from syscall reflects the emulated machine, whilst /proc // filesystem is read as file so its value is not emulated data, err := os.ReadFile(procSysKernelArch) if err != nil { if os.IsNotExist(err) { // fallback to checking version string for older kernels version, err := os.ReadFile(procVersion) if err != nil && !os.IsNotExist(err) { return "", fmt.Errorf("failed to read kernel version: %w", err) } versionStr := string(version) if strings.Contains(versionStr, archAmd64) || strings.Contains(versionStr, arch8664) { return archAmd64, nil } else if strings.Contains(versionStr, archArm64) || strings.Contains(versionStr, archAarch64) { // for parity with Architecture() and /proc/sys/kernel/arch // as aarch64 and arm64 are used interchangeably return archAarch64, nil } return "", nil } return "", fmt.Errorf("failed to read kernel arch: %w", err) } nativeArch := string(data) nativeArch = strings.TrimRight(nativeArch, "\n") return nativeArch, nil }