Skip to content

Commit

Permalink
Merge branch 'danielpaulus:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Assadginem authored May 21, 2024
2 parents aa058ae + 6a94ebe commit ccd72aa
Show file tree
Hide file tree
Showing 88 changed files with 8,457 additions and 855 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

- name: Build
run: |
((Get-Content -path main.go -Raw) -replace "local-build","${{ steps.create_release.outputs.current_tag }}") | Set-Content -Path main.go
((Get-Content -path main.go -Raw) -replace "local-build","${{ steps.create_release.outputs.current_tag }}") | Set-Content -Path main.go
mkdir bin
go build -ldflags="-s -w" -o bin/ios.exe
"${{ steps.create_release.outputs.current_tag }}" | Out-File -Encoding utf8NoBOM release_tag -NoNewline
Expand Down Expand Up @@ -69,7 +69,9 @@ jobs:
alias sed=gsed
gsed -i 's/version \= \"local-build\"/version = \"${{ env.release_tag }}\"/' main.go
mkdir bin
go build -ldflags="-s -w" -o bin/ios
GOARCH=arm64 go build -ldflags="-s -w" -o bin/ios-arm64
GOARCH=amd64 go build -ldflags="-s -w" -o bin/ios-amd64
lipo bin/ios-amd64 bin/ios-arm64 -create -output bin/ios
zip -j go-ios-mac.zip bin/ios
- name: upload the macos build
Expand Down Expand Up @@ -141,9 +143,10 @@ jobs:
mkdir ./npm_publish/dist/go-ios-darwin-amd64_darwin_amd64
mkdir ./npm_publish/dist/go-ios-linux-amd64_linux_amd64
mkdir ./npm_publish/dist/go-ios-windows-amd64_windows_amd64
cp ./mac-bin/ios ./npm_publish/dist/go-ios-darwin-amd64_darwin_amd64/ios
cp ./mac-bin/ios ./npm_publish/dist/go-ios-darwin-fat_darwin_fat/ios
cp ./win-bin/ios.exe ./npm_publish/dist/go-ios-windows-amd64_windows_amd64/ios.exe
cp ./bin/ios ./npm_publish/dist/go-ios-linux-amd64_linux_amd64/ios
cp README.md ./npm_publish/README.md
echo "//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" >> ~/.npmrc
cd npm_publish
sed -i 's/\"local-build\"/\"${{ env.release_tag }}\"/' package.json
Expand Down
14 changes: 11 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ jobs:
go-version-file: go.mod
cache: true

#- name: Install Libusb
# run: choco install

- name: Build executable
run: go build

- name: Run fast tests
run: go test -v -tags=fast ./...
#- name: Run fast tests
# run: go test -v -tags=fast ./...

test_on_linux:
runs-on: ubuntu-latest
Expand All @@ -30,9 +33,14 @@ jobs:
with:
go-version-file: go.mod
cache: true
- name: update
run: sudo apt-get update

- name: install libusb
run: sudo apt-get install -y libusb-1.0-0-dev

- name: Build executable
run: go build
run: make build --trace

- name: Run fast tests
run: go test -v -tags=fast ./...
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ devimages
go-ios
usbmuxd
main
go-ncm
*.png
!logo.png
# Test binary, build with `go test -c`
Expand Down
45 changes: 45 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Makefile to build and run go-ios and the cdc-ncm network driver
# cdc-ncm needs to be executed with sudo on Linux for USB Access and setting
# up virtual TAP network devices.
# use Make build to build both binaries.
# Make run is a simple target that just runs the cdc-ncm driver with sudo
# For development, use "make up" to rebuild and run cdc-ncm quickly

# Name of your Go binaries
GO_IOS_BINARY_NAME=ios
NCM_BINARY_NAME=go-ncm


# Detect the system architecture
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)

# Default GOARCH value
GOARCH := amd64

# Set GOARCH based on the detected architecture
ifeq ($(UNAME_M),x86_64)
GOARCH := amd64
else ifeq ($(UNAME_M),armv7l)
GOARCH := arm
else ifeq ($(UNAME_M),aarch64)
GOARCH := arm64
# Add more architecture mappings as needed
endif

# Build the Go program
build:
@go work use .
@GOARCH=$(GOARCH) go build -o $(GO_IOS_BINARY_NAME) ./main.go
@go work use ./ncm
@CGO_ENABLED=1 GOARCH=$(GOARCH) go build -o $(NCM_BINARY_NAME) ./cmd/cdc-ncm/main.go

# Run the Go program with sudo
run: build
@sudo ./$(NCM_BINARY_NAME) --prometheusport=8080

# Build and run
up: build run

# Phony targets
.PHONY: build run up
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Welcome 👋

`npm install -g go-ios` can be used to get going. Run `ios --help` after the installation for details.

The goal of this project is to provide a stable and production ready opensource solution to automate iOS device on Linux, Windows and Mac OS X. I am delighted to announce that a few companies including [headspin.io](https://www.headspin.io/) will use or are using go-iOS.
The goal of this project is to provide a stable and production ready opensource solution to automate iOS device on Linux, Windows and Mac OS X. I am delighted to announce that a few companies including [headspin.io](https://www.headspin.io/) and [Sauce Labs](https://saucelabs.com/) will use or are using go-iOS.

Follow my twitter for updates or check out my medium blog: https://daniel-paulus.medium.com/

Expand Down
61 changes: 61 additions & 0 deletions cmd/cdc-ncm/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"flag"
ncm "go-ios-cdcncm"
"log/slog"
"os"
"os/signal"
"runtime"
)

func checkRoot() {
u := os.Geteuid()
if u != 0 {
slog.Error("go-ncm needs root. run with sudo.")
os.Exit(1)
}
}

func checkLinux() {
if runtime.GOOS != "linux" {
slog.Error("go-ncm only works on linux")
os.Exit(1)
}
}

// accepts one cmd line argument: --prometheusport=8080
// if specified, prometheus metrics will be available at http://0.0.0.0:prometheusport/metrics
// if not specified, the prometheus endpoint will not be started and not be available.
func main() {
checkLinux()
checkUsbMux()
checkRoot()
// Define a string flag with a default value and a short description.
// This will read the command-line argument for --prometheusport.
prometheusPort := flag.Int("prometheusport", -1, "The port for Prometheus metrics")
// Parse the flags from the command-line arguments.
flag.Parse()
if *prometheusPort != -1 {
go ncm.StartPrometheus(*prometheusPort)
} else {
slog.Info("prometheus metrics not configured. start with '--prometheusport=8080' to expose prometheus metrics.")
}
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
err := ncm.Start(c)
if err != nil {
slog.Error("error looking for devices", slog.Any("error", err))
os.Exit(1)
}

}

func checkUsbMux() {
v, err := ncm.CheckUSBMUXVersion()
if err != nil {
slog.Error("error getting usbmuxd version", slog.Any("error", err))
os.Exit(1)
}
slog.Info("usbmuxd version", slog.Any("version", v))
}
129 changes: 129 additions & 0 deletions cmd/configure/configure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package main

import (
"bytes"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)

func main() {
if !IsDebianUbuntuOrAlpine() {
fail("only ubuntu, debian or alpine are supported")
}
if !DpkgExists() {
fail("dpkg needs to be installed to check dependencies")
}

checkDep("libusb-1.0-0-dev")
checkDep("build-essential")
checkDep("pkg-config")

log.Println("good to go. run 'make'")
//apt-get install -y libusb-1.0-0-dev

}

func checkDep(dep string) {
log.Println("checking: " + dep)
if !CheckPackageInstalled(dep) {
log.Println("installing: " + dep)
InstallPackage(dep)
}
log.Println("ok: " + dep)
}

func fail(reason string) {
panic(reason)
}

// CheckPackageInstalled checks if the specified package is installed.
// It uses dpkg on Debian/Ubuntu and apk on Alpine.
func CheckPackageInstalled(packageName string) bool {
if DpkgExists() {
output := ExecuteCommand("dpkg", "-l", packageName)
return strings.Contains(output, packageName) && !strings.Contains(output, "no packages found")
} else if ApkExists() {
output := ExecuteCommand("apk", "info", packageName)
return output != ""
}
log.Println("No compatible package manager found (dpkg or apk).")
return false
}

// ExecuteCommand runs the specified shell command and returns its output or panics if there's an error.
func ExecuteCommand(command string, args ...string) string {
cmd := exec.Command(command, args...)
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Printf("Failed to execute command: %s\nError: %v, Stderr: %v\n", command, err, stderr.String())
}
return out.String()
}

// DpkgExists checks if dpkg exists in the system's PATH.
func DpkgExists() bool {
_, err := exec.LookPath("dpkg")
return err == nil
}

// IsDebianUbuntuOrAlpine checks if the operating system is Debian, Ubuntu, or Alpine.
func IsDebianUbuntuOrAlpine() bool {
content, err := ioutil.ReadFile("/etc/os-release")
if err != nil {
log.Printf("Failed to read /etc/os-release: %v", err)
return false
}

osRelease := string(content)
return strings.Contains(osRelease, "ID=debian") || strings.Contains(osRelease, "ID=ubuntu") || strings.Contains(osRelease, "ID=alpine")
}

func IsRunningWithSudo() bool {
// The effective user ID (eUID) is 0 for the root user.
return os.Geteuid() == 0
}

// PackageManagerType returns the type of package manager available on the system.
func PackageManagerType() string {
if _, err := exec.LookPath("apt-get"); err == nil {
return "apt-get"
} else if _, err := exec.LookPath("apk"); err == nil {
return "apk"
}
return ""
}

// InstallPackage installs a package using the system's package manager.
func InstallPackage(packageName string) {
var command string
var args []string

// Check if apt-get is available
if _, err := exec.LookPath("apt-get"); err == nil {
command = "apt-get"
args = []string{"install", "-y", packageName}
} else if _, err := exec.LookPath("apk"); err == nil {
// If apt-get is not available, check for apk
command = "apk"
args = []string{"add", packageName}
} else {
log.Panic("No compatible package manager found (apt-get or apk).")
}

// Execute the install command
log.Printf("Installing package %s using %s\n", packageName, command)
ExecuteCommand(command, args...)
}

// ApkExists checks if apk (Alpine Package Keeper) exists in the system's PATH.
func ApkExists() bool {
_, err := exec.LookPath("apk")
return err == nil
}
22 changes: 22 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
# this uses golang because I don't like shell scripts
# if you need to fix stuff, change it in the configure.go

GO_BIN=$(which go)

# Check if Go is installed by verifying if GO_BIN is not empty
if [ -z "$GO_BIN" ]; then
echo "Go is not installed or not found in the PATH."
exit 1
fi

check_sudo() {
if command -v sudo >/dev/null 2>&1; then
echo "sudo"
else
echo ""
fi
}
SUDO=$(check_sudo)

$SUDO $GO_BIN run cmd/configure/configure.go
25 changes: 21 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
module github.com/danielpaulus/go-ios

go 1.17
go 1.21

require (
github.com/Masterminds/semver v1.5.0
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa
github.com/google/gopacket v1.1.19
github.com/google/uuid v1.1.2
github.com/grandcat/zeroconf v1.0.0
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/pierrec/lz4 v2.6.1+incompatible
github.com/quic-go/quic-go v0.40.1-0.20231203135336-87ef8ec48d55
github.com/sirupsen/logrus v1.6.0
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/stretchr/testify v1.6.1
golang.org/x/crypto v0.0.0-20210812204632-0ba0e8f03122
github.com/tadglines/go-pkgs v0.0.0-20210623144937-b983b20f54f9
golang.org/x/crypto v0.15.0
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
golang.org/x/net v0.18.0
howett.net/plist v0.0.0-20200419221736-3b63eb3a43b5
)

require (
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/frankban/quicktest v1.14.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/miekg/dns v1.1.57 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/stretchr/objx v0.1.0 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
go.uber.org/mock v0.3.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit ccd72aa

Please sign in to comment.