Compare commits
3 Commits
e686473d9a
...
b7ac6612be
Author | SHA1 | Date |
---|---|---|
wang | b7ac6612be | |
wang | df8ece4dd8 | |
wang | ce75c0484d |
|
@ -4,31 +4,12 @@ import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import io, { Socket } from "socket.io-client";
|
import io, { Socket } from "socket.io-client";
|
||||||
|
|
||||||
function base64Decode(encoded: string): string {
|
|
||||||
return atob(encoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function WebSSH() {
|
export default function WebSSH({ ip = "10.233.183.99", port = "22", password = "123456", user = "dmdba" }) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const terminalObj = useRef<HTMLDivElement | null>(null);
|
const terminalObj = useRef<HTMLDivElement | null>(null);
|
||||||
const [terminal, setTerminal] = useState<Terminal | null>(null);
|
const [terminal, setTerminal] = useState<Terminal | null>(null);
|
||||||
const [socket, setSocket] = useState<Socket | null>(null);
|
const [socket, setSocket] = useState<Socket | null>(null);
|
||||||
const [ip, setIp] = useState("");
|
|
||||||
const [port, setPort] = useState("");
|
|
||||||
const [password, setPassword] = useState("");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const params = new URLSearchParams(location.search);
|
|
||||||
const encodedIp = params.get("ip");
|
|
||||||
const encodedPort = params.get("port");
|
|
||||||
const encodedPassword = params.get("password");
|
|
||||||
|
|
||||||
if (encodedIp && encodedPort && encodedPassword) {
|
|
||||||
setIp(base64Decode(encodedIp));
|
|
||||||
setPort(base64Decode(encodedPort));
|
|
||||||
setPassword(base64Decode(encodedPassword));
|
|
||||||
}
|
|
||||||
}, [location]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (terminal === null) {
|
if (terminal === null) {
|
||||||
|
@ -69,9 +50,9 @@ export default function WebSSH() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (socket && ip && port && password) {
|
if (socket && ip && port && password) {
|
||||||
socket.emit("connect_ssh", { ip, port, password });
|
socket.emit("connect_ssh", { ip, port, password, user });
|
||||||
}
|
}
|
||||||
}, [socket, ip, port, password]);
|
}, [socket, ip, port, password, user]);
|
||||||
|
|
||||||
function pasteContent(event: React.MouseEvent) {
|
function pasteContent(event: React.MouseEvent) {
|
||||||
navigator.clipboard.readText().then((content) => {
|
navigator.clipboard.readText().then((content) => {
|
||||||
|
|
|
@ -83,7 +83,7 @@ function SendTrain(){
|
||||||
endDate
|
endDate
|
||||||
})
|
})
|
||||||
alert('发布成功')
|
alert('发布成功')
|
||||||
window.location.href='http://localhost:3000/teacher/trainmanage'
|
window.location.href='/teacher/trainmanage'
|
||||||
}catch{
|
}catch{
|
||||||
alert('SendTrainTest出错')
|
alert('SendTrainTest出错')
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,23 @@ import { max, min } from 'lodash';
|
||||||
|
|
||||||
// 首页
|
// 首页
|
||||||
function Home(){
|
function Home(){
|
||||||
const student_ID=localStorage.getItem('islogin')
|
const [isChecked,setisChecked]=useState(false)
|
||||||
if(student_ID==null){
|
//判断是否登录
|
||||||
window.location.href='http://localhost:3000/signin'
|
// useEffect(()=>{
|
||||||
alert('未登录,请先前往登录')
|
// if (!isChecked){
|
||||||
}
|
// const is_login=localStorage.getItem('islogin')
|
||||||
|
// if(!is_login){
|
||||||
|
// alert('未登录')
|
||||||
|
// window.location.href='/signin'
|
||||||
|
// }else{
|
||||||
|
// console.log(is_login);
|
||||||
|
// console.log('已登录');
|
||||||
|
// setisChecked(true)
|
||||||
|
// }
|
||||||
|
// //组件加载时自动调用login函数进行登录检测
|
||||||
|
// }
|
||||||
|
// },[]);//在组件加载时只调用一次
|
||||||
|
|
||||||
//课表数据
|
//课表数据
|
||||||
const [lesson, setLesson] = useState([]);
|
const [lesson, setLesson] = useState([]);
|
||||||
const [firstlesson, setfirstlesson] = useState([]);
|
const [firstlesson, setfirstlesson] = useState([]);
|
||||||
|
@ -36,7 +48,7 @@ function Home(){
|
||||||
setLesson(lesson_data)
|
setLesson(lesson_data)
|
||||||
}catch(error){
|
}catch(error){
|
||||||
if(student_ID.length===6){
|
if(student_ID.length===6){
|
||||||
window.location.href='http://localhost:3000/teacher'
|
window.location.href='/teacher'
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
alert('提示出错')
|
alert('提示出错')
|
||||||
|
|
|
@ -81,7 +81,7 @@ function Exam() {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
alert('考试时间到!');
|
alert('考试时间到!');
|
||||||
correct()
|
correct()
|
||||||
window.location.href='http://localhost:3000/subject'
|
window.location.href='/subject'
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
|
@ -183,7 +183,7 @@ function Exam() {
|
||||||
setCountdown(0)
|
setCountdown(0)
|
||||||
localStorage.removeItem('time')
|
localStorage.removeItem('time')
|
||||||
alert('提交成功')
|
alert('提交成功')
|
||||||
window.location.href='http://localhost:3000/subject'
|
window.location.href='/subject'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ function Operation2() {
|
||||||
localStorage.removeItem('answeredJudge')
|
localStorage.removeItem('answeredJudge')
|
||||||
localStorage.removeItem('RemainingTime')
|
localStorage.removeItem('RemainingTime')
|
||||||
alert('提交成功')
|
alert('提交成功')
|
||||||
window.location.href='http://localhost:3000/train'
|
window.location.href='/train'
|
||||||
localStorage.removeItem('TrainData')
|
localStorage.removeItem('TrainData')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,10 @@ import ClassID from '../TeacherPages/classlistpages/classId';
|
||||||
import ManageTest from '../TeacherPages/TestManage/ManageTest';
|
import ManageTest from '../TeacherPages/TestManage/ManageTest';
|
||||||
import SendTest from '../TeacherPages/TestManage/SendTest';
|
import SendTest from '../TeacherPages/TestManage/SendTest';
|
||||||
import Marking from '../TeacherPages/MarkingPages/Marking';
|
import Marking from '../TeacherPages/MarkingPages/Marking';
|
||||||
|
import SendTrain from '../TeacherPages/Trainmanage/SendTrain'
|
||||||
|
import TrainManage from '../TeacherPages/Trainmanage/Trainmanage'
|
||||||
import StudentLink from '../TeacherPages/MarkingPages/StudentLink';
|
import StudentLink from '../TeacherPages/MarkingPages/StudentLink';
|
||||||
|
import Test from '../TeacherPages/TestManage/Test.tsx'
|
||||||
|
|
||||||
|
|
||||||
import SendTrain from '../TeacherPages/Trainmanage/SendTrain';
|
import SendTrain from '../TeacherPages/Trainmanage/SendTrain';
|
||||||
|
@ -69,6 +72,7 @@ function App() {
|
||||||
<Route path="/classID/:key" element={<MainLayout headerNav={HeaderNavTeacher} />}>
|
<Route path="/classID/:key" element={<MainLayout headerNav={HeaderNavTeacher} />}>
|
||||||
<Route index element={<ClassID/>} />
|
<Route index element={<ClassID/>} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="test" element={<Test />}/>
|
||||||
|
|
||||||
{/* 页面使用单独的布局,不包含HeaderNav和HeaderNavTeacher */}
|
{/* 页面使用单独的布局,不包含HeaderNav和HeaderNavTeacher */}
|
||||||
<Route path="exam/:examId" element={<Exam />} />{/* 练习-考试页面 */}
|
<Route path="exam/:examId" element={<Exam />} />{/* 练习-考试页面 */}
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -43,9 +43,11 @@ main() {
|
||||||
build_image build-dmpython
|
build_image build-dmpython
|
||||||
build_image build-frontend
|
build_image build-frontend
|
||||||
build_image flask-app
|
build_image flask-app
|
||||||
|
build_image code-server
|
||||||
|
|
||||||
push_image flask-app
|
push_image flask-app
|
||||||
push_image base-dm
|
push_image base-dm
|
||||||
|
push_image code-server
|
||||||
|
|
||||||
echo "脚本结束"
|
echo "脚本结束"
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,3 +31,14 @@ services:
|
||||||
- '8765:8765'
|
- '8765:8765'
|
||||||
command: gunicorn -w 3 -t 60 -b 0.0.0.0:8000 app:app
|
command: gunicorn -w 3 -t 60 -b 0.0.0.0:8000 app:app
|
||||||
|
|
||||||
|
code-server:
|
||||||
|
build: ./docker/code-server
|
||||||
|
restart: always
|
||||||
|
image: code-server
|
||||||
|
depends_on:
|
||||||
|
- build-dmpython
|
||||||
|
ports:
|
||||||
|
- '8443:8443'
|
||||||
|
- '5000:5000'
|
||||||
|
- '3000:3000'
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
|
# base-dm
|
||||||
FROM base
|
FROM base
|
||||||
# 添加用户
|
# 添加用户
|
||||||
RUN useradd -m -s /bin/bash dmdba \
|
RUN useradd -m -s /bin/bash dmdba \
|
||||||
# 修改用户密码
|
# 修改用户密码
|
||||||
&& echo "dmdba:123456" | chpasswd
|
&& echo "dmdba:123456" | chpasswd \
|
||||||
|
&& apt-get -y update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
p7zip-full unzip wget \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /config/* /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
||||||
WORKDIR /home/dmdba
|
WORKDIR /home/dmdba
|
||||||
|
|
||||||
# 传入安装包并解压
|
# 下载安装包并解压
|
||||||
RUN wget https://download.dameng.com/eco/adapter/DM8/202405/dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip \
|
RUN wget https://download.dameng.com/eco/adapter/DM8/202405/dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip --no-check-certificate \
|
||||||
&& unzip dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip \
|
&& unzip dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip \
|
||||||
&& chown -R dmdba:dmdba /home/dmdba \
|
&& chown -R dmdba:dmdba /home/dmdba \
|
||||||
&& rm -f dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip \
|
&& rm -f dm8_20240408_x86_rh7_64_ent_8.1.3.140.zip \
|
||||||
&& 7z x dm8_20240408_x86_rh7_64.iso \
|
&& 7z x dm8_20240408_x86_rh7_64.iso \
|
||||||
&& rm -f dm8_20240408_x86_rh7_64.iso \
|
&& rm -f dm8_20240408_x86_rh7_64.iso \
|
||||||
&& chmod +x DMInstall.bin
|
&& chmod +x DMInstall.bin \
|
||||||
|
&& apt-get remove -y p7zip-full unzip wget
|
||||||
USER dmdba
|
USER dmdba
|
||||||
|
CMD ["/bin/bash", "-e"]
|
|
@ -1,4 +1,5 @@
|
||||||
FROM ubuntu
|
# base
|
||||||
|
FROM ubuntu:22.04
|
||||||
# apt安装时,防止卡死在交互界面
|
# apt安装时,防止卡死在交互界面
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV LANG=zh_CN.UTF-8
|
ENV LANG=zh_CN.UTF-8
|
||||||
|
@ -6,19 +7,14 @@ ENV LC_ALL=zh_CN.UTF-8
|
||||||
# 基础软件安装
|
# 基础软件安装
|
||||||
RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list \
|
RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list \
|
||||||
&& apt-get -y update && apt-get -y upgrade \
|
&& apt-get -y update && apt-get -y upgrade \
|
||||||
&& apt-get install -y python3.10-venv libssl-dev sudo vim python3-pip ssh wget unzip p7zip* language-pack-zh-hans language-selector-common locales locales-all \
|
&& apt-get install -y --no-install-recommends \
|
||||||
# 设置中文环境
|
# && apt-get install -y python3.10-venv libssl-dev sudo vim python3-pip ssh wget unzip p7zip* language-pack-zh-hans language-selector-common locales locales-all \
|
||||||
&& apt install -y $(check-language-support) \
|
ssh locales language-pack-zh-hans-base \
|
||||||
&& sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
|
&& sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
|
||||||
&& sudo sed -i 's/^UsePAM yes/UsePAM no/' /etc/ssh/sshd_config \
|
&& sed -i 's/^UsePAM yes/UsePAM no/' /etc/ssh/sshd_config \
|
||||||
&& echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen \
|
&& echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen \
|
||||||
&& sudo /usr/sbin/update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 \
|
&& /usr/sbin/update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 \
|
||||||
&& locale-gen \
|
&& locale-gen \
|
||||||
&& pip config set global.index-url https://mirrors.bfsu.edu.cn/pypi/web/simple \
|
# && pip config set global.index-url https://mirrors.bfsu.edu.cn/pypi/web/simple \
|
||||||
&& echo "**** clean up ****" && \
|
&& apt-get clean \
|
||||||
apt-get clean && \
|
&& rm -rf /config/* /tmp/* /var/lib/apt/lists/* /var/tmp/*
|
||||||
rm -rf \
|
|
||||||
/config/* \
|
|
||||||
/tmp/* \
|
|
||||||
/var/lib/apt/lists/* \
|
|
||||||
/var/tmp/*
|
|
|
@ -1,7 +1,24 @@
|
||||||
|
#build-dmpython
|
||||||
FROM base-dm
|
FROM base-dm
|
||||||
WORKDIR /home/dmdba
|
WORKDIR /home/dmdba
|
||||||
COPY auto_install.xml .
|
COPY auto_install.xml .
|
||||||
RUN ./DMInstall.bin -q /home/dmdba/auto_install.xml
|
RUN ./DMInstall.bin -q /home/dmdba/auto_install.xml \
|
||||||
|
&& rm -rf ./DMInstall.bin
|
||||||
|
USER root
|
||||||
|
RUN apt-get -y update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
python3-dev python3-pip gcc \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /config/* /tmp/* /var/lib/apt/lists/* /var/tmp/* \
|
||||||
|
&& pip3 install wheel
|
||||||
|
|
||||||
|
USER dmdba
|
||||||
# 编译
|
# 编译
|
||||||
WORKDIR /home/dmdba/dmdbms/drivers/python/dmPython
|
WORKDIR /home/dmdba/dmdbms/drivers/python/dmPython
|
||||||
RUN DM_HOME=/home/dmdba/dmdbms python3 setup.py bdist_wheel && mkdir /home/dmdba/build_artifacts && cp dist/dmPython-2.5.5-cp310-cp310-linux_x86_64.whl /home/dmdba/build_artifacts/ && cp /home/dmdba/dmdbms/bin/libdmdpi.so /home/dmdba/build_artifacts/
|
RUN DM_HOME=/home/dmdba/dmdbms python3 setup.py bdist_wheel \
|
||||||
|
&& mkdir /home/dmdba/build_artifacts \
|
||||||
|
&& mv dist/dmPython-2.5.5-cp310-cp310-linux_x86_64.whl /home/dmdba/build_artifacts/ \
|
||||||
|
&& cp /home/dmdba/dmdbms/bin/libdmdpi.so /home/dmdba/build_artifacts/
|
||||||
|
USER root
|
||||||
|
RUN apt-get remove -y python3-dev python3-pip gcc
|
||||||
|
USER dmdba
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<KEY></KEY>
|
<KEY></KEY>
|
||||||
|
|
||||||
<!--安装程序组件类型,取值范围:0、1、2,0 表示安装全部,1 表示安装服务器,2 表示安装客户端。缺省为0。 -->
|
<!--安装程序组件类型,取值范围:0、1、2,0 表示安装全部,1 表示安装服务器,2 表示安装客户端。缺省为0。 -->
|
||||||
<INSTALL_TYPE>0</INSTALL_TYPE>
|
<INSTALL_TYPE>1</INSTALL_TYPE>
|
||||||
|
|
||||||
<!--安装路径,不允许为空。 -->
|
<!--安装路径,不允许为空。 -->
|
||||||
<INSTALL_PATH>/home/dmdba/dmdbms</INSTALL_PATH>
|
<INSTALL_PATH>/home/dmdba/dmdbms</INSTALL_PATH>
|
||||||
|
|
|
@ -1,57 +1,73 @@
|
||||||
FROM ghcr.io/linuxserver/baseimage-ubuntu:jammy
|
#code-server
|
||||||
|
FROM build-dmpython
|
||||||
|
|
||||||
# set version label
|
ENV DEBIAN_FRONTEND="noninteractive"
|
||||||
ARG BUILD_DATE
|
WORKDIR /home/dmdba
|
||||||
ARG VERSION
|
USER root
|
||||||
ARG CODE_RELEASE
|
|
||||||
LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}"
|
|
||||||
LABEL maintainer="aptalca"
|
|
||||||
|
|
||||||
# environment settings
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
ARG DEBIAN_FRONTEND="noninteractive"
|
git jq libatomic1 nano net-tools netcat python3-pip nodejs npm curl sudo catatonit \
|
||||||
ENV HOME="/config"
|
cron \
|
||||||
|
curl \
|
||||||
RUN \
|
gnupg \
|
||||||
echo "**** install runtime dependencies ****" && \
|
|
||||||
apt-get update && \
|
|
||||||
apt-get install -y \
|
|
||||||
git \
|
|
||||||
jq \
|
jq \
|
||||||
libatomic1 \
|
|
||||||
nano \
|
|
||||||
net-tools \
|
|
||||||
netcat \
|
netcat \
|
||||||
# 安装python nodejs
|
tzdata \
|
||||||
python3 \
|
xz-utils \
|
||||||
python3-pip \
|
&& CODE_RELEASE=$(curl -sX GET https://api.github.com/repos/coder/code-server/releases/latest | awk '/tag_name/{print $4;exit}' FS='[""]' | sed 's|^v||') \
|
||||||
nodejs \
|
&& mkdir -p /app/code-server \
|
||||||
npm \
|
&& curl -o /tmp/code-server.tar.gz -L "https://github.com/coder/code-server/releases/download/v${CODE_RELEASE}/code-server-${CODE_RELEASE}-linux-amd64.tar.gz" \
|
||||||
sudo && \
|
&& tar xf /tmp/code-server.tar.gz -C /app/code-server --strip-components=1 \
|
||||||
echo "**** install code-server ****" && \
|
&& apt-get clean \
|
||||||
if [ -z ${CODE_RELEASE+x} ]; then \
|
&& rm -rf /tmp/* /var/lib/apt/lists/* /var/tmp/* \
|
||||||
CODE_RELEASE=$(curl -sX GET https://api.github.com/repos/coder/code-server/releases/latest \
|
&& pip3 install /home/dmdba/build_artifacts/dmPython-2.5.5-cp310-cp310-linux_x86_64.whl \
|
||||||
| awk '/tag_name/{print $4;exit}' FS='[""]' | sed 's|^v||'); \
|
&& rm /home/dmdba/build_artifacts/dmPython-2.5.5-cp310-cp310-linux_x86_64.whl
|
||||||
fi && \
|
|
||||||
mkdir -p /app/code-server && \
|
# set environment variables
|
||||||
curl -o \
|
ENV HOME="/root" \
|
||||||
/tmp/code-server.tar.gz -L \
|
LANGUAGE="en_US.UTF-8" \
|
||||||
"https://github.com/coder/code-server/releases/download/v${CODE_RELEASE}/code-server-${CODE_RELEASE}-linux-amd64.tar.gz" && \
|
LANG="en_US.UTF-8" \
|
||||||
tar xf /tmp/code-server.tar.gz -C \
|
TERM="xterm" \
|
||||||
/app/code-server --strip-components=1 && \
|
S6_CMD_WAIT_FOR_SERVICES_MAXTIME="0" \
|
||||||
echo "**** clean up ****" && \
|
S6_VERBOSITY=1 \
|
||||||
apt-get clean && \
|
S6_STAGE2_HOOK=/docker-mods \
|
||||||
rm -rf \
|
VIRTUAL_ENV=/lsiopy \
|
||||||
/config/* \
|
PATH="/lsiopy/bin:$PATH" \
|
||||||
/tmp/* \
|
HOME="/config"
|
||||||
/var/lib/apt/lists/* \
|
|
||||||
/var/tmp/*
|
# set version for s6 overlay
|
||||||
|
ARG S6_OVERLAY_VERSION="3.1.6.2"
|
||||||
|
ARG S6_OVERLAY_ARCH="x86_64"
|
||||||
|
|
||||||
|
# add s6 overlay
|
||||||
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
|
||||||
|
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
|
||||||
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz /tmp
|
||||||
|
RUN tar -C / -Jxpf /tmp/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz
|
||||||
|
|
||||||
|
# add s6 optional symlinks
|
||||||
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz /tmp
|
||||||
|
RUN tar -C / -Jxpf /tmp/s6-overlay-symlinks-noarch.tar.xz
|
||||||
|
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-arch.tar.xz /tmp
|
||||||
|
RUN tar -C / -Jxpf /tmp/s6-overlay-symlinks-arch.tar.xz && \
|
||||||
|
useradd -u 911 -U -d /config -s /bin/false abc && \
|
||||||
|
usermod -G users abc && \
|
||||||
|
mkdir -p \
|
||||||
|
/app \
|
||||||
|
/config \
|
||||||
|
/defaults \
|
||||||
|
/lsiopy
|
||||||
|
|
||||||
|
ARG MODS_VERSION="v3"
|
||||||
|
ARG PKG_INST_VERSION="v1"
|
||||||
|
ARG LSIOWN_VERSION="v1"
|
||||||
|
ADD --chmod=744 "https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/docker-mods.${MODS_VERSION}" "/docker-mods"
|
||||||
|
ADD --chmod=744 "https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/package-install.${PKG_INST_VERSION}" "/etc/s6-overlay/s6-rc.d/init-mods-package-install/run"
|
||||||
|
ADD --chmod=744 "https://raw.githubusercontent.com/linuxserver/docker-mods/mod-scripts/lsiown.${LSIOWN_VERSION}" "/usr/bin/lsiown"
|
||||||
|
|
||||||
# 安装达梦数据库
|
|
||||||
RUN mkdir -p /opt/dm8.zip && \
|
|
||||||
wget -O root/opt/dm8.zip https://download.dameng.com/eco/adapter/DM8/202401END/dm8_20240408_x86_rh7_64.zip
|
|
||||||
|
|
||||||
# add local files
|
# add local files
|
||||||
COPY /root /
|
COPY /root /
|
||||||
|
|
||||||
# ports and volumes
|
# ports and volumes
|
||||||
EXPOSE 8443
|
EXPOSE 5000 3000 8443
|
||||||
|
ENTRYPOINT ["/init"]
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
echo "[ls.io-init] done."
|
|
@ -0,0 +1,12 @@
|
||||||
|
───────────────────────────────────────
|
||||||
|
_____ __ __ _____ _____ _____ _____
|
||||||
|
| | | | __|_ _| | |
|
||||||
|
| --| | |__ | | | | | | | | |
|
||||||
|
|_____|_____|_____| |_| |_____|_|_|_|
|
||||||
|
_____ __ __ _ __ ____
|
||||||
|
| __ | | | | | | \
|
||||||
|
| __ -| | | | |__| | |
|
||||||
|
|_____|_____|_|_____|____/
|
||||||
|
|
||||||
|
Based on images from linuxserver.io
|
||||||
|
───────────────────────────────────────
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
PUID=${PUID:-911}
|
||||||
|
PGID=${PGID:-911}
|
||||||
|
|
||||||
|
groupmod -o -g "$PGID" abc
|
||||||
|
usermod -o -u "$PUID" abc
|
||||||
|
|
||||||
|
cat /etc/s6-overlay/s6-rc.d/init-adduser/branding
|
||||||
|
|
||||||
|
if [[ -f /donate.txt ]]; then
|
||||||
|
echo '
|
||||||
|
To support the app dev(s) visit:'
|
||||||
|
cat /donate.txt
|
||||||
|
fi
|
||||||
|
echo '
|
||||||
|
To support LSIO projects visit:
|
||||||
|
https://www.linuxserver.io/donate/
|
||||||
|
|
||||||
|
───────────────────────────────────────
|
||||||
|
GID/UID
|
||||||
|
───────────────────────────────────────'
|
||||||
|
echo "
|
||||||
|
User UID: $(id -u abc)
|
||||||
|
User GID: $(id -g abc)
|
||||||
|
───────────────────────────────────────
|
||||||
|
"
|
||||||
|
|
||||||
|
lsiown abc:abc /app
|
||||||
|
lsiown abc:abc /config
|
||||||
|
lsiown abc:abc /defaults
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-adduser/run
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it's just the end of the downstream image init process
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it's just the start of the downstream image init process
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
for cron_user in abc root; do
|
||||||
|
if [[ -f "/etc/crontabs/${cron_user}" ]]; then
|
||||||
|
lsiown "${cron_user}":"${cron_user}" "/etc/crontabs/${cron_user}"
|
||||||
|
crontab -u "${cron_user}" "/etc/crontabs/${cron_user}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "/defaults/crontabs/${cron_user}" ]]; then
|
||||||
|
# make folders
|
||||||
|
mkdir -p \
|
||||||
|
/config/crontabs
|
||||||
|
|
||||||
|
# if crontabs do not exist in config
|
||||||
|
if [[ ! -f "/config/crontabs/${cron_user}" ]]; then
|
||||||
|
# copy crontab from system
|
||||||
|
if crontab -l -u "${cron_user}" >/dev/null 2>&1; then
|
||||||
|
crontab -l -u "${cron_user}" >"/config/crontabs/${cron_user}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if crontabs still do not exist in config (were not copied from system)
|
||||||
|
# copy crontab from image defaults (using -n, do not overwrite an existing file)
|
||||||
|
cp -n "/defaults/crontabs/${cron_user}" /config/crontabs/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set permissions and import user crontabs
|
||||||
|
lsiown "${cron_user}":"${cron_user}" "/config/crontabs/${cron_user}"
|
||||||
|
crontab -u "${cron_user}" "/config/crontabs/${cron_user}"
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-crontab-config/run
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SCRIPTS_DIR="/custom-cont-init.d"
|
||||||
|
|
||||||
|
# Make sure custom init directory exists and has files in it
|
||||||
|
if [[ -e "${SCRIPTS_DIR}" ]] && [[ -n "$(/bin/ls -A ${SCRIPTS_DIR} 2>/dev/null)" ]]; then
|
||||||
|
echo "[custom-init] Files found, executing"
|
||||||
|
for SCRIPT in "${SCRIPTS_DIR}"/*; do
|
||||||
|
NAME="$(basename "${SCRIPT}")"
|
||||||
|
if [[ -f "${SCRIPT}" ]]; then
|
||||||
|
echo "[custom-init] ${NAME}: executing..."
|
||||||
|
/bin/bash "${SCRIPT}"
|
||||||
|
echo "[custom-init] ${NAME}: exited $?"
|
||||||
|
elif [[ ! -f "${SCRIPT}" ]]; then
|
||||||
|
echo "[custom-init] ${NAME}: is not a file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "[custom-init] No custom files found, skipping..."
|
||||||
|
fi
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-custom-files/run
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
if find /run/s6/container_environment/FILE__* -maxdepth 1 > /dev/null 2>&1; then
|
||||||
|
for FILENAME in /run/s6/container_environment/FILE__*; do
|
||||||
|
SECRETFILE=$(cat "${FILENAME}")
|
||||||
|
if [[ -f ${SECRETFILE} ]]; then
|
||||||
|
FILESTRIP=${FILENAME//FILE__/}
|
||||||
|
if [[ $(tail -n1 "${SECRETFILE}" | wc -l) != 0 ]]; then
|
||||||
|
echo "[env-init] Your secret: ${FILENAME##*/}"
|
||||||
|
echo " contains a trailing newline and may not work as expected"
|
||||||
|
fi
|
||||||
|
cat "${SECRETFILE}" >"${FILESTRIP}"
|
||||||
|
echo "[env-init] ${FILESTRIP##*/} set from ${FILENAME##*/}"
|
||||||
|
else
|
||||||
|
echo "[env-init] cannot find secret in ${FILENAME##*/}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-envfile/run
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
MIGRATIONS_DIR="/migrations"
|
||||||
|
MIGRATIONS_HISTORY="/config/.migrations"
|
||||||
|
|
||||||
|
echo "[migrations] started"
|
||||||
|
|
||||||
|
if [[ ! -d ${MIGRATIONS_DIR} ]]; then
|
||||||
|
echo "[migrations] no migrations found"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
for MIGRATION in $(find ${MIGRATIONS_DIR}/* | sort -n); do
|
||||||
|
NAME="$(basename "${MIGRATION}")"
|
||||||
|
if [[ -f ${MIGRATIONS_HISTORY} ]] && grep -Fxq "${NAME}" ${MIGRATIONS_HISTORY}; then
|
||||||
|
echo "[migrations] ${NAME}: skipped"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "[migrations] ${NAME}: executing..."
|
||||||
|
chmod +x "${MIGRATION}"
|
||||||
|
# Execute migration script in a subshell to prevent it from modifying the current environment
|
||||||
|
("${MIGRATION}")
|
||||||
|
EXIT_CODE=$?
|
||||||
|
if [[ ${EXIT_CODE} -ne 0 ]]; then
|
||||||
|
echo "[migrations] ${NAME}: failed with exit code ${EXIT_CODE}, contact support"
|
||||||
|
exit "${EXIT_CODE}"
|
||||||
|
fi
|
||||||
|
echo "${NAME}" >>${MIGRATIONS_HISTORY}
|
||||||
|
echo "[migrations] ${NAME}: succeeded"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[migrations] done"
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-migrations/run
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it's just the end of the mod init process
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
/etc/s6-overlay/s6-rc.d/init-mods-package-install/run
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it's just the start of the mod init process
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it's just the end of the mod init process
|
|
@ -0,0 +1 @@
|
||||||
|
oneshot
|
|
@ -0,0 +1 @@
|
||||||
|
# This file doesn't do anything, it just signals that services can start
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
if builtin command -v crontab >/dev/null 2>&1 && [[ -n "$(crontab -l -u abc 2>/dev/null || true)" || -n "$(crontab -l -u root 2>/dev/null || true)" ]]; then
|
||||||
|
if builtin command -v busybox >/dev/null 2>&1 && [[ $(busybox || true) =~ [[:space:]](crond)([,]|$) ]]; then
|
||||||
|
exec busybox crond -f -S -l 5
|
||||||
|
elif [[ -f /usr/bin/apt ]] && [[ -f /usr/sbin/cron ]]; then
|
||||||
|
exec /usr/sbin/cron -f -L 5
|
||||||
|
else
|
||||||
|
echo "**** cron not found ****"
|
||||||
|
sleep infinity
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
sleep infinity
|
||||||
|
fi
|
|
@ -0,0 +1 @@
|
||||||
|
longrun
|
|
@ -1,15 +1,18 @@
|
||||||
|
#flask-app
|
||||||
FROM base
|
FROM base
|
||||||
|
|
||||||
# 升级pip
|
|
||||||
RUN pip install --upgrade pip
|
|
||||||
|
|
||||||
# 创建一个用户运行flask
|
# 创建一个用户运行flask
|
||||||
RUN useradd -m -s /bin/bash flask && \
|
RUN useradd -m -s /bin/bash flask && \
|
||||||
chown -R flask:flask /home/flask && \
|
chown -R flask:flask /home/flask && \
|
||||||
mkdir -p /var/log/flask-app && touch /var/log/flask-app/flask-app.err.log && touch /var/log/flask-app/flask-app.out.log && \
|
mkdir -p /var/log/flask-app && touch /var/log/flask-app/flask-app.err.log && touch /var/log/flask-app/flask-app.out.log && \
|
||||||
chown -R flask:flask /var/log/flask-app && \
|
chown -R flask:flask /var/log/flask-app \
|
||||||
service ssh start && \
|
&& apt-get -y update \
|
||||||
service ssh restart
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
python3 python3-dev python3-pip python3-venv \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /config/* /tmp/* /var/lib/apt/lists/* /var/tmp/* \
|
||||||
|
&& pip install --upgrade pip
|
||||||
WORKDIR /home/flask
|
WORKDIR /home/flask
|
||||||
USER flask
|
USER flask
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import paramiko
|
||||||
|
|
||||||
from teacher_func import *
|
from teacher_func import *
|
||||||
from student_func import *
|
from student_func import *
|
||||||
|
from k8s_func import *
|
||||||
|
|
||||||
from flask import Flask, render_template, request, jsonify, send_from_directory, session
|
from flask import Flask, render_template, request, jsonify, send_from_directory, session
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
@ -256,13 +257,11 @@ def SendTrainTest():
|
||||||
TrainJudge=data['TrainJudge']
|
TrainJudge=data['TrainJudge']
|
||||||
Hour=data['HourValue']
|
Hour=data['HourValue']
|
||||||
Min=data['MinValue']
|
Min=data['MinValue']
|
||||||
|
StopTime=data['StopTime']
|
||||||
Class=data['selectedItems']
|
Class=data['selectedItems']
|
||||||
Train=data['Train']
|
Train=data['Train']
|
||||||
teacher_id=data['teacher_ID']
|
teacher_id=data['teacher_ID']
|
||||||
startTime=data['startDate']
|
SendTrainTestFunc(TrainChoice, TrainCompletion, TrainJudge, Hour, Min, StopTime,Class,Train,teacher_id)
|
||||||
endTime=data['endDate']
|
|
||||||
SendTrainTestFunc(TrainChoice, TrainCompletion, TrainJudge, Hour, Min,Class,Train,teacher_id,startTime,endTime)
|
|
||||||
TeacherMark(Class,teacher_id)
|
|
||||||
return '发布成功'
|
return '发布成功'
|
||||||
|
|
||||||
|
|
||||||
|
@ -271,14 +270,26 @@ def Find_details():
|
||||||
data=request.json
|
data=request.json
|
||||||
ID=data['ID']
|
ID=data['ID']
|
||||||
result=Find_details_Func(ID)
|
result=Find_details_Func(ID)
|
||||||
|
print(result)
|
||||||
return jsonify({'TestScore':result})
|
return jsonify({'TestScore':result})
|
||||||
|
@app.route("/api/teacher/list_pods") # 列出pod
|
||||||
|
def teacher_list_pods():
|
||||||
|
return list_pods()
|
||||||
|
@app.route("/api/teacher/list_services") # 列出服务
|
||||||
|
def teacher_list_services():
|
||||||
|
return list_services()
|
||||||
|
|
||||||
@app.route('/api/teacher/NotMarkTest',methods=["POST"])
|
@app.route("/api/teacher/create_pod") # 创建服务 0为项目实训, 1为安装实训
|
||||||
def NotMark():
|
def teacher_create_pod():
|
||||||
testID=request.json['testID']
|
return create_pod(1, "test")
|
||||||
result=NotMarkTest(testID)
|
|
||||||
return jsonify({'result':result})
|
|
||||||
|
|
||||||
|
@app.route("/api/teacher/delete_pod") # 删除服务
|
||||||
|
def teacher_delete_pod():
|
||||||
|
return delete_pod("test")
|
||||||
|
|
||||||
|
@app.route("/api/teacher/check_pod") # 检测数据库是否安装成功 若成功,返回OK 否则返回NO
|
||||||
|
def teacher_check_pod():
|
||||||
|
return check_dm("test")
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
@app.route('/<path:path>')
|
@app.route('/<path:path>')
|
||||||
|
@ -291,13 +302,14 @@ def handle_connect_ssh(data):
|
||||||
ip = data['ip']
|
ip = data['ip']
|
||||||
port = int(data['port'])
|
port = int(data['port'])
|
||||||
password = data['password']
|
password = data['password']
|
||||||
|
user = data['user']
|
||||||
client_id = request.sid
|
client_id = request.sid
|
||||||
|
print("connected to " + ip + " " + str(port) + " " + password)
|
||||||
ssh_client = paramiko.SSHClient()
|
ssh_client = paramiko.SSHClient()
|
||||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ssh_client.connect(ip, port=port, username='your-username', password=password)
|
ssh_client.connect(ip, port=port, username=user, password=password)
|
||||||
transport = ssh_client.get_transport()
|
transport = ssh_client.get_transport()
|
||||||
channel = transport.open_session()
|
channel = transport.open_session()
|
||||||
channel.get_pty()
|
channel.get_pty()
|
||||||
|
|
|
@ -8,12 +8,17 @@ metadata:
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: base-dm
|
- name: base-dm
|
||||||
image: harbor.dameng.io/cnsof50011836/base-dm
|
image: harbor.dameng.io/cnsof50011836/base-dm:latest
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: Always
|
||||||
|
command: [ "/bin/bash", "-c" ]
|
||||||
|
args: [ "service ssh start && tail -f /dev/null" ]
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 0
|
||||||
|
runAsGroup: 0
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: '1'
|
cpu: '1'
|
||||||
memory: 1Gi
|
memory: 1Gi
|
||||||
requests:
|
requests:
|
||||||
cpu: '0.25'
|
cpu: '0.25'
|
||||||
memory: 0.5G
|
memory: 0.5Gi
|
|
@ -0,0 +1,20 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: NAME
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: NAME
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 22
|
||||||
|
targetPort: 22
|
||||||
|
name: "ssh"
|
||||||
|
- protocol: TCP
|
||||||
|
port: 5236
|
||||||
|
targetPort: 5236
|
||||||
|
name: "dm"
|
||||||
|
type: ClusterIP
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: NAME
|
||||||
|
namespace: ""
|
||||||
|
labels:
|
||||||
|
app: NAME
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: code-server
|
||||||
|
image: harbor.dameng.io/cnsof50011836/code-server:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 0
|
||||||
|
runAsGroup: 0
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: '1'
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: '0.25'
|
||||||
|
memory: 0.5Gi
|
|
@ -0,0 +1,27 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: NAME
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: NAME
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8443
|
||||||
|
targetPort: 8443
|
||||||
|
name: "code"
|
||||||
|
appProtocol: HTTP
|
||||||
|
- protocol: TCP
|
||||||
|
port: 5000
|
||||||
|
targetPort: 5000
|
||||||
|
name: "flask"
|
||||||
|
appProtocol: HTTP
|
||||||
|
- protocol: TCP
|
||||||
|
port: 3000
|
||||||
|
targetPort: 3000
|
||||||
|
name: "frontend"
|
||||||
|
appProtocol: HTTP
|
||||||
|
type: NodePort
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
import json
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
from kubernetes import client, config
|
||||||
|
from flask import jsonify
|
||||||
|
import dmPython
|
||||||
|
# Load in-cluster config
|
||||||
|
config.load_incluster_config()
|
||||||
|
v1 = client.CoreV1Api()
|
||||||
|
namespace = open("/var/run/secrets/kubernetes.io/serviceaccount/namespace").read()
|
||||||
|
IP = "36.138.114.105"
|
||||||
|
def list_pods():
|
||||||
|
ret = v1.list_namespaced_pod(namespace, watch=False)
|
||||||
|
return {
|
||||||
|
"list": [{
|
||||||
|
"name": item.metadata.name,
|
||||||
|
"ip": item.status.pod_ip
|
||||||
|
} for item in ret.items]
|
||||||
|
}
|
||||||
|
|
||||||
|
def list_services():
|
||||||
|
ret = v1.list_namespaced_service(namespace)
|
||||||
|
return {
|
||||||
|
"list": [
|
||||||
|
item.to_dict()
|
||||||
|
for item in ret.items]
|
||||||
|
}
|
||||||
|
|
||||||
|
def create_pod(type, name):
|
||||||
|
# 读取 pod yaml 文件
|
||||||
|
with open(f"assets/type{type}-pod.yaml") as f:
|
||||||
|
pod_manifest = yaml.safe_load(f)
|
||||||
|
pod_manifest["metadata"]["name"] = name
|
||||||
|
pod_manifest["metadata"]["labels"]["app"] = name
|
||||||
|
# 创建 Pod
|
||||||
|
resp = v1.create_namespaced_pod(
|
||||||
|
body=pod_manifest,
|
||||||
|
namespace=namespace
|
||||||
|
)
|
||||||
|
print(f"pod '{resp.metadata.name}' 创建成功")
|
||||||
|
# 创建 Service
|
||||||
|
with open(f"assets/type{type}-service.yaml") as f:
|
||||||
|
service_pod = yaml.safe_load(f)
|
||||||
|
service_pod["metadata"]["name"] = name + "-service"
|
||||||
|
service_pod["spec"]["selector"]["app"] = name
|
||||||
|
|
||||||
|
resp = v1.create_namespaced_service(
|
||||||
|
body=service_pod,
|
||||||
|
namespace=namespace
|
||||||
|
)
|
||||||
|
print(f"服务 '{resp.metadata.name}' 创建成功")
|
||||||
|
if type == 1:
|
||||||
|
# 创建成功,再次查询,拿到端口
|
||||||
|
service = v1.read_namespaced_service(name=name + "-service", namespace=namespace)
|
||||||
|
print(service)
|
||||||
|
print("访问地址:" + IP + ":" + str(service.spec.ports[0].node_port))
|
||||||
|
else:
|
||||||
|
service = v1.read_namespaced_service(name=name + "-service", namespace=namespace)
|
||||||
|
print(service)
|
||||||
|
print("访问地址:" + IP + ":" + str(service.spec.ports[0].node_port))
|
||||||
|
return f"{IP} {service.spec.ports[0].node_port}"
|
||||||
|
|
||||||
|
def delete_pod(name):
|
||||||
|
v1.delete_namespaced_pod(name=name, namespace=namespace)
|
||||||
|
v1.delete_namespaced_service(name=name + "-service", namespace=namespace)
|
||||||
|
return "删除成功"
|
||||||
|
|
||||||
|
def check_dm(name):
|
||||||
|
try:
|
||||||
|
service = v1.read_namespaced_service(name=name + "-service", namespace=namespace)
|
||||||
|
db = dmPython.connect(user='SYSDBA', password='SYSDBA', host=service.spec.cluster_ip, port="5236")
|
||||||
|
cursor = db.cursor()
|
||||||
|
records = cursor.execute("SELECT * FROM V$VERSION").fetchall()
|
||||||
|
for record in records:
|
||||||
|
print(record)
|
||||||
|
return "OK"
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
return "NO"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue