Skip to content

Latest commit

 

History

History

README.md

Turing Pi Client Library

A Go client library for controlling Turing Pi boards via their BMC API.

Features

  • Power management (on/off/reset)
  • USB configuration
  • UART access
  • Firmware management
  • Network configuration
  • Advanced node modes (MSD, normal)
  • Remote control via Agent mode

Installation

go get github.com/davidroman0O/tpi/client

Usage

package main

import (
	"fmt"
	"os"

	"github.com/davidroman0O/tpi/client"
)

func main() {
	// Create a client
	c, err := client.NewClient(
		client.WithHost("192.168.1.91"),
		client.WithCredentials("root", "turing"),
	)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating client: %v\n", err)
		os.Exit(1)
	}

	// Get board info
	info, err := c.Info()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error getting info: %v\n", err)
		os.Exit(1)
	}

	// Print info
	for key, value := range info {
		fmt.Printf("%s: %s\n", key, value)
	}
}

API Documentation

Client Creation

// Create a client with options
client, err := client.NewClient(
    client.WithHost("192.168.1.91"),
    client.WithCredentials("root", "turing"),
    client.WithApiVersion(client.ApiVersionV1_1),
    client.WithTimeout(5 * time.Second),
)

Power Management

// Get power status of all nodes
status, err := client.PowerStatus()

// Power on node 1
err := client.PowerOn(1)

// Power off node 1
err := client.PowerOff(1)

// Reset node 1
err := client.PowerReset(1)

// Power on all nodes
err := client.PowerOnAll()

// Power off all nodes
err := client.PowerOffAll()

See code documentation for more details on available functions.

Agent Mode

The library supports an Agent Mode that allows you to control a Turing Pi board remotely without direct access to the BMC. This works through two components:

  1. Agent Server: Runs on a machine with direct access to the Turing Pi board
  2. Agent Client: Connects to the Agent Server from a remote machine

Running an Agent Server

package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/davidroman0O/tpi/client"
	"github.com/davidroman0O/tpi/client/agent"
)

func main() {
	// Create a standard TPI client
	tpiClient, err := client.NewClient(
		client.WithHost("192.168.1.91"),
		client.WithCredentials("root", "turing"),
	)
	if err != nil {
		log.Fatalf("Error creating client: %v", err)
	}

	// Create and configure agent server
	server, err := agent.NewAgentServer(tpiClient,
		agent.WithServerPort(9977),
		agent.WithServerSecret("mysecret"),
		agent.WithAllowedIPs([]string{"192.168.1.0/24"}), // Optional IP restriction
	)
	if err != nil {
		log.Fatalf("Error creating agent server: %v", err)
	}

	// Setup context with cancellation
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Handle termination signals
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		<-sigCh
		cancel()
	}()

	// Start the agent server
	log.Println("Starting agent server on port 9977")
	if err := server.Run(ctx); err != nil {
		log.Fatalf("Agent server error: %v", err)
	}
}

Using an Agent Client

package main

import (
	"fmt"
	"log"

	"github.com/davidroman0O/tpi/client/agent"
)

func main() {
	// Create agent client
	client, err := agent.NewAgentClient(
		agent.WithAgentHost("192.168.1.91"),
		agent.WithAgentPort(9977),
		agent.WithAgentSecret("mysecret"),
	)
	if err != nil {
		log.Fatalf("Error creating agent client: %v", err)
	}

	// Get power status
	status, err := client.PowerStatus()
	if err != nil {
		log.Fatalf("Error getting power status: %v", err)
	}
	fmt.Println("Power status:", status)

	// Power on a node
	if err := client.PowerOn(1); err != nil {
		log.Fatalf("Error powering on node: %v", err)
	}
	fmt.Println("Powered on node 1 successfully")
}

File Transfer Functionality

The client provides SSH-based file transfer capabilities using SFTP, allowing you to upload files to, download files from, list directories on, and execute commands on the Turing Pi or connected systems.

Upload a File

Upload a local file to a remote path:

err := client.UploadFile("local/path/to/file.txt", "/remote/path/file.txt",
    WithSSHCredentials("username", "password"),
    WithSSHPort(22),
    WithSSHTimeout(30*time.Second),
)

Download a File

Download a file from the remote system to a local path:

err := client.DownloadFile("/remote/path/file.txt", "local/path/to/file.txt",
    WithSSHCredentials("username", "password"),
    WithSSHPort(22),
)

List Directory Contents

Get a list of files and directories in a remote path:

files, err := client.ListDirectory("/remote/path",
    WithSSHCredentials("username", "password"),
)

if err == nil {
    for _, file := range files {
        fmt.Printf("Name: %s, Size: %d, IsDir: %t\n", file.Name, file.Size, file.IsDir)
    }
}

Execute Remote Commands

Execute commands on the remote system:

output, err := client.ExecuteCommand("ls -la /tmp",
    WithSSHCredentials("username", "password"),
)

if err == nil {
    fmt.Println(output)
}

SSH Options

When using file transfer functions, you can provide additional options to configure the SSH connection:

  • WithSSHCredentials(username, password) - Set the SSH username and password
  • WithSSHPrivateKey(privateKey) - Use a private key for authentication
  • WithSSHPort(port) - Set a custom SSH port (default: 22)
  • WithSSHTimeout(timeout) - Set connection timeout (default: 10 seconds)

License

Apache License 2.0