Connect to SSL-enabled P4 Server

Scripts written with P4 API for Go use the existing P4TRUST file present in the operating environment. By default, .p4trust is found in the home directory of the user running the script.

The fingerprint returned by the server must match the fingerprint of the one installed in the P4TRUST file found in the script’s run-time environment.

If the fingerprints do not match, the script will fail to connect to the server.

Example

Here is an example for how to connect to SSL-enabled P4 Server

Copy
package main

import (
    "fmt"
    "math/rand"
    "os"
    "os/exec"
    "p4"
    "time"
)

func main() {
    // Setup directories and Perforce SSL server
    serverRoot := "/tmp/p4go_example_server"
    sslDir := serverRoot + "/ssl"
    os.MkdirAll(sslDir, 0700)

    // Generate fingerprint
    cmd := exec.Command("p4d", "-Gc")
    cmd.Env = append(os.Environ(), "P4SSLDIR="+sslDir)
    if err := cmd.Run(); err != nil {
        fmt.Println("Failed to create fingerprints:", err)
        return
    }

    // Pick a random SSL port and start p4d
    var randPort string
    var p4dCmd *exec.Cmd
    for retries := 10; retries > 0; retries-- {
        randPort = fmt.Sprintf("ssl:localhost:%d", 1024+rand.Intn(65000-1024))
        p4dCmd = exec.Command("p4d", "-p", randPort)
        p4dCmd.Env = append(os.Environ(), "P4SSLDIR="+sslDir)
        if err := p4dCmd.Start(); err == nil {
            time.Sleep(1 * time.Second)
            break
        }
    }

    defer func() {
        if p4dCmd != nil && p4dCmd.Process != nil {
            p4dCmd.Process.Kill()
            p4dCmd.Wait()
        }
        os.RemoveAll(serverRoot)
    }()

    // --- Use your Go API ---
    trustFile := ".p4trust"
    os.Remove(trustFile) // Ensure it doesn't exist

    // Create and configure your Perforce API client
    p4api := p4.New()
    p4api.SetPort(randPort)
    p4api.SetTrustFile(trustFile)

    // Connect (may need to retry if server is slow to start)
    retries := 60
    ret, _ := p4api.Connect()
    for retries > 0 && !ret {
        time.Sleep(1 * time.Second)
        retries--
        ret, _ = p4api.Connect()
    }
    if !p4api.Connected() {
        fmt.Println("Failed to connect to Perforce server")
        return
    }

    // Accept the trust
    _, _ = p4api.Run("trust", "-y")

    // Print the trust file path using p4api.TrustFile()
    fmt.Println("Trust file path:", p4api.TrustFile())

    // Optionally, check the trust file exists and is not empty
    fileInfo, err := os.Stat(trustFile)
    if err != nil || fileInfo.Size() == 0 {
        fmt.Println("Trust file not created or empty")
        return
    }
    fmt.Println("Trust file created and not empty:", trustFile)
}

Output

Copy
Trust file path: .p4trust-test
Trust file created and not empty: .p4trust-test