From dd366ca2ea5aa939490070c083135ebab3e533d4 Mon Sep 17 00:00:00 2001 From: takumi Date: Fri, 2 Oct 2020 18:40:45 +0900 Subject: [PATCH] refactor --- client/src/services/api.ts | 8 +++++- client/src/services/apiProxy.ts | 12 +++++++-- client/src/views/logs.tsx | 48 ++++++++++++++++++++++----------- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/client/src/services/api.ts b/client/src/services/api.ts index 8eacf0f..9334801 100644 --- a/client/src/services/api.ts +++ b/client/src/services/api.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; import {Base64} from 'js-base64'; -import {request, post, stream, apiFactory, apiFactoryWithNamespace} from './apiProxy'; +import { request, post, stream, apiFactory, apiFactoryWithNamespace, requestText } from './apiProxy'; import log from '../utils/log'; import { K8sEvent, Namespace, TODO, Metrics, PersistentVolume, Node, Pod, ClusterRole, ClusterRoleBinding, ConfigMap, RoleBinding, Secret, ServiceAccount, StorageClass } from '../utils/types'; @@ -40,6 +40,7 @@ const apis = { testAuth, getRules, logs, + logsAll, swagger, exec, metrics: metricsFactory(), @@ -160,6 +161,11 @@ function exec(namespace: string, name: string, container: string, cb: DataCallba return stream(url, cb, {additionalProtocols, isJson: false}); } +function logsAll(namespace: string, name: string, container: string, showPrevious: boolean) { + const url = `/api/v1/namespaces/${namespace}/pods/${name}/log?container=${container}&previous=${showPrevious}`; + return requestText(url); +} + function logs(namespace: string, name: string, container: string, tailLines: number, showPrevious: boolean, cb: DataCallback) { const items: string[] = []; const url = `/api/v1/namespaces/${namespace}/pods/${name}/log?container=${container}&previous=${showPrevious}&tailLines=${tailLines}&follow=true`; diff --git a/client/src/services/apiProxy.ts b/client/src/services/apiProxy.ts index a627f2e..00a94b0 100644 --- a/client/src/services/apiProxy.ts +++ b/client/src/services/apiProxy.ts @@ -25,7 +25,7 @@ const BASE_HTTP_URL = isDev && hostname === 'localhost' ? 'http://localhost:4654 const BASE_WS_URL = BASE_HTTP_URL.replace('http', 'ws'); const JSON_HEADERS = {Accept: 'application/json', 'Content-Type': 'application/json'}; -export async function request(path: string, params?: any, autoLogoutOnAuthError = true) { +async function requestInner(path: string, params?: any, autoLogoutOnAuthError = true) { const opts = Object.assign({headers: {}}, params); const token = getToken(); @@ -55,7 +55,15 @@ export async function request(path: string, params?: any, autoLogoutOnAuthError throw error; } - return response.json(); + return response; +} + +export async function request(path: string, params?: any, autoLogoutOnAuthError = true) { + return (await requestInner(path, params, autoLogoutOnAuthError)).json(); +} + +export async function requestText(path: string, params?: any, autoLogoutOnAuthError = true) { + return (await requestInner(path, params, autoLogoutOnAuthError)).text(); } export function apiFactory>(group: string, version: string, resource: string) { diff --git a/client/src/views/logs.tsx b/client/src/views/logs.tsx index 14ad5f9..435c94e 100644 --- a/client/src/views/logs.tsx +++ b/client/src/views/logs.tsx @@ -10,6 +10,7 @@ import Loading from '../components/loading'; import api from '../services/api'; import { Pod } from '../utils/types'; import Button from '../components/button'; +import LogsSvg from '../art/logsSvg'; type Props = { namespace: string; @@ -24,6 +25,7 @@ type State = { container?: string; initContainers?: string[]; filter?: string; + logDownloading: boolean; } export default class Logs extends Base { @@ -32,6 +34,7 @@ export default class Logs extends Base { state: State = { showPrevious: false, items: [], + logDownloading: false, }; constructor(props: Props) { @@ -87,23 +90,37 @@ export default class Logs extends Base { } startDownloadLog = () => { - const {name} = this.props; - const {items} = this.state; - const blob = new Blob(items, { - type: 'text/plain;charset=utf8', - }); - const url = window.URL.createObjectURL(blob); + const {namespace, name} = this.props; + const {container, showPrevious = false, logDownloading} = this.state; + + if (!container || logDownloading) { + return; + } + + this.setState({logDownloading: true}, () => { + api.logsAll(namespace, name, container, showPrevious).then((message) => { + const blob = new Blob([message], { + type: 'text/plain;charset=utf8', + }); + const url = window.URL.createObjectURL(blob); + + const element = document.createElement('a'); + element.setAttribute('href', url); + element.setAttribute('download', `${name}.log`); + element.click(); + window.URL.revokeObjectURL(url); + }).then(() => { + this.setState({logDownloading: false}); + }).catch(() => { + this.setState({logDownloading: false}); + }); + }); - const element = document.createElement('a'); - element.setAttribute('href', url); - element.setAttribute('download', `${name}.log`); - element.click(); - window.URL.revokeObjectURL(url); }; render() { const {namespace, name} = this.props; - const {items, container, containers = [], initContainers = [], filter = '', showPrevious = false} = this.state; + const {items, container, containers = [], initContainers = [], filter = '', showPrevious = false, logDownloading} = this.state; const lowercaseFilter = filter.toLowerCase(); const filteredLogs = items.filter(x => x.toLowerCase().includes(lowercaseFilter)); @@ -156,11 +173,12 @@ export default class Logs extends Base { />