@@ -255,14 +255,25 @@ func (o *ConcurrentTridentOrchestrator) bootstrapBackends(ctx context.Context) e
255255 backend , backendErr := o .validateAndCreateBackendFromConfig (ctx , serializedConfig , storageBackend .ConfigRef ,
256256 storageBackend .BackendUUID )
257257 if backendErr != nil {
258- Logc (ctx ).WithFields (LogFields {
259- "backend" : storageBackend .Name ,
260- "backendUUID" : storageBackend .BackendUUID ,
261- }).WithError (backendErr ).Error ("Failed to create backend from config." )
262- return backendErr
258+ Logc (ctx ).WithError (backendErr ).WithFields (LogFields {
259+ "handler" : "Bootstrap" ,
260+ "newBackendExternal" : backend ,
261+ }).Error ("Failed to create backend from config." )
262+
263+ // Trident for Docker supports one backend at a time, and the Docker volume plugin
264+ // should not start if the backend fails to initialize, so return any error here.
265+ if config .CurrentDriverContext == config .ContextDocker {
266+ return backendErr
267+ }
268+ }
269+
270+ if backend == nil {
271+ // If we couldn't create a backend, even a failed one, skip this backend.
272+ continue
263273 }
264274
265- results , unlocker , lockErr := db .Lock (ctx , db .Query (db .UpsertBackend (backend .BackendUUID (), "" , backend .Name ())))
275+ results , unlocker , lockErr := db .Lock (
276+ ctx , db .Query (db .UpsertBackend (backend .BackendUUID (), "" , backend .Name ())))
266277 if lockErr != nil {
267278 Logc (ctx ).WithFields (LogFields {
268279 "backend" : storageBackend .Name ,
@@ -272,6 +283,12 @@ func (o *ConcurrentTridentOrchestrator) bootstrapBackends(ctx context.Context) e
272283 return lockErr
273284 }
274285
286+ // Set some backend values from the persistent version that aren't in the config
287+ if storageBackend .State == storage .Deleting {
288+ backend .SetState (storage .Deleting )
289+ }
290+ backend .SetUserState (storageBackend .UserState )
291+
275292 results [0 ].Backend .Upsert (backend )
276293 unlocker ()
277294
@@ -686,7 +703,7 @@ func (o *ConcurrentTridentOrchestrator) Stop() {
686703// validateAndCreateBackendFromConfig validates config and creates backend based on Config
687704func (o * ConcurrentTridentOrchestrator ) validateAndCreateBackendFromConfig (
688705 ctx context.Context , configJSON , configRef , backendUUID string ,
689- ) (backendExternal storage.Backend , err error ) {
706+ ) (storage.Backend , error ) {
690707 var backendSecret map [string ]string
691708
692709 commonConfig , configInJSON , err := factory .ValidateCommonSettings (ctx , configJSON )
@@ -737,6 +754,9 @@ func (o *ConcurrentTridentOrchestrator) validateAndCreateBackendFromConfig(
737754 return sb , err
738755}
739756
757+ // updateUserBackendState sets the user state on an existing backend. The caller is expected
758+ // to obtain a cache lock, pass the locked backend reference in sb, and handle upserting,
759+ // unlocking and any cache errors.
740760func (o * ConcurrentTridentOrchestrator ) updateUserBackendState (
741761 ctx context.Context , sb * storage.Backend , userBackendState string , isCLI bool ,
742762) (err error ) {
@@ -771,8 +791,7 @@ func (o *ConcurrentTridentOrchestrator) updateUserBackendState(
771791 }
772792 }
773793
774- userBackendState = strings .ToLower (userBackendState )
775- newUserBackendState := storage .UserBackendState (userBackendState )
794+ newUserBackendState := storage .UserBackendState (strings .ToLower (userBackendState ))
776795
777796 // An extra check to ensure that the user-backend state is valid.
778797 if err = newUserBackendState .Validate (); err != nil {
@@ -1783,7 +1802,76 @@ func (o *ConcurrentTridentOrchestrator) validateBackendUpdate(oldBackend, newBac
17831802func (o * ConcurrentTridentOrchestrator ) UpdateBackendState (
17841803 ctx context.Context , backendName , backendState , userBackendState string ,
17851804) (storageBackendExternal * storage.BackendExternal , err error ) {
1786- return nil , fmt .Errorf ("UpdateBackendState is not implemented for concurrent core" )
1805+ ctx = GenerateRequestContextForLayer (ctx , LogLayerCore )
1806+
1807+ if o .bootstrapError != nil {
1808+ return nil , o .bootstrapError
1809+ }
1810+
1811+ defer recordTiming ("backend_update_state" , & err )()
1812+
1813+ // Extra check to ensure exactly one is set.
1814+ if (backendState == "" && userBackendState == "" ) || (backendState != "" && userBackendState != "" ) {
1815+ return nil , fmt .Errorf ("exactly one of backendState or userBackendState must be set" )
1816+ }
1817+
1818+ results , unlocker , err := db .Lock (ctx , db .Query (db .UpsertBackend ("" , backendName , "" )))
1819+ defer unlocker ()
1820+ if err != nil {
1821+ return nil , err
1822+ }
1823+
1824+ backend := results [0 ].Backend .Read
1825+ upserter := results [0 ].Backend .Upsert
1826+
1827+ if backend == nil {
1828+ return nil , errors .NotFoundError ("backend %v was not found" , backendName )
1829+ }
1830+
1831+ if userBackendState != "" {
1832+ if err = o .updateUserBackendState (ctx , & backend , userBackendState , true ); err != nil {
1833+ return nil , err
1834+ }
1835+ }
1836+ if backendState != "" {
1837+ if err = o .updateBackendState (ctx , & backend , backendState ); err != nil {
1838+ return nil , err
1839+ }
1840+ }
1841+
1842+ if err = o .storeClient .UpdateBackend (ctx , backend ); err != nil {
1843+ return nil , err
1844+ }
1845+ upserter (backend )
1846+
1847+ return backend .ConstructExternal (ctx ), nil
1848+ }
1849+
1850+ // updateBackendState sets the state on an existing backend. The caller is expected
1851+ // to obtain a cache lock, pass the locked backend reference in sb, and handle upserting,
1852+ // unlocking and any cache errors.
1853+ func (o * ConcurrentTridentOrchestrator ) updateBackendState (
1854+ ctx context.Context , sb * storage.Backend , backendState string ,
1855+ ) (err error ) {
1856+ backend := * sb
1857+ Logc (ctx ).WithFields (LogFields {
1858+ "backendName" : backend .Name (),
1859+ "backendState" : backendState ,
1860+ }).Debug ("updateBackendState" )
1861+
1862+ newBackendState := storage .BackendState (strings .ToLower (backendState ))
1863+
1864+ // Limit the command to Failed
1865+ if ! newBackendState .IsFailed () {
1866+ return fmt .Errorf ("unsupported backend state: %s" , newBackendState )
1867+ }
1868+
1869+ if ! newBackendState .IsOnline () {
1870+ backend .Terminate (ctx )
1871+ }
1872+ backend .SetState (newBackendState )
1873+
1874+ return nil
17871875}
17881876
17891877func (o * ConcurrentTridentOrchestrator ) RemoveBackendConfigRef (
0 commit comments