Bläddra i källkod

添加 docker 管理页面 Docker.vue

reghao 3 månader sedan
förälder
incheckning
d6daa8c403
3 ändrade filer med 282 tillägg och 0 borttagningar
  1. 17 0
      src/api/devops.js
  2. 9 0
      src/router/background_devops.js
  3. 256 0
      src/views/devops/machine/Docker.vue

+ 17 - 0
src/api/devops.js

@@ -7,6 +7,7 @@ const devopsApi = {
   eraseBuildDir: '/api/devops/build/dir/erase',
   getMachineList: '/api/devops/machine/host',
   getAliyunKeyList: '/api/devops/machine/aliyun/key',
+  getDockerList: '/api/devops/machine/docker',
   getEnvList: '/api/devops/envs',
   getAppTypeList: '/api/devops/app_types',
   getCompilerList: '/api/devops/build/compiler',
@@ -76,6 +77,22 @@ export function getAliyunKeyList() {
   return get(devopsApi.getAliyunKeyList)
 }
 
+export function getDockerImageList(queryInfo) {
+  return get(devopsApi.getDockerList + '/image/list', queryInfo)
+}
+
+export function deleteDockerImages(formData) {
+  return postForm(devopsApi.getDockerList + '/image/delete', formData)
+}
+
+export function getDockerContainerList() {
+  return get(devopsApi.getDockerList + '/container/list')
+}
+
+export function handleDockerContainer(formData) {
+  return postForm(devopsApi.getDockerList + '/container/ops', formData)
+}
+
 export function getEnvList() {
   return get(devopsApi.getEnvList)
 }

+ 9 - 0
src/router/background_devops.js

@@ -12,6 +12,7 @@ const User = () => import('views/devops/rbac/User')
 // machine
 const MachineHost = () => import('views/devops/machine/MachineHost')
 const AliyunKey = () => import('views/devops/machine/AliyunKey')
+const Docker = () => import('views/devops/machine/Docker')
 // build
 const BuildDir = () => import('views/devops/build/BuildDir')
 const RepoAuth = () => import('views/devops/build/RepoAuth')
@@ -89,6 +90,14 @@ export default {
           icon: 'el-icon-s-data',
           component: AliyunKey,
           meta: { needAuth: true, roles: ['devops_admin'] }
+        },
+        {
+          path: '/bg/machine/docker',
+          name: 'Docker',
+          title: 'Docker 管理',
+          icon: 'el-icon-s-data',
+          component: Docker,
+          meta: { needAuth: true, roles: ['devops_admin'] }
         }
       ]
     },

+ 256 - 0
src/views/devops/machine/Docker.vue

@@ -0,0 +1,256 @@
+<template>
+  <el-container>
+    <el-header height="220">
+      <h3>Docker 容器列表</h3>
+      <el-row style="margin-top: 10px">
+        <el-button size="mini" type="success" icon="el-icon-refresh" style="margin-left: 5px" @click="onRefresh">刷新</el-button>
+        <el-button size="mini" type="success" icon="el-icon-files" style="margin-left: 5px" @click="onGetImages">镜像列表</el-button>
+      </el-row>
+    </el-header>
+    <el-main>
+      <el-table
+        :data="dataList"
+        border
+        height="480"
+        style="width: 100%"
+      >
+        <el-table-column
+          prop="name"
+          label="容器名"
+        />
+        <el-table-column
+          prop="status"
+          label="状态"
+        />
+        <el-table-column
+          prop="createdAt"
+          label="创建时间"
+        />
+        <el-table-column
+          prop="repoTag"
+          label="依赖镜像"
+        />
+        <el-table-column
+          fixed="right"
+          label="操作"
+          width="210"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleStart(scope.$index, scope.row)"
+            >启动</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleStop(scope.$index, scope.row)"
+            >停止</el-button>
+            <el-button
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.$index, scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-main>
+
+    <el-dialog
+      title="镜像列表"
+      append-to-body
+      :visible.sync="showImageDialog"
+      width="70%"
+      center
+    >
+      <template>
+        <el-select
+          v-model="queryInfo.type"
+          size="mini"
+          style="margin-left: 5px"
+        >
+          <el-option label="关键字匹配" value="1" />
+          <el-option label="前缀匹配" value="2" />
+        </el-select>
+        <el-input
+          v-model="queryInfo.keyword"
+          size="mini"
+          style="width: 20%; padding: 3px"
+          clearable
+          placeholder="标题"
+        />
+        <el-button size="mini" type="success" icon="el-icon-search" style="margin-left: 5px" @click="onGetImages">查询</el-button>
+        <el-table
+          ref="multipleTable"
+          :data="dataList1"
+          border
+          height="480"
+          style="margin-left: 5px; width: 100%"
+          @selection-change="handleSelectionChange"
+        >
+          <el-table-column
+            type="selection"
+          />
+          <el-table-column
+            prop="repoTag"
+            label="镜像标签"
+          />
+          <el-table-column
+            prop="createdAt"
+            label="创建时间"
+          />
+          <el-table-column
+            prop="totalContainers"
+            label="使用的容器数量"
+          />
+        </el-table>
+        <el-button size="mini" type="success" icon="el-icon-minus" style="margin: 5px" @click="toggleSelection()">取消已选择</el-button>
+        <el-button size="mini" type="success" icon="el-icon-delete" style="margin: 5px" @click="deleteSelection()">删除已选择</el-button>
+      </template>
+    </el-dialog>
+  </el-container>
+</template>
+
+<script>
+import {deleteDockerImages, getDockerContainerList, getDockerImageList, handleDockerContainer} from '@/api/devops'
+
+export default {
+  name: 'Docker',
+  data() {
+    return {
+      queryInfo: {
+        type: '1',
+        keyword: ''
+      },
+      multipleSelection: [],
+      dataList: [],
+      dockerContainerList: [],
+      showImageDialog: false,
+      dataList1: []
+    }
+  },
+  created() {
+    document.title = 'Docker 列表'
+    this.getData()
+  },
+  methods: {
+    getData() {
+      this.dataList = []
+      getDockerContainerList().then(resp => {
+        if (resp.code === 0) {
+          this.dataList = resp.data
+        } else {
+          this.$message.error(resp.msg)
+        }
+      }).catch(error => {
+        this.$message.error(error.message)
+      })
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach(row => {
+          this.$refs.multipleTable.toggleRowSelection(row)
+        })
+      } else {
+        this.$refs.multipleTable.clearSelection()
+      }
+    },
+    deleteSelection() {
+      if (this.multipleSelection.length === 0) {
+        this.$message.warning('请先选择要删除的项')
+        return
+      }
+
+      const imageIds = []
+      for (const item of this.multipleSelection) {
+        imageIds.push(item.imageId)
+      }
+      this.$confirm('确定要删除选择的镜像?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        const formData = new FormData()
+        formData.append('imageIds', imageIds)
+        deleteDockerImages(formData).then(resp => {
+          this.$message.info(resp.msg)
+          this.onGetImages()
+        }).catch(error => {
+          this.$message.error(error.message)
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    handleStart(index, row) {
+      const formData = new FormData()
+      formData.append('opsType', 1)
+      formData.append('containerId', row.containerId)
+      handleDockerContainer(formData).then(resp => {
+        this.$message.info(resp.msg)
+        this.getData()
+      }).catch(error => {
+        this.$message.error(error.message)
+      })
+    },
+    handleStop(index, row) {
+      const formData = new FormData()
+      formData.append('opsType', 2)
+      formData.append('containerId', row.containerId)
+      handleDockerContainer(formData).then(resp => {
+        this.$message.info(resp.msg)
+        this.getData()
+      }).catch(error => {
+        this.$message.error(error.message)
+      })
+    },
+    handleDelete(index, row) {
+      this.$confirm('确定要删除选择的容器?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        const formData = new FormData()
+        formData.append('opsType', 3)
+        formData.append('containerId', row.containerId)
+        handleDockerContainer(formData).then(resp => {
+          this.$message.info(resp.msg)
+          this.getData()
+        }).catch(error => {
+          this.$message.error(error.message)
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
+    },
+    onRefresh() {
+      this.getData()
+    },
+    onGetImages() {
+      this.dataList1 = []
+      getDockerImageList(this.queryInfo).then(resp => {
+        if (resp.code === 0) {
+          this.dataList1 = resp.data
+          this.showImageDialog = true
+        } else {
+          this.$message.error(resp.msg)
+        }
+      }).catch(error => {
+        this.$message.error(error.message)
+      })
+    },
+  }
+}
+</script>
+
+<style>
+</style>