mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Keep working when there is no internet access (#77978)
* fix: make connections and plugins-catalog work when GCOM is not available * fix: remove unused import
This commit is contained in:
parent
ea2b493937
commit
ea12eecac5
@ -30,13 +30,24 @@ export async function getPluginDetails(id: string): Promise<CatalogPluginDetails
|
||||
}
|
||||
|
||||
export async function getRemotePlugins(): Promise<RemotePlugin[]> {
|
||||
// We are also fetching deprecated plugins, because we would like to be able to label plugins in the list that are both installed and deprecated.
|
||||
// (We won't show not installed deprecated plugins in the list)
|
||||
const { items: remotePlugins }: { items: RemotePlugin[] } = await getBackendSrv().get(`${GCOM_API_ROOT}/plugins`, {
|
||||
includeDeprecated: true,
|
||||
});
|
||||
try {
|
||||
const { items: remotePlugins }: { items: RemotePlugin[] } = await getBackendSrv().get(`${GCOM_API_ROOT}/plugins`, {
|
||||
// We are also fetching deprecated plugins, because we would like to be able to label plugins in the list that are both installed and deprecated.
|
||||
// (We won't show not installed deprecated plugins in the list)
|
||||
includeDeprecated: true,
|
||||
});
|
||||
|
||||
return remotePlugins.filter(isRemotePluginVisibleByConfig);
|
||||
return remotePlugins.filter(isRemotePluginVisibleByConfig);
|
||||
} catch (error) {
|
||||
if (isFetchError(error)) {
|
||||
// It can happen that GCOM is not available, in that case we show a limited set of information to the user.
|
||||
error.isHandled = true;
|
||||
console.error('Failed to fetch plugins from catalog (default https://grafana.com/api/plugins)');
|
||||
return [];
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getPluginErrors(): Promise<PluginError[]> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createAction, createAsyncThunk, Update } from '@reduxjs/toolkit';
|
||||
import { from, forkJoin, timeout, lastValueFrom, catchError, throwError, of } from 'rxjs';
|
||||
import { from, forkJoin, timeout, lastValueFrom, catchError, of } from 'rxjs';
|
||||
|
||||
import { PanelPlugin, PluginError } from '@grafana/data';
|
||||
import { config, getBackendSrv, isFetchError } from '@grafana/runtime';
|
||||
@ -27,13 +27,22 @@ export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, t
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchLocal/pending` });
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/pending` });
|
||||
|
||||
const local$ = from(getLocalPlugins());
|
||||
const remote$ = from(getRemotePlugins());
|
||||
const instance$ =
|
||||
config.pluginAdminExternalManageEnabled && configCore.featureToggles.managedPluginsInstall
|
||||
? from(getInstancePlugins())
|
||||
: of(undefined);
|
||||
const TIMEOUT = 500;
|
||||
const pluginErrors$ = from(getPluginErrors());
|
||||
const local$ = from(getLocalPlugins());
|
||||
// Unknown error while fetching remote plugins from GCOM.
|
||||
// (In this case we still operate, but only with locally available plugins.)
|
||||
const remote$ = from(getRemotePlugins()).pipe(
|
||||
catchError((err) => {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/rejected` });
|
||||
console.error(err);
|
||||
return of([]);
|
||||
})
|
||||
);
|
||||
|
||||
forkJoin({
|
||||
local: local$,
|
||||
@ -42,20 +51,14 @@ export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, t
|
||||
pluginErrors: pluginErrors$,
|
||||
})
|
||||
.pipe(
|
||||
// Fetching the list of plugins from GCOM is slow / errors out
|
||||
// Fetching the list of plugins from GCOM is slow / times out
|
||||
// (We are waiting for TIMEOUT, and if there is still no response from GCOM we continue with locally
|
||||
// installed plugins only by returning a new observable. We also still wait for the remote request to finish or
|
||||
// time out, but we don't block the main execution flow.)
|
||||
timeout({
|
||||
each: 500,
|
||||
each: TIMEOUT,
|
||||
with: () => {
|
||||
remote$
|
||||
// The request to fetch remote plugins from GCOM failed
|
||||
.pipe(
|
||||
catchError((err) => {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/rejected` });
|
||||
return throwError(
|
||||
() => new Error('Failed to fetch plugins from catalog (default https://grafana.com/api/plugins)')
|
||||
);
|
||||
})
|
||||
)
|
||||
// Remote plugins loaded after a timeout, updating the store
|
||||
.subscribe(async (remote: RemotePlugin[]) => {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/fulfilled` });
|
||||
@ -69,7 +72,7 @@ export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, t
|
||||
}
|
||||
});
|
||||
|
||||
return forkJoin({ local: local$, pluginErrors: pluginErrors$ });
|
||||
return forkJoin({ local: local$, instance: instance$, pluginErrors: pluginErrors$ });
|
||||
},
|
||||
})
|
||||
)
|
||||
@ -85,16 +88,23 @@ export const fetchAll = createAsyncThunk(`${STATE_PREFIX}/fetchAll`, async (_, t
|
||||
instance?: InstancePlugin[];
|
||||
pluginErrors: PluginError[];
|
||||
}) => {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchLocal/fulfilled` });
|
||||
|
||||
// Both local and remote plugins are loaded
|
||||
if (local && remote) {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchLocal/fulfilled` });
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/fulfilled` });
|
||||
thunkApi.dispatch(addPlugins(mergeLocalsAndRemotes({ local, remote, instance, pluginErrors })));
|
||||
|
||||
// Only remote plugins are loaded (remote timed out)
|
||||
} else if (local) {
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchLocal/fulfilled` });
|
||||
thunkApi.dispatch(addPlugins(mergeLocalsAndRemotes({ local, pluginErrors })));
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.log(error);
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchLocal/rejected` });
|
||||
thunkApi.dispatch({ type: `${STATE_PREFIX}/fetchRemote/rejected` });
|
||||
return thunkApi.rejectWithValue('Unknown error.');
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user