Skip to content

feat: Condition gates for system-state-gated resources#8

Merged
TsekNet merged 3 commits intomainfrom
condition-gate
Mar 16, 2026
Merged

feat: Condition gates for system-state-gated resources#8
TsekNet merged 3 commits intomainfrom
condition-gate

Conversation

@TsekNet
Copy link
Copy Markdown
Owner

@TsekNet TsekNet commented Mar 16, 2026

Implements #7: condition gates for system-state-gated resources.

Summary

  • New Condition interface in extensions/: Met(), Wait(), String() — gates daemon convergence on system state
  • Four built-in conditions in the new condition/ package: FileExists, NetworkReachable, NetworkInterface, MountPoint
  • Platform-native Wait() implementations: netlink RTMGRP_LINK (Linux), NotifyIpInterfaceChange (Windows), 2s poll (macOS) for network interfaces; inotify on /proc/self/mountinfo (Linux), kqueue on / (macOS), 5s poll (Windows) for mount points; inotify/kqueue/ReadDirectoryChangesW for file existence
  • Daemon: conditionsMet sync.Map tracks per-resource gate state; condition watcher goroutine blocks until Wait() returns, then injects EventCondition to trigger initial convergence
  • EventCondition send is blocking with ctx.Done() guard — a dropped event would leave the resource permanently unconverged
  • No unsafe imports: windows.NotifyIpInterfaceChange / windows.CancelMibChangeNotify2 from x/sys/windows used directly; ReadDirectoryChanges takes *byte
  • Struct/Met/String deduplicated to build-tag-free shared files; platform files contain only Wait()
  • Docs: immutable infrastructure section added to design.md (converge runs in Packer image builds via --timeout, then as a daemon on the running system — same blueprint, both phases); Chef/Puppet/Ansible accuracy fixes

Integration test (WSL2)

Results: 6 passed, 0 failed, 2 skipped

Skips: systemd not running in WSL (service drift test), nftables not available (firewall test). Both expected.

Usage

r.File("/etc/app/config.toml", dsl.FileOpts{
    Content: "...",
    Meta: dsl.ResourceMeta{
        Condition: condition.MountPoint("/mnt/nfs"),
    },
})

Ref #7

TsekNet added 3 commits March 16, 2026 14:19
- Move networkInterfaceCondition struct/Met/String to build-tag-free
  condition/network_interface.go; platform files keep only Wait()
- Move mountPointCondition struct/Met/String to condition/mount_point_unix.go
  (linux || darwin); Windows keeps its own struct/Met/String
- Remove sync.Mutex from Windows NotifyIpInterfaceChange callback (deadlock
  risk in thread pool context); buffered channel select/default is sufficient
- Replace hand-rolled iphlpapi procs with windows.NotifyIpInterfaceChange and
  windows.CancelMibChangeNotify2 from x/sys/windows; drops unsafe import
- Remove unsafe import from file_windows.go; ReadDirectoryChanges takes *byte
- Move overlapped event handle creation outside the loop in file_windows.go;
  add CancelIoEx on timeout; check GetOverlappedResult error
- Fix tests: dynamic loopback interface lookup, positive NetworkReachable case,
  rename misleading subtest, t.Skip for container/WSL mount edge case
- Fix docs/design.md: Puppet runtime is Ruby (agent) + JVM/JRuby (server only);
  Puppet apply compiles catalog locally; ansible-pull noted; ChefSpec vs InSpec
@TsekNet TsekNet merged commit a27521c into main Mar 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant