Skip to content

Commit 8774d61

Browse files
authored
Concurrent update backend state
1 parent 950d13a commit 8774d61

4 files changed

Lines changed: 485 additions & 18 deletions

File tree

core/concurrent_core.go

Lines changed: 98 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
687704
func (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.
740760
func (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
17831802
func (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

17891877
func (o *ConcurrentTridentOrchestrator) RemoveBackendConfigRef(

0 commit comments

Comments
 (0)