Skip to content

Commit

Permalink
adds Host.Info().NativeArchitecture
Browse files Browse the repository at this point in the history
  • Loading branch information
intxgo committed Feb 5, 2024
1 parent 489579d commit 0351ceb
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 14 deletions.
42 changes: 41 additions & 1 deletion providers/darwin/arch_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ package darwin

import (
"fmt"
"os"

"golang.org/x/sys/unix"
)

const hardwareMIB = "hw.machine"
const (
hardwareMIB = "hw.machine"
procTranslated = "sysctl.proc_translated"
archIntel = "x86_64"
archApple = "arm64"
)

func Architecture() (string, error) {
arch, err := unix.Sysctl(hardwareMIB)
Expand All @@ -35,3 +41,37 @@ func Architecture() (string, error) {

return arch, nil
}

func NativeArchitecture() (string, error) {
processArch, err := Architecture()
if err != nil {
return "", err
}

// https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment

data, err := unix.Sysctl(procTranslated)
if err != nil {
// macos without Rosetta installed doesn't have sysctl.proc_translated
if os.IsNotExist(err) {
return processArch, nil
}
return "", fmt.Errorf("failed to read sysctl.proc_translated: %w", err)
}

nativeArch := ""
translated := data[0]

switch translated {
case 0:
nativeArch = processArch
case 1:
// Rosetta 2 is supported only on Apple silicon
if processArch == archIntel {
nativeArch = archApple
}
default:
}

return nativeArch, nil
}
6 changes: 6 additions & 0 deletions providers/darwin/arch_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ func TestArchitecture(t *testing.T) {
assert.NoError(t, err)
assert.NotEmpty(t, a)
}

func TestNativeArchitecture(t *testing.T) {
a, err := NativeArchitecture()
assert.NoError(t, err)
assert.NotEmpty(t, a)
}
9 changes: 9 additions & 0 deletions providers/darwin/host_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ func newHost() (*host, error) {
h := &host{}
r := &reader{}
r.architecture(h)
r.nativeArchitecture(h)
r.bootTime(h)
r.hostname(h)
r.network(h)
Expand Down Expand Up @@ -206,6 +207,14 @@ func (r *reader) architecture(h *host) {
h.info.Architecture = v
}

func (r *reader) nativeArchitecture(h *host) {
v, err := NativeArchitecture()
if r.addErr(err) {
return
}
h.info.NativeArchitecture = v
}

func (r *reader) bootTime(h *host) {
v, err := BootTime()
if r.addErr(err) {
Expand Down
20 changes: 20 additions & 0 deletions providers/linux/arch_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ package linux

import (
"fmt"
"os"
"strings"
"syscall"
)

const procSysKernelArch = "/proc/sys/kernel/arch"

func Architecture() (string, error) {
var uname syscall.Utsname
if err := syscall.Uname(&uname); err != nil {
Expand All @@ -38,3 +42,19 @@ func Architecture() (string, error) {

return string(data), nil
}

func NativeArchitecture() (string, error) {
data, err := os.ReadFile(procSysKernelArch)
if err != nil {
if os.IsNotExist(err) {
return "", nil
}

return "", fmt.Errorf("failed to read kernel arch: %w", err)
}

nativeArch := string(data)
nativeArch = strings.TrimSpace(nativeArch)

return string(data), nil
}
36 changes: 36 additions & 0 deletions providers/linux/arch_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 darwin

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestArchitecture(t *testing.T) {
a, err := Architecture()
assert.NoError(t, err)
assert.NotEmpty(t, a)
}

func TestNativeArchitecture(t *testing.T) {
a, err := NativeArchitecture()
assert.NoError(t, err)
assert.NotEmpty(t, a)
}
9 changes: 9 additions & 0 deletions providers/linux/host_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func newHost(fs procFS) (*host, error) {
h := &host{stat: stat, procFS: fs}
r := &reader{}
r.architecture(h)
r.nativeArchitecture(h)
r.bootTime(h)
r.containerized(h)
r.hostname(h)
Expand Down Expand Up @@ -197,6 +198,14 @@ func (r *reader) architecture(h *host) {
h.info.Architecture = v
}

func (r *reader) nativeArchitecture(h *host) {
v, err := NativeArchitecture()
if r.addErr(err) {
return
}
h.info.NativeArchitecture = v
}

func (r *reader) bootTime(h *host) {
v, err := bootTime(h.procFS.FS)
if r.addErr(err) {
Expand Down
37 changes: 35 additions & 2 deletions providers/windows/arch_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,47 @@
package windows

import (
windows "github.com/elastic/go-windows"
"golang.org/x/sys/windows"

go_windows "github.com/elastic/go-windows"
)

const (
IMAGE_FILE_MACHINE_AMD64 = 0x8664
IMAGE_FILE_MACHINE_ARM64 = 0xAA64
archIntel = "x86_64"
archArm64 = "arm64"
)

func Architecture() (string, error) {
systemInfo, err := windows.GetNativeSystemInfo()
systemInfo, err := go_windows.GetNativeSystemInfo()
if err != nil {
return "", err
}

return systemInfo.ProcessorArchitecture.String(), nil
}

func NativeArchitecture() (string, error) {
var processMachine, nativeMachine uint16
// the pseudo handle doesn't need to be closed
var currentProcessHandle = windows.CurrentProcess()

err := windows.IsWow64Process2(currentProcessHandle, &processMachine, &nativeMachine)
if err != nil {
return "", err
}

nativeArch := ""

switch nativeMachine {
case IMAGE_FILE_MACHINE_AMD64:
// for parity with Architecture() as amd64 and x86_64 are used interchangeably
nativeArch = archIntel
case IMAGE_FILE_MACHINE_ARM64:
nativeArch = archArm64
default:
}

return nativeArch, nil
}
36 changes: 36 additions & 0 deletions providers/windows/arch_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 darwin

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestArchitecture(t *testing.T) {
a, err := Architecture()
assert.NoError(t, err)
assert.NotEmpty(t, a)
}

func TestNativeArchitecture(t *testing.T) {
a, err := NativeArchitecture()
assert.NoError(t, err)
assert.NotEmpty(t, a)
}
9 changes: 9 additions & 0 deletions providers/windows/host_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func newHost() (*host, error) {
h := &host{}
r := &reader{}
r.architecture(h)
r.nativeArchitecture(h)
r.bootTime(h)
r.hostname(h)
r.network(h)
Expand Down Expand Up @@ -141,6 +142,14 @@ func (r *reader) architecture(h *host) {
h.info.Architecture = v
}

func (r *reader) nativeArchitecture(h *host) {
v, err := NativeArchitecture()
if r.addErr(err) {
return
}
h.info.NativeArchitecture = v
}

func (r *reader) bootTime(h *host) {
v, err := BootTime()
if r.addErr(err) {
Expand Down
23 changes: 12 additions & 11 deletions types/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,18 @@ type VMStat interface {

// HostInfo contains basic host information.
type HostInfo struct {
Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips).
BootTime time.Time `json:"boot_time"` // Host boot time.
Containerized *bool `json:"containerized,omitempty"` // Is the process containerized.
Hostname string `json:"name"` // Hostname, lowercased.
IPs []string `json:"ip,omitempty"` // List of all IPs.
KernelVersion string `json:"kernel_version"` // Kernel version.
MACs []string `json:"mac"` // List of MAC addresses.
OS *OSInfo `json:"os"` // OS information.
Timezone string `json:"timezone"` // System timezone.
TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC).
UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional).
Architecture string `json:"architecture"` // Process hardware architecture (e.g. x86_64, arm, ppc, mips).
NativeArchitecture string `json:"native_architecture"` // Native OS hardware architecture (e.g. x86_64, arm, ppc, mips).
BootTime time.Time `json:"boot_time"` // Host boot time.
Containerized *bool `json:"containerized,omitempty"` // Is the process containerized.
Hostname string `json:"name"` // Hostname, lowercased.
IPs []string `json:"ip,omitempty"` // List of all IPs.
KernelVersion string `json:"kernel_version"` // Kernel version.
MACs []string `json:"mac"` // List of MAC addresses.
OS *OSInfo `json:"os"` // OS information.
Timezone string `json:"timezone"` // System timezone.
TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC).
UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional).
}

// Uptime returns the system uptime
Expand Down

0 comments on commit 0351ceb

Please sign in to comment.