Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ trond preflight --intent my-net.yaml -o json

# 4. Create the whole network in one shot. trond auto-wires
# node.active between siblings so peering works under auto_ports.
SR_KEY=da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0 \
SR_KEY=a31d54825aea2fc5127e3bd435fc2346021313005e5f304ab33372432784acae \
trond network create --intent my-net.yaml --wait -o json
# Output: {"network":"pn", "nodes":[{"name":"pn-node0", "endpoints":{...}}, ...]}

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ LDFLAGS := -s -w -X $(MODULE)/cmd.version=$(VERSION) -X $(MODULE)/cmd.commit=
# resolves on PATH (useful in CI runners that already pinned Go via
# actions/setup-go and want to skip the download step).

GO_VERSION ?= 1.25.9
GO_VERSION ?= 1.25.13

ifeq ($(USE_SYSTEM_GO),1)
GO := go
Expand Down
7 changes: 7 additions & 0 deletions cmd/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func runBootstrap(cmd *cobra.Command, args []string) error {
if closer, ok := tgt.(interface{ Close() error }); ok {
defer closer.Close()
}
// Host preparation installs packages, which the ordinary SSH whitelist
// does not allow — deliberately, so that no lifecycle path or `trond
// exec` can. bootstrap is the one command that may, and only for the
// lifetime of this target.
if p, ok := tgt.(interface{ SetProvisioning(bool) }); ok {
p.SetProvisioning(true)
Comment thread
SeriousCoding789 marked this conversation as resolved.
}

runtimeType := parsed.Target.Runtime
if runtimeType == "" {
Expand Down
8 changes: 6 additions & 2 deletions cmd/config/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ func runDiff(cmd *cobra.Command, args []string) error {
// assignment misaligns the tail and would otherwise print the SR
// private key into `diffs[]`.
func simpleDiff(old, new []string) []string {
// Redact whole-slice: a multi-line `localwitness = [` array keeps its
// key on a line that does not itself start with the key name.
oldR := render.RedactWitnessLines(old)
newR := render.RedactWitnessLines(new)
var diffs []string

maxLen := len(old)
Expand All @@ -139,10 +143,10 @@ func simpleDiff(old, new []string) []string {
}
if oldLine != newLine {
if oldLine != "" {
diffs = append(diffs, fmt.Sprintf("- %s", render.RedactWitnessLine(oldLine)))
diffs = append(diffs, fmt.Sprintf("- %s", oldR[i]))
}
if newLine != "" {
diffs = append(diffs, fmt.Sprintf("+ %s", render.RedactWitnessLine(newLine)))
diffs = append(diffs, fmt.Sprintf("+ %s", newR[i]))
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions cmd/network/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ func runAdd(cmd *cobra.Command, args []string) error {
// Pick the next free index. Existing entries are "<network>-node<N>"; we
// rescan state instead of trusting any in-memory counter so the operation
// is safe to retry.
// Hold the state lock across the whole load-modify-save cycle: this
// command reads the node list here and writes it back much later, and
// a concurrent trond would otherwise drop one of the two updates.
lock := state.NewLock(paths.BaseDir())
if err := lock.Acquire(); err != nil {
return output.NewError("LOCK_ERROR", output.ExitGeneralError, "acquire state lock: "+err.Error())
}
defer lock.Release()

store, err := state.NewStore(paths.State())
if err != nil {
return err
Expand Down
9 changes: 9 additions & 0 deletions cmd/network/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ func runCreate(cmd *cobra.Command, args []string) error {
templateDir := findTemplatesDir()
workDir := paths.Deployments()

// Hold the state lock across the whole load-modify-save cycle: this
// command reads the node list here and writes it back much later, and
// a concurrent trond would otherwise drop one of the two updates.
lock := state.NewLock(paths.BaseDir())
if err := lock.Acquire(); err != nil {
return output.NewError("LOCK_ERROR", output.ExitGeneralError, "acquire state lock: "+err.Error())
}
defer lock.Release()

store, err := state.NewStore(paths.State())
if err != nil {
return output.NewError("STATE_ERROR", output.ExitGeneralError, err.Error())
Expand Down
9 changes: 9 additions & 0 deletions cmd/network/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ func runDestroy(cmd *cobra.Command, args []string) error {
WithSuggestions("Add --confirm <network-name> to proceed")
}

// Hold the state lock across the whole load-modify-save cycle: this
// command reads the node list here and writes it back much later, and
// a concurrent trond would otherwise drop one of the two updates.
lock := state.NewLock(paths.BaseDir())
if err := lock.Acquire(); err != nil {
return output.NewError("LOCK_ERROR", output.ExitGeneralError, "acquire state lock: "+err.Error())
}
defer lock.Release()

store, err := state.NewStore(paths.State())
if err != nil {
return err
Expand Down
8 changes: 6 additions & 2 deletions cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ func runPlan(cmd *cobra.Command, args []string) error {
// tail and would otherwise push the SR private key straight into
// stdout and into result["config_diff"].
func simpleHOCONDiff(old, new []string) []string {
// Redact whole-slice: a multi-line `localwitness = [` array keeps its
// key on a line that does not itself start with the key name.
oldR := render.RedactWitnessLines(old)
newR := render.RedactWitnessLines(new)
var diffs []string
maxLen := len(old)
if len(new) > maxLen {
Expand All @@ -215,10 +219,10 @@ func simpleHOCONDiff(old, new []string) []string {
}
if oldLine != newLine {
if oldLine != "" {
diffs = append(diffs, "- "+render.RedactWitnessLine(oldLine))
diffs = append(diffs, "- "+oldR[i])
}
if newLine != "" {
diffs = append(diffs, "+ "+render.RedactWitnessLine(newLine))
diffs = append(diffs, "+ "+newR[i])
}
}
}
Expand Down
29 changes: 28 additions & 1 deletion cmd/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,24 @@ type nodeContext struct {
Node *state.ManagedNode
Target target.Target
Runtime runtime.Runtime

// lock is held for the whole load-modify-save cycle. Every command
// built on a nodeContext reads state here and writes it back through
// SaveState, sometimes many seconds later, so the read and the write
// have to sit inside one lock or a concurrent trond drops one of the
// two updates.
lock *state.Lock
}

// Close releases resources (e.g., SSH connections).
// Close releases the state lock and any resources (e.g., SSH connections).
func (nc *nodeContext) Close() {
if closer, ok := nc.Target.(interface{ Close() error }); ok {
closer.Close()
}
if nc.lock != nil {
nc.lock.Release()
nc.lock = nil
}
}

// SaveState persists the current deployment state.
Expand Down Expand Up @@ -111,13 +122,27 @@ func resolveNodeContext(name string) (*nodeContext, error) {
return nil, err
}

// Take the lock before the read: the caller writes the same state back
// through SaveState once its operation finishes.
lock := state.NewLock(stateDir())
Comment thread
SeriousCoding789 marked this conversation as resolved.
Outdated
if err := lock.Acquire(); err != nil {
return nil, exitWithError("LOCK_ERROR", output.ExitGeneralError,
"Failed to acquire state lock: "+err.Error(),
"Check if another trond process is running")
}
release := func() {
lock.Release()
}

deployState, err := store.Load()
if err != nil {
release()
return nil, err
}

node := store.GetNode(deployState, name)
if node == nil {
release()
return nil, exitWithError("NODE_NOT_FOUND", output.ExitGeneralError,
fmt.Sprintf("Node %q not found in state", name),
"Run: trond list",
Expand All @@ -126,6 +151,7 @@ func resolveNodeContext(name string) (*nodeContext, error) {

tgt, err := resolveTargetFromNode(node)
if err != nil {
release()
return nil, exitWithError("TARGET_UNREACHABLE", output.ExitTargetUnreachable, err.Error())
}

Expand All @@ -137,6 +163,7 @@ func resolveNodeContext(name string) (*nodeContext, error) {
Node: node,
Target: tgt,
Runtime: rt,
lock: lock,
}, nil
}

Expand Down
12 changes: 8 additions & 4 deletions cmd/verify_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ func readLiveConfig(ctx context.Context, nc *nodeContext, name string) (string,
func lineDiff(live, desired string, contextLines int) []string {
a := strings.Split(strings.TrimRight(live, "\n"), "\n")
b := strings.Split(strings.TrimRight(desired, "\n"), "\n")
// Redact whole-slice: a multi-line `localwitness = [` array keeps its
// key on a line that does not itself start with the key name.
aR := render.RedactWitnessLines(a)
bR := render.RedactWitnessLines(b)
var diffs []string
max := len(a)
if len(b) > max {
Expand All @@ -192,17 +196,17 @@ func lineDiff(live, desired string, contextLines int) []string {
}
for j := lo; j < i; j++ {
if j < len(a) {
diffs = append(diffs, " "+render.RedactWitnessLine(a[j]))
diffs = append(diffs, " "+aR[j])
}
}
}
switch {
case i < len(a) && i >= len(b):
diffs = append(diffs, "- "+render.RedactWitnessLine(aLine))
diffs = append(diffs, "- "+aR[i])
case i >= len(a) && i < len(b):
diffs = append(diffs, "+ "+render.RedactWitnessLine(bLine))
diffs = append(diffs, "+ "+bR[i])
default:
diffs = append(diffs, "- "+render.RedactWitnessLine(aLine), "+ "+render.RedactWitnessLine(bLine))
diffs = append(diffs, "- "+aR[i], "+ "+bR[i])
}
}
return diffs
Expand Down
2 changes: 1 addition & 1 deletion examples/token-lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ through it with `txgen`, and assert the receivers hold exactly what was sent.

```bash
npm install # once — tronweb, for signing
export SR_PRIVATE_KEY=da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0
export SR_PRIVATE_KEY=a31d54825aea2fc5127e3bd435fc2346021313005e5f304ab33372432784acae

trond recipe run --file examples/token-lab/trc20.yaml --allow-host-exec \
--param lab_dir=examples/token-lab --param sender_key=$SR_PRIVATE_KEY
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/tronprotocol/tron-deployment

go 1.25.0

toolchain go1.25.11
toolchain go1.25.13

require (
github.com/cloudflare/circl v1.6.3
Expand Down Expand Up @@ -51,7 +51,7 @@ require (
go.opentelemetry.io/otel/metric v1.43.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/net v0.54.0 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/text v0.37.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGb
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down
6 changes: 3 additions & 3 deletions internal/knowledge/files/test-harness.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Driver script:

```bash
docker network create tron-pn-mesh
SR_KEY=da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0 \
SR_KEY=a31d54825aea2fc5127e3bd435fc2346021313005e5f304ab33372432784acae \
trond --state-dir /tmp/trond-$JOB \
network create --intent pn.yaml -o json
```
Expand All @@ -191,8 +191,8 @@ docker run --rm -v pn-node1_pn-node1-logs:/L alpine \
```

The default private-net witness private key
(`da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0`) matches
the genesis address `TPL66VK2gCXNCD7EJg9pgJRfqcRazjhUZY` baked into the
(`a31d54825aea2fc5127e3bd435fc2346021313005e5f304ab33372432784acae`) matches
the genesis address `TM4yToQ1njkcFwi3ADY5x6dbdfNekU3rVi` baked into the
`private_net_config.conf` template. Use that exact key unless you also
supply a fresh genesis block.

Expand Down
15 changes: 10 additions & 5 deletions internal/mcp/tools_drift.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ func mcpLineDiff(live, desired string, ctxLines int) []string {
if len(b) > maxLen {
maxLen = len(b)
}
// Redact whole-slice: a multi-line `localwitness = [` array keeps its
// key on a line that does not itself start with the key name. This
// output leaves the machine, so the per-line pass is not enough.
aR := render.RedactWitnessLines(a)
Comment thread
SeriousCoding789 marked this conversation as resolved.
bR := render.RedactWitnessLines(b)
for i := range maxLen {
var aLine, bLine string
if i < len(a) {
Expand All @@ -129,18 +134,18 @@ func mcpLineDiff(live, desired string, ctxLines int) []string {
}
for j := lo; j < i; j++ {
if j < len(a) {
diffs = append(diffs, " "+render.RedactWitnessLine(a[j]))
diffs = append(diffs, " "+aR[j])
}
}
}
switch {
case i < len(a) && i >= len(b):
diffs = append(diffs, "- "+render.RedactWitnessLine(aLine))
diffs = append(diffs, "- "+aR[i])
case i >= len(a) && i < len(b):
diffs = append(diffs, "+ "+render.RedactWitnessLine(bLine))
diffs = append(diffs, "+ "+bR[i])
default:
diffs = append(diffs, "- "+render.RedactWitnessLine(aLine))
diffs = append(diffs, "+ "+render.RedactWitnessLine(bLine))
diffs = append(diffs, "- "+aR[i])
diffs = append(diffs, "+ "+bR[i])
}
}
return diffs
Expand Down
9 changes: 9 additions & 0 deletions internal/mcp/tools_heal.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ func autoHealTool(ctx context.Context, _ *mcp.CallToolRequest, args autoHealArgs
return errResult(fmt.Errorf("name is required"))
}

// Hold the state lock across the load-modify-save cycle, the same way
// the lifecycle tool does — heal writes the node list back after the
// repair runs.
lock := state.NewLock(paths.BaseDir())
if err := lock.Acquire(); err != nil {
return errResult(fmt.Errorf("acquire state lock: %w", err))
}
defer lock.Release()

store, err := state.NewStore(paths.State())
if err != nil {
return errResult(err)
Expand Down
Loading
Loading