@@ -1706,7 +1706,15 @@ func newDaemonPromise(params daemonParams) (promise.Promise[*Daemon], promise.Pr
1706
1706
var wg sync.WaitGroup
1707
1707
1708
1708
params .Lifecycle .Append (cell.Hook {
1709
- OnStart : func (cell.HookContext ) error {
1709
+ OnStart : func (cell.HookContext ) (err error ) {
1710
+ defer func () {
1711
+ // Reject promises on error
1712
+ if err != nil {
1713
+ cfgResolver .Reject (err )
1714
+ daemonResolver .Reject (err )
1715
+ }
1716
+ }()
1717
+
1710
1718
d , restoredEndpoints , err := newDaemon (daemonCtx , cleaner , & params )
1711
1719
if err != nil {
1712
1720
cancelDaemonCtx ()
@@ -1716,16 +1724,45 @@ func newDaemonPromise(params daemonParams) (promise.Promise[*Daemon], promise.Pr
1716
1724
daemon = d
1717
1725
1718
1726
if ! option .Config .DryMode {
1719
- if err := startDaemon (daemon , restoredEndpoints , cleaner , params ); err != nil {
1720
- daemonResolver .Reject (err )
1721
- cancelDaemonCtx ()
1722
- cleaner .Clean ()
1723
- cfgResolver .Reject (err )
1724
- return err
1727
+ log .Info ("Initializing daemon" )
1728
+
1729
+ // This validation needs to be done outside of the agent until
1730
+ // datapath.NodeAddressing is used consistently across the code base.
1731
+ log .Info ("Validating configured node address ranges" )
1732
+ if err := node .ValidatePostInit (); err != nil {
1733
+ return fmt .Errorf ("postinit failed: %w" , err )
1734
+ }
1735
+
1736
+ // Store config in file before resolving the DaemonConfig promise.
1737
+ err = option .Config .StoreInFile (option .Config .StateDir )
1738
+ if err != nil {
1739
+ log .WithError (err ).Error ("Unable to store Cilium's configuration" )
1740
+ }
1741
+
1742
+ err = option .StoreViperInFile (option .Config .StateDir )
1743
+ if err != nil {
1744
+ log .WithError (err ).Error ("Unable to store Viper's configuration" )
1725
1745
}
1726
1746
}
1727
- daemonResolver .Resolve (daemon )
1747
+
1748
+ // 'option.Config' is assumed to be stable at this point, execpt for
1749
+ // 'option.Config.Opts' that are explicitly deemed to be runtime-changeable
1728
1750
cfgResolver .Resolve (option .Config )
1751
+
1752
+ if option .Config .DryMode {
1753
+ daemonResolver .Resolve (daemon )
1754
+ } else {
1755
+ wg .Add (1 )
1756
+ go func () {
1757
+ defer wg .Done ()
1758
+ if err := startDaemon (daemon , restoredEndpoints , cleaner , params ); err != nil {
1759
+ log .WithError (err ).Error ("Daemon start failed" )
1760
+ daemonResolver .Reject (err )
1761
+ } else {
1762
+ daemonResolver .Resolve (daemon )
1763
+ }
1764
+ }()
1765
+ }
1729
1766
return nil
1730
1767
},
1731
1768
OnStop : func (cell.HookContext ) error {
@@ -1739,16 +1776,9 @@ func newDaemonPromise(params daemonParams) (promise.Promise[*Daemon], promise.Pr
1739
1776
}
1740
1777
1741
1778
// startDaemon starts the old unmodular part of the cilium-agent.
1779
+ // option.Config has already been exposed via *option.DaemonConfig promise,
1780
+ // so it may not be modified here
1742
1781
func startDaemon (d * Daemon , restoredEndpoints * endpointRestoreState , cleaner * daemonCleanup , params daemonParams ) error {
1743
- log .Info ("Initializing daemon" )
1744
-
1745
- // This validation needs to be done outside of the agent until
1746
- // datapath.NodeAddressing is used consistently across the code base.
1747
- log .Info ("Validating configured node address ranges" )
1748
- if err := node .ValidatePostInit (); err != nil {
1749
- return fmt .Errorf ("postinit failed: %w" , err )
1750
- }
1751
-
1752
1782
bootstrapStats .k8sInit .Start ()
1753
1783
if params .Clientset .IsEnabled () {
1754
1784
// Wait only for certain caches, but not all!
@@ -1911,28 +1941,28 @@ func startDaemon(d *Daemon, restoredEndpoints *endpointRestoreState, cleaner *da
1911
1941
bootstrapStats .updateMetrics ()
1912
1942
go d .launchHubble ()
1913
1943
1914
- err = option .Config .StoreInFile (option .Config .StateDir )
1915
- if err != nil {
1916
- log .WithError (err ).Error ("Unable to store Cilium's configuration" )
1917
- }
1918
-
1919
- err = option .StoreViperInFile (option .Config .StateDir )
1920
- if err != nil {
1921
- log .WithError (err ).Error ("Unable to store Viper's configuration" )
1922
- }
1923
-
1924
1944
return nil
1925
1945
}
1926
1946
1927
1947
func registerEndpointStateResolver (lc cell.Lifecycle , daemonPromise promise.Promise [* Daemon ], resolver promise.Resolver [endpointstate.Restorer ]) {
1948
+ var wg sync.WaitGroup
1949
+
1928
1950
lc .Append (cell.Hook {
1929
1951
OnStart : func (ctx cell.HookContext ) error {
1930
- daemon , err := daemonPromise .Await (context .Background ())
1931
- if err != nil {
1932
- resolver .Reject (err )
1933
- return err
1934
- }
1935
- resolver .Resolve (daemon )
1952
+ wg .Add (1 )
1953
+ go func () {
1954
+ defer wg .Done ()
1955
+ daemon , err := daemonPromise .Await (context .Background ())
1956
+ if err != nil {
1957
+ resolver .Reject (err )
1958
+ } else {
1959
+ resolver .Resolve (daemon )
1960
+ }
1961
+ }()
1962
+ return nil
1963
+ },
1964
+ OnStop : func (ctx cell.HookContext ) error {
1965
+ wg .Wait ()
1936
1966
return nil
1937
1967
},
1938
1968
})
0 commit comments