|
|
@@ -22,9 +22,20 @@ const (
|
|
|
)
|
|
|
|
|
|
type Manager struct {
|
|
|
- mu sync.RWMutex
|
|
|
- configPath string
|
|
|
- config DynamicConfig
|
|
|
+ mu sync.RWMutex
|
|
|
+ configPath string
|
|
|
+ birdConfigPath string
|
|
|
+ config DynamicConfig
|
|
|
+}
|
|
|
+
|
|
|
+func (m *Manager) getBirdConfigPath() string {
|
|
|
+ if m.birdConfigPath != "" {
|
|
|
+ return m.birdConfigPath
|
|
|
+ }
|
|
|
+ if m.configPath != "" && m.configPath != defaultConfigPath {
|
|
|
+ return filepath.Join(filepath.Dir(m.configPath), "bird.conf")
|
|
|
+ }
|
|
|
+ return birdConfigPath
|
|
|
}
|
|
|
|
|
|
func NewManager(configPath string) *Manager {
|
|
|
@@ -1077,6 +1088,7 @@ func (m *Manager) generateBirdConfig() string {
|
|
|
}
|
|
|
|
|
|
var ripExports []string
|
|
|
+ ripExports = append(ripExports, "RTS_RIP")
|
|
|
if inst.RedistributeStatic {
|
|
|
ripExports = append(ripExports, "RTS_STATIC", "RTS_INHERIT")
|
|
|
}
|
|
|
@@ -1206,6 +1218,7 @@ func (m *Manager) generateBirdConfig() string {
|
|
|
}
|
|
|
|
|
|
var babelExports []string
|
|
|
+ babelExports = append(babelExports, "RTS_BABEL")
|
|
|
if inst.RedistributeStatic {
|
|
|
babelExports = append(babelExports, "RTS_STATIC", "RTS_INHERIT")
|
|
|
}
|
|
|
@@ -1363,34 +1376,41 @@ func (m *Manager) generateBirdConfig() string {
|
|
|
// applyBirdConfig generates /etc/bird/bird.conf and live reloads BIRD daemon
|
|
|
func (m *Manager) applyBirdConfig() error {
|
|
|
cfgText := m.generateBirdConfig()
|
|
|
+ bPath := m.getBirdConfigPath()
|
|
|
|
|
|
// Ensure directory exists with proper permissions
|
|
|
- dir := filepath.Dir(birdConfigPath)
|
|
|
+ dir := filepath.Dir(bPath)
|
|
|
if err := os.MkdirAll(dir, 0775); err == nil {
|
|
|
_ = os.Chmod(dir, 0775)
|
|
|
_ = exec.Command("chown", "root:bird", dir).Run()
|
|
|
}
|
|
|
|
|
|
// Write candidate configuration to temporary file
|
|
|
- tmpPath := birdConfigPath + ".new"
|
|
|
+ tmpPath := bPath + ".new"
|
|
|
if err := os.WriteFile(tmpPath, []byte(cfgText), 0664); err != nil {
|
|
|
return fmt.Errorf("failed to write %s: %w", tmpPath, err)
|
|
|
}
|
|
|
_ = exec.Command("chown", "root:bird", tmpPath).Run()
|
|
|
|
|
|
- // Validate syntax with bird -p
|
|
|
- out, err := exec.Command("bird", "-p", "-c", tmpPath).CombinedOutput()
|
|
|
- if err != nil {
|
|
|
- _ = os.Remove(tmpPath)
|
|
|
- return fmt.Errorf("bird syntax check failed: %s: %w", string(out), err)
|
|
|
+ // Validate syntax with bird -p if bird is installed
|
|
|
+ if bPath == birdConfigPath {
|
|
|
+ out, err := exec.Command("bird", "-p", "-c", tmpPath).CombinedOutput()
|
|
|
+ if err != nil {
|
|
|
+ _ = os.Remove(tmpPath)
|
|
|
+ return fmt.Errorf("bird syntax check failed: %s: %w", string(out), err)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Replace active config
|
|
|
- if err := os.Rename(tmpPath, birdConfigPath); err != nil {
|
|
|
- return fmt.Errorf("failed to replace %s: %w", birdConfigPath, err)
|
|
|
+ if err := os.Rename(tmpPath, bPath); err != nil {
|
|
|
+ return fmt.Errorf("failed to replace %s: %w", bPath, err)
|
|
|
+ }
|
|
|
+ _ = os.Chmod(bPath, 0664)
|
|
|
+ _ = exec.Command("chown", "root:bird", bPath).Run()
|
|
|
+
|
|
|
+ if bPath != birdConfigPath {
|
|
|
+ return nil
|
|
|
}
|
|
|
- _ = os.Chmod(birdConfigPath, 0664)
|
|
|
- _ = exec.Command("chown", "root:bird", birdConfigPath).Run()
|
|
|
|
|
|
// Ensure BIRD systemd service is active
|
|
|
_ = exec.Command("systemctl", "start", "bird").Run()
|