Skip to content

Commit

Permalink
feat: NTP, some packages version
Browse files Browse the repository at this point in the history
  • Loading branch information
kerimkaan committed May 24, 2024
1 parent 7114d24 commit 23fb272
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 10 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
on:
release:
types: [created]

permissions:
contents: write
packages: write

jobs:
release-linux-amd64:
name: release linux/amd64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: linux
goarch: amd64
build_args: -ldflags "-s -w"
build_tags: linux-amd64
release-mac-arm64:
name: release linux/amd64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: darwin
goarch: arm64
build_args: -ldflags "-s -w"
build_tags: darwin-arm64
82 changes: 75 additions & 7 deletions cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ package cmd

import (
"fmt"
"genius/helpers"
"log"
"net"
"os"
"time"

"github.com/beevik/ntp"
"github.com/miekg/dns"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/load"
Expand All @@ -26,7 +30,17 @@ Get a brief system information such as hostname, OS, architecture, kernel versio
platform version, virtualization system, virtualization role, hostID, uptime, boot time, procs, load average, CPU model,
CPU cores, total memory, memory usage, total disk space, disk space used, disk space free, disk space used percentage,
disk filesystem, interface name, interface hardware address, interface MTU, IPv4 of en0, DNS servers.`,
PreRun: func(cmd *cobra.Command, args []string) {
// Is the system Windows?
// If it is, the program will exit.
// Because the program is not compatible with Windows.
if helpers.IsWindows() {
fmt.Println("The program is not compatible with Windows.")
os.Exit(0)
}
},
Run: func(cmd *cobra.Command, args []string) {
t0 := time.Now()
hInfo, err := host.Info()
if err != nil {
log.Println(err)
Expand All @@ -51,20 +65,34 @@ disk filesystem, interface name, interface hardware address, interface MTU, IPv4
log.Println(err)
panic(err)
}
swapInfo, err := mem.SwapMemory()
if err != nil {
log.Println(err)
panic(err)
}
// Get disk usage information
diskInfo, err := disk.Usage("/")
if err != nil {
log.Println(err)
panic(err)
}

// Get NTP configurations from /etc/ntp.conf
ntpConfig, err := helpers.ReadNTPConfFile()
if err != nil {
log.Println(err)
// panic(err)
}

virtSystem := !(hInfo.VirtualizationSystem == "")
virtName := hInfo.VirtualizationSystem
virtRole := hInfo.VirtualizationRole
if !virtSystem {
virtName = "Not Available"
virtRole = "Not Available"
}
fmt.Println("============================================")
fmt.Println("System Information")
fmt.Println("Hostname: ", hInfo.Hostname)
fmt.Println("OS: ", hInfo.OS)
fmt.Println("Architecture: ", hInfo.KernelArch)
Expand All @@ -75,24 +103,29 @@ disk filesystem, interface name, interface hardware address, interface MTU, IPv4
fmt.Println("Virtualization System: ", virtName)
fmt.Println("Virtualization Role: ", virtRole)
fmt.Println("HostID: ", hInfo.HostID)
fmt.Println("Uptime: ", hInfo.Uptime)
fmt.Println("Boot Time: ", hInfo.BootTime)
fmt.Println("Uptime: ", hInfo.Uptime/60/60/24, "days", hInfo.Uptime/60/60%24, "hours", hInfo.Uptime/60%60, "minutes")
// BootTime is in Unix timestamp
// Convert it to human readable format
fmt.Println("Last Boot Time in Local Time: ", time.Unix(int64(hInfo.BootTime), 0).Format("2006-01-02 15:04:05"))
fmt.Println("Procs: ", hInfo.Procs)

fmt.Println("Load Average (1/5/15): ", loadAvg.Load1, loadAvg.Load5, loadAvg.Load15)

fmt.Println("============================================")
fmt.Println("CPU Model: ", cpuInfo[0].ModelName)
fmt.Println("CPU Cores: ", cpuInfo[0].Cores)

fmt.Println("Load Average (1/5/15): ", loadAvg.Load1, loadAvg.Load5, loadAvg.Load15)
fmt.Println("============================================")
fmt.Println("Total Memory: ", memInfo.Total/1024/1024, "MB")
usedPercentWith2Digit := fmt.Sprintf("%.2f", memInfo.UsedPercent)
fmt.Println("Memory usage (%): ", usedPercentWith2Digit)
fmt.Println("Swap Total: ", swapInfo.Total/1024/1024, "MB")
fmt.Println("Swap Used (%): ", fmt.Sprintf("%.2f", swapInfo.UsedPercent))
fmt.Println("============================================")

fmt.Println("Total Disk Space: ", diskInfo.Total/1024/1024/1024, "GB")
fmt.Println("Disk Space Used: ", diskInfo.Used/1024/1024/1024, "GB")
fmt.Println("Disk Space Free: ", diskInfo.Free/1024/1024/1024, "GB")
fmt.Println("Disk Space Used (%): ", diskInfo.UsedPercent)
fmt.Println("Disk Space Used (%): ", fmt.Sprintf("%.2f", diskInfo.UsedPercent))
fmt.Println("Disk filesystem: ", diskInfo.Fstype)
fmt.Println("============================================")

ifaces, err := net.Interfaces()
if err != nil {
Expand All @@ -117,13 +150,48 @@ disk filesystem, interface name, interface hardware address, interface MTU, IPv4
}
}
}
fmt.Println("============================================")

resolvConf, err := dns.ClientConfigFromFile("/etc/resolv.conf")
if err != nil {
log.Println(err)
panic(err)
}
fmt.Println("DNS Servers: ", resolvConf.Servers)
for _, ntp := range *ntpConfig {
fmt.Println("NTP Server: ", ntp.Server)
fmt.Println("NTP Burst Option: ", ntp.IBurst)
}

// Get the ntp pool time
ntpTime, err := ntp.Time("0.tr.pool.ntp.org")
if err != nil {
log.Println("Error getting NTP time")
log.Println(err)
}
// Get the current time of the system
currentTime := time.Now()
fmt.Println("Current Time of the System: ", currentTime.Format("2006-01-02 15:04:05"))
fmt.Println("NTP (0.tr.pool.ntp.org) Time: ", ntpTime.Format("2006-01-02 15:04:05"))
// Calculate the time difference between the system and NTP time
timeDiff := ntpTime.Sub(currentTime)
fmt.Println("Time Difference: ", timeDiff)
fmt.Println("============================================")
if helpers.IsMacOS() {
brewVersion, err := helpers.GetHomeBrewVersion()
if err != nil {
log.Println(err)
}
fmt.Println("Homebrew Version: ", brewVersion)
}

pythonVersion, err := helpers.GetPythonVersion()
if err != nil {
log.Println(err)
}
fmt.Println("Python Version: ", pythonVersion)
t1 := time.Now()
fmt.Println("Time taken to get the system information: ", t1.Sub(t0))
},
}

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module genius
go 1.22.3

require (
github.com/beevik/ntp v1.4.2
github.com/miekg/dns v1.1.59
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/shirou/gopsutil/v3 v3.24.4
Expand All @@ -20,7 +21,7 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/tools v0.19.0 // indirect
)
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/beevik/ntp v1.4.2 h1:cjYhZqczanf6br/ocViahE75ipj7CmKQAh7fSBaCNK4=
github.com/beevik/ntp v1.4.2/go.mod h1:zkATLTt8VUZuOfYX2KgOnir4yvtAxWbnUUA24umXFnc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down Expand Up @@ -48,8 +50,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
80 changes: 80 additions & 0 deletions helpers/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package helpers

import (
"fmt"
"genius/types"
"os"
"strings"
)

// CheckFileExists checks if the file exists in the given path
// and returns a boolean value.
func CheckFileExists(path string) bool {
if _, err := os.Stat(path); os.IsNotExist(err) {
return false
}
return true
}

// ReadNTPConfFile reads the NTP configuration file and returns the content.
// The NTP configuration file is located at /etc/ntp.conf
// and it contains the NTP server addresses.
// The NTP server addresses are used to get the time from the NTP server.
func ReadNTPConfFile() (*[]types.NTPConfiguration, error) {
ntpConfFile := "/etc/ntp.conf"
// Or if it has chrony installed
// ntpConfFile := "/etc/chrony/chrony.conf"

if !CheckFileExists(ntpConfFile) {
return nil, fmt.Errorf("NTP configuration file %s does not exist.", ntpConfFile)
}
// Read the NTP configuration file
// and return the content
ntpFile, err := os.ReadFile(ntpConfFile)
if err != nil {
return nil, err
}
stringNTPFile := string(ntpFile)

// We have NTP config file something like this:
// server 0.us.pool.ntp.org iburst
// server 1.us.pool.ntp.org iburst
// server 2.us.pool.ntp.org iburst
// server 3.us.pool.ntp.org iburst

// Find the server addresses in the NTP configuration file
// and return them
if strings.Index(stringNTPFile, "server") == -1 {
return nil, fmt.Errorf("NTP server addresses not found in %s", ntpConfFile)
}
// Remove the comments and get the server addresses
if strings.Index(stringNTPFile, "#") != -1 {
stringNTPFile = stringNTPFile[:strings.Index(stringNTPFile, "#")] // Remove the comments
}
stringNTPFile = stringNTPFile[strings.Index(stringNTPFile, "server")+7:] // Get the server addresses
// Replace the "server" keyword with an empty string
stringNTPFile = strings.ReplaceAll(stringNTPFile, "server", "")

stringNTPFile = strings.ReplaceAll(stringNTPFile, "\n", " ")
stringArrayNTPFile := strings.Fields(stringNTPFile)

var ntpConfig []types.NTPConfiguration
for i, server := range stringArrayNTPFile {
if server == "iburst" {
continue
} else if server == "" {
continue
}
var iburst bool
if i+1 >= len(stringArrayNTPFile) {
iburst = false
} else {
iburst = stringArrayNTPFile[i+1] == "iburst"
}
ntpConfig = append(ntpConfig, types.NTPConfiguration{
Server: server,
IBurst: iburst,
})
}
return &ntpConfig, nil
}
19 changes: 19 additions & 0 deletions helpers/os.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package helpers

import "runtime"

func IsWindows() bool {
// GOOS is the running program's operating system target:
// one of darwin, freebsd, linux, and so on.
if runtime.GOOS == "windows" {
return true
}
return false
}

func IsMacOS() bool {
if runtime.GOOS == "darwin" {
return true
}
return false
}
53 changes: 53 additions & 0 deletions helpers/packages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package helpers

import (
"log"
"os/exec"
"strings"
)

func GetHomeBrewVersion() (string, error) {
// Get the Homebrew version
// brew --version
cmd := exec.Command("brew", "--version")
stdout, err := cmd.Output()
if err != nil {
if strings.Contains(err.Error(), "executable file not found") {
return "Not found", nil
}
log.Println(err)
// panic(err)
return "", err
}
stringified := string(stdout)
// Remove the new line character
stringified = strings.TrimSuffix(stringified, "\n")
// Remove the Homebrew keyword
stringified = strings.ReplaceAll(stringified, "Homebrew", "")
// Remove the whitespace
stringified = strings.TrimSpace(stringified)
return stringified, nil
}

func GetPythonVersion() (string, error) {
// Get the Python version
// python --version
cmd := exec.Command("python3", "--version")
stdout, err := cmd.Output()
if err != nil {
if strings.Contains(err.Error(), "executable file not found") {
return "Not found", nil
}
log.Println(err)
// panic(err)
return "", err
}
stringified := string(stdout)
// Remove the new line character
stringified = strings.TrimSuffix(stringified, "\n")
// Remove the Python keyword
stringified = strings.ReplaceAll(stringified, "Python", "")
// Remove the whitespace
stringified = strings.TrimSpace(stringified)
return stringified, nil
}
6 changes: 6 additions & 0 deletions types/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package types

type NTPConfiguration struct {
Server string `json:"server"`
IBurst bool `json:"iburst"`
}

0 comments on commit 23fb272

Please sign in to comment.