feat: add more docker api
This commit is contained in:
parent
f0810cc9d9
commit
3e480da539
@ -1,4 +1,4 @@
|
|||||||
@url=https://dayu.n.yumc.pw
|
@url=https://dayu-api.miaowoo.cc
|
||||||
|
|
||||||
### System
|
### System
|
||||||
##### Info
|
##### Info
|
||||||
@ -25,11 +25,22 @@ POST {{swarm}}/init
|
|||||||
@stack={{url}}/stack
|
@stack={{url}}/stack
|
||||||
##### Stack List
|
##### Stack List
|
||||||
GET {{stack}}/list
|
GET {{stack}}/list
|
||||||
|
##### Stack Info
|
||||||
|
GET {{stack}}/faas
|
||||||
##### Stack Remove
|
##### Stack Remove
|
||||||
POST {{stack}}/develop/remove
|
POST {{stack}}/develop/remove
|
||||||
|
|
||||||
|
|
||||||
|
### Service
|
||||||
|
@service={{url}}/service
|
||||||
|
##### Service List
|
||||||
|
GET {{service}}/list
|
||||||
|
##### Service Info
|
||||||
|
GET {{service}}/3gchxsmjld0fuex216w56jl5g
|
||||||
|
##### Service Remove
|
||||||
|
POST {{service}}/develop/remove
|
||||||
|
|
||||||
|
|
||||||
### Container
|
### Container
|
||||||
@container={{url}}/container
|
@container={{url}}/container
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "npx lerna run clean",
|
"clean": "npx lerna run clean",
|
||||||
"watch": "npx lerna run watch --concurrency 10",
|
"watch": "npx lerna run watch --parallel",
|
||||||
"build": "npx lerna run build",
|
"build": "npx lerna run build",
|
||||||
"lp": "npx lerna publish"
|
"lp": "npx lerna publish"
|
||||||
},
|
},
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.0",
|
"@types/express": "^4.17.0",
|
||||||
"@types/socket.io": "^2.1.2",
|
"@types/socket.io": "^2.1.2",
|
||||||
|
"nodemon": "^1.19.1",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
"ts-node-dev": "^1.0.0-pre.40",
|
"ts-node-dev": "^1.0.0-pre.40",
|
||||||
"typescript": "^3.5.2"
|
"typescript": "^3.5.2"
|
||||||
|
19
packages/core/src/controller/service.ts
Normal file
19
packages/core/src/controller/service.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { controller, httpGet, requestParam } from 'inversify-express-utils';
|
||||||
|
import * as docker from '@dayu/docker-api'
|
||||||
|
|
||||||
|
@controller('/service')
|
||||||
|
class ServiceController {
|
||||||
|
@httpGet('/list')
|
||||||
|
public async list() {
|
||||||
|
let services = await docker.service.list();
|
||||||
|
return services.map(s => ({
|
||||||
|
id: s.ID,
|
||||||
|
name: s.Spec.Name
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@httpGet('/:id')
|
||||||
|
public async details(@requestParam('id') id: string) {
|
||||||
|
return await docker.service.inspect(id)
|
||||||
|
}
|
||||||
|
}
|
@ -6,18 +6,25 @@ const STACK_LABEL = 'com.docker.stack.namespace';
|
|||||||
@controller('/stack')
|
@controller('/stack')
|
||||||
class StackController {
|
class StackController {
|
||||||
@httpGet('/list')
|
@httpGet('/list')
|
||||||
public async list() {
|
public async list(): Promise<any> {
|
||||||
let stacks: { [key: string]: string[] } = {};
|
let stacks: { [key: string]: string[] } = {};
|
||||||
|
let result = [];
|
||||||
let services = await docker.service.list();
|
let services = await docker.service.list();
|
||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
let stackName = service.Spec.Labels[STACK_LABEL]
|
let stackName = service.Spec.Labels[STACK_LABEL]
|
||||||
if (stackName) {
|
if (stackName) {
|
||||||
let stack = stacks[stackName] || [];
|
let stack = stacks[stackName];
|
||||||
|
if (!stack) {
|
||||||
|
result.push({
|
||||||
|
name: stackName,
|
||||||
|
services: stack = []
|
||||||
|
})
|
||||||
|
stacks[stackName] = stack;
|
||||||
|
}
|
||||||
stack.push(service.Spec.Name);
|
stack.push(service.Spec.Name);
|
||||||
stacks[stackName] = stack;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stacks;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@httpGet('/:stack')
|
@httpGet('/:stack')
|
||||||
@ -31,11 +38,9 @@ class StackController {
|
|||||||
}
|
}
|
||||||
let services = await docker.service.list(filterOpt)
|
let services = await docker.service.list(filterOpt)
|
||||||
let networks = await docker.network.list(filterOpt)
|
let networks = await docker.network.list(filterOpt)
|
||||||
let containers = await docker.container.list(filterOpt);
|
|
||||||
return {
|
return {
|
||||||
services: services.map(service => service.Spec.Name),
|
services: services.map(service => service.Spec.Name),
|
||||||
networks: networks.map(network => network.Name),
|
networks: networks.map(network => network.Name),
|
||||||
containers: containers.map(container => container.Names[0].substring(1))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,4 +19,4 @@ for (let file of list) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server.static().build().start();
|
server.static().build().start(81);
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "src",
|
"baseUrl": "src",
|
||||||
"outDir": "dist"
|
"outDir": "dist",
|
||||||
|
"target": "es6",
|
||||||
|
"module": "commonjs",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"allowUnreachableCode": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cc-server/core": "^0.3.3",
|
"@cc-server/core": "^0.6.1",
|
||||||
"axios": "^0.19.0"
|
"axios": "^0.19.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
6
packages/docker-api/src/api/opts/node.ts
Normal file
6
packages/docker-api/src/api/opts/node.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import * as common from './common'
|
||||||
|
|
||||||
|
export declare namespace node {
|
||||||
|
export interface ListOpts extends common.query.FilterOpt {
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,18 @@ import { Labels } from '../common'
|
|||||||
export declare namespace swarm {
|
export declare namespace swarm {
|
||||||
type NodeAvailability = string;
|
type NodeAvailability = string;
|
||||||
|
|
||||||
|
export interface UnlockOpts {
|
||||||
|
UnlockKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JoinOpts {
|
||||||
|
ListenAddr?: string;
|
||||||
|
AdvertiseAddr?: string;
|
||||||
|
DataPathAddr?: string;
|
||||||
|
RemoteAddrs?: string[];
|
||||||
|
JoinToken?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface InitOpts {
|
export interface InitOpts {
|
||||||
ListenAddr?: string;
|
ListenAddr?: string;
|
||||||
AdvertiseAddr?: string;
|
AdvertiseAddr?: string;
|
||||||
|
@ -297,4 +297,9 @@ export declare namespace container {
|
|||||||
NetworkSettings: SummaryNetworkSettings;
|
NetworkSettings: SummaryNetworkSettings;
|
||||||
Mounts: Mount[];
|
Mounts: Mount[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ContainerPrune {
|
||||||
|
ContainersDeleted: string[];
|
||||||
|
SpaceReclaimed: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,22 @@ export namespace container {
|
|||||||
return await api.get<types.container.Container[]>('/containers/json', filters)
|
return await api.get<types.container.Container[]>('/containers/json', filters)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function info(id: string, query: { size: boolean } = { size: false }) {
|
export async function inspect(id: string, query: { size: boolean } = { size: false }) {
|
||||||
return await api.get<types.container.ContainerJSON>(`/containers/${id}/json`, query);
|
return await api.get<types.container.ContainerJSON>(`/containers/${id}/json`, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function prune() {
|
||||||
|
return api.post<types.container.ContainerPrune>('/containers/prune');
|
||||||
|
}
|
||||||
|
|
||||||
export async function logs(id: string, opts: opts.container.LogsOpts = {}): Promise<http.ServerResponse> {
|
export async function logs(id: string, opts: opts.container.LogsOpts = {}): Promise<http.ServerResponse> {
|
||||||
return await api.stream(`/containers/${id}/logs`, Object.assign({
|
let data = {
|
||||||
follow: true,
|
follow: true,
|
||||||
stdout: true,
|
stdout: true,
|
||||||
stderr: true,
|
stderr: true,
|
||||||
tail: 10
|
tail: 10,
|
||||||
}, opts));
|
...opts
|
||||||
|
}
|
||||||
|
return await api.stream(`/containers/${id}/logs`, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,7 @@ export namespace service {
|
|||||||
export async function create() {
|
export async function create() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
export async function inspect(id: string, query: { insertDefaults: boolean } = { insertDefaults: false }) {
|
||||||
|
return await api.get<any>(`/services/${id}`, query);
|
||||||
|
}
|
||||||
}
|
}
|
0
packages/docker-api/src/client/stack.ts
Normal file
0
packages/docker-api/src/client/stack.ts
Normal file
@ -10,4 +10,20 @@ export namespace swarm {
|
|||||||
export async function init(opts: opts.swarm.InitOpts) {
|
export async function init(opts: opts.swarm.InitOpts) {
|
||||||
return await api.post<string>('/swarm/init', opts);
|
return await api.post<string>('/swarm/init', opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function join(opts: opts.swarm.JoinOpts) {
|
||||||
|
return await api.post<string>('/swarm/join', opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function leave(force: boolean = false) {
|
||||||
|
return await api.post<string>(`/swarm/leave?force=${force}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function unlockkey() {
|
||||||
|
return await api.get<string>(`/swarm/unlockkey`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function unlock(opts: opts.swarm.UnlockOpts) {
|
||||||
|
return await api.post<string>(`/swarm/unlockkey`, opts);
|
||||||
|
}
|
||||||
}
|
}
|
@ -23,9 +23,9 @@ async function handle<T>(method: Method, path: string, reqConfig?: AxiosRequestC
|
|||||||
let config: AxiosRequestConfig = {
|
let config: AxiosRequestConfig = {
|
||||||
method,
|
method,
|
||||||
url: path,
|
url: path,
|
||||||
|
...reqConfig
|
||||||
};
|
};
|
||||||
let startTime = Date.now();
|
let startTime = Date.now();
|
||||||
Object.assign(config, reqConfig)
|
|
||||||
let response: AxiosResponse;
|
let response: AxiosResponse;
|
||||||
try {
|
try {
|
||||||
response = await api.request(config);
|
response = await api.request(config);
|
||||||
@ -57,10 +57,6 @@ RESPONSE BODY : ${toString.call(response.data.pipe) === "[object Function]" ?
|
|||||||
HANDLE TIME : ${Date.now() - startTime}ms
|
HANDLE TIME : ${Date.now() - startTime}ms
|
||||||
=======================================`);
|
=======================================`);
|
||||||
}
|
}
|
||||||
// console.log(`${method} ${path} HTTP/1.1
|
|
||||||
// ${config.data ? JSON.stringify(config.data, null, 2) + '\n' : ''}
|
|
||||||
// HTTP/1.1 ${response.status} ${response.statusText}
|
|
||||||
// ${config.responseType != 'stream' ? JSON.stringify(response.data, null, 2) : config.responseType}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@dayu/vscode",
|
"name": "@dayu/vscode",
|
||||||
"displayName": "vscode",
|
"displayName": "vscode",
|
||||||
"description": "",
|
"description": "Dayu VsCode Plugin",
|
||||||
"publisher": "MiaoWoo",
|
"publisher": "MiaoWoo",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -56,6 +56,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"package": "vsce package",
|
||||||
"vscode:prepublish": "yarn run compile",
|
"vscode:prepublish": "yarn run compile",
|
||||||
"compile": "tsc -p ./",
|
"compile": "tsc -p ./",
|
||||||
"watch": "tsc -watch -p ./",
|
"watch": "tsc -watch -p ./",
|
||||||
|
@ -7,6 +7,7 @@ import { OpenFaasProvider, DockerProvider } from './provider'
|
|||||||
// this method is called when your extension is activated
|
// this method is called when your extension is activated
|
||||||
// your extension is activated the very first time the command is executed
|
// your extension is activated the very first time the command is executed
|
||||||
export function activate(context: vscode.ExtensionContext) {
|
export function activate(context: vscode.ExtensionContext) {
|
||||||
|
console.log('init...')
|
||||||
new DockerProvider(context);
|
new DockerProvider(context);
|
||||||
new OpenFaasProvider(context);
|
new OpenFaasProvider(context);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export class DockerProvider extends BaseProvider<vscode.TreeItem> {
|
|||||||
context.subscriptions.push(
|
context.subscriptions.push(
|
||||||
vscode.commands.registerCommand('dayu.container.logs', (item: vscode.TreeItem) => {
|
vscode.commands.registerCommand('dayu.container.logs', (item: vscode.TreeItem) => {
|
||||||
let value: ItemContextValue = JSON.parse(item.contextValue);
|
let value: ItemContextValue = JSON.parse(item.contextValue);
|
||||||
let url = `https://faas.n.yumc.pw?action=container&data=${value.data.id}`;
|
let url = `https://dayu-api.miaowoo.cc?action=container&data=${value.data.id}`;
|
||||||
return vscode.commands.executeCommand("mini-browser.openUrl", url);
|
return vscode.commands.executeCommand("mini-browser.openUrl", url);
|
||||||
}),
|
}),
|
||||||
vscode.window.registerTreeDataProvider('docker-explorer', this)
|
vscode.window.registerTreeDataProvider('docker-explorer', this)
|
||||||
|
@ -35,7 +35,7 @@ export class OpenFaasProvider extends BaseProvider<vscode.TreeItem> {
|
|||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case Type.ROOT:
|
case Type.ROOT:
|
||||||
let funcs = await faas.getFunctions();
|
let funcs = await faas.getFunctions();
|
||||||
return funcs.map(f => {
|
return funcs.map((f: any) => {
|
||||||
return this.createTreeItem({
|
return this.createTreeItem({
|
||||||
label: f.name,
|
label: f.name,
|
||||||
tooltip: JSON.stringify(f, undefined, 2)
|
tooltip: JSON.stringify(f, undefined, 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user