mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-17 21:25:47 +02:00
update to 6.8.37
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public #line:13
|
||||
import os #line:14
|
||||
import time #line:15
|
||||
import projectModel .bt_docker .dk_public as dp #line:16
|
||||
import projectModel .bt_docker .dk_container as dc #line:17
|
||||
import projectModel .bt_docker .dk_setup as ds #line:18
|
||||
import json #line:19
|
||||
class main :#line:22
|
||||
compose_path ="{}/data/compose".format (public .get_panel_path ())#line:23
|
||||
__O00OO0OO00O0OO000 ="/tmp/dockertmp.log"#line:24
|
||||
def check_conf (O0OO0OO00OO0OOO00 ,O0OOOOOOO00O00O00 ):#line:27
|
||||
OOO0OOO0OOO0000O0 ="/usr/bin/docker-compose -f {} config".format (O0OOOOOOO00O00O00 )#line:28
|
||||
O0O0000OOOO0O0O0O ,OOOO00O0O00OOO0O0 =public .ExecShell (OOO0OOO0OOO0000O0 )#line:29
|
||||
if OOOO00O0O00OOO0O0 :#line:30
|
||||
return public .return_msg_gettext (False ,"Check failed:{}".format (OOOO00O0O00OOO0O0 ))#line:31
|
||||
return public .return_msg_gettext (True ,"Passed!")#line:32
|
||||
def add_template_gui (O0O0OOOOOOO00O000 ,O0000O0O0O0O00O00 ):#line:35
|
||||
""#line:69
|
||||
import yaml #line:70
|
||||
O000000OOO0O00OO0 ="{}/template".format (O0O0OOOOOOO00O000 .compose_path )#line:71
|
||||
O0O00000OO000OO0O ="{}/{}.yaml".format (O000000OOO0O00OO0 ,O0000O0O0O0O00O00 .name )#line:72
|
||||
if not os .path .exists (O000000OOO0O00OO0 ):#line:73
|
||||
os .makedirs (O000000OOO0O00OO0 )#line:74
|
||||
O000O0O000O0OOOO0 =json .loads (O0000O0O0O0O00O00 .data )#line:75
|
||||
yaml .dump (O000O0O000O0OOOO0 ,O0O00000OO000OO0O )#line:76
|
||||
def get_template_kw (O0OOO0OO0OOO0000O ,OO00OO000OOOOOOOO ):#line:78
|
||||
O0OO0OO0O00O0OO0O ={"version":"","services":{"server_name_str":{"build":{"context":"str","dockerfile":"str","args":[],"cache_from":[],"labels":[],"network":"str","shm_size":"str","target":"str"},"cap_add":"","cap_drop":"","cgroup_parent":"str","command":"str","configs":{"my_config_str":[]},"container_name":"str","credential_spec":{"file":"str","registry":"str"},"depends_on":[],"deploy":{"endpoint_mode":"str","labels":{"key":"value"},"mode":"str","placement":[{"key":"value"}],"max_replicas_per_node":"int","replicas":"int","resources":{"limits":{"cpus":"str","memory":"str",},"reservations":{"cpus":"str","memory":"str",},"restart_policy":{"condition":"str","delay":"str","max_attempts":"int","window":"str"}}}}}}#line:134
|
||||
def add_template (OO0O00000000O00OO ,O00OOOOOO0O0O0000 ):#line:137
|
||||
""#line:145
|
||||
OO00O0OO0O0O0000O =OO0O00000000O00OO .template_list (O00OOOOOO0O0O0000 )['msg']['template']#line:146
|
||||
for O0O00O000OO000OO0 in OO00O0OO0O0O0000O :#line:147
|
||||
if O00OOOOOO0O0O0000 .name ==O0O00O000OO000OO0 ['name']:#line:148
|
||||
return public .return_msg_gettext (False ,"This template name already exists!")#line:149
|
||||
OO0OOOOO0OO0O0OOO ="{}/{}/template".format (OO0O00000000O00OO .compose_path ,O00OOOOOO0O0O0000 .name )#line:150
|
||||
O00OOO00O0O0O0OOO ="{}/{}.yaml".format (OO0OOOOO0OO0O0OOO ,O00OOOOOO0O0O0000 .name )#line:151
|
||||
if not os .path .exists (OO0OOOOO0OO0O0OOO ):#line:152
|
||||
os .makedirs (OO0OOOOO0OO0O0OOO )#line:153
|
||||
public .writeFile (O00OOO00O0O0O0OOO ,O00OOOOOO0O0O0000 .data )#line:154
|
||||
OOO0000O000O0OO00 =OO0O00000000O00OO .check_conf (O00OOO00O0O0O0OOO )#line:155
|
||||
if not OOO0000O000O0OO00 ['status']:#line:156
|
||||
if os .path .exists (O00OOO00O0O0O0OOO ):#line:157
|
||||
os .remove (O00OOO00O0O0O0OOO )#line:158
|
||||
return OOO0000O000O0OO00 #line:160
|
||||
O0O0OO0O00OO00OO0 ={"name":O00OOOOOO0O0O0000 .name ,"remark":O00OOOOOO0O0O0000 .remark ,"path":O00OOO00O0O0O0OOO }#line:165
|
||||
dp .sql ("templates").insert (O0O0OO0O00OO00OO0 )#line:166
|
||||
dp .write_log ("Add template [{}] successful!".format (O00OOOOOO0O0O0000 .name ))#line:167
|
||||
return public .return_msg_gettext (True ,"Template added successfully!")#line:169
|
||||
def edit_template (OOOO00O0OOOOO0O00 ,O00O0O0O000O0O000 ):#line:171
|
||||
""#line:178
|
||||
O0O00OOO00OOOO00O =dp .sql ("templates").where ("id=?",(O00O0O0O000O0O000 .id ,)).find ()#line:179
|
||||
if not O0O00OOO00OOOO00O :#line:180
|
||||
return public .return_msg_gettext (False ,"This template was not found!")#line:181
|
||||
public .writeFile (O0O00OOO00OOOO00O ['path'],O00O0O0O000O0O000 .data )#line:182
|
||||
O0OOOO0O0000OOO0O =OOOO00O0OOOOO0O00 .check_conf (O0O00OOO00OOOO00O ['path'])#line:183
|
||||
if not O0OOOO0O0000OOO0O ['status']:#line:184
|
||||
return O0OOOO0O0000OOO0O #line:185
|
||||
OOOOO0OO00OOO000O ={"name":O0O00OOO00OOOO00O ['name'],"remark":O00O0O0O000O0O000 .remark ,"path":O0O00OOO00OOOO00O ['path']}#line:190
|
||||
dp .sql ("templates").where ("id=?",(O00O0O0O000O0O000 .id ,)).update (OOOOO0OO00OOO000O )#line:191
|
||||
dp .write_log ("Editing template [{}] succeeded!".format (O0O00OOO00OOOO00O ['name']))#line:192
|
||||
return public .return_msg_gettext (True ,"Modify the template successfully!")#line:193
|
||||
def get_template (O0O000OO00O0OO0O0 ,O0OOOO00O00O00OO0 ):#line:195
|
||||
""#line:200
|
||||
OOO0OO0OO0OO0000O =dp .sql ("templates").where ("id=?",(O0OOOO00O00O00OO0 .id ,)).find ()#line:201
|
||||
if not OOO0OO0OO0OO0000O :#line:202
|
||||
return public .return_msg_gettext (False ,"This template was not found!")#line:203
|
||||
return public .return_msg_gettext (True ,public .readFile (OOO0OO0OO0OO0000O ['path']))#line:204
|
||||
def template_list (OOO00OO000O0OOO0O ,O00O0O00OOO00O000 ):#line:206
|
||||
""#line:211
|
||||
import projectModel .bt_docker .dk_setup as ds #line:212
|
||||
OOOO0OO00OOOO0O0O =ds .main ()#line:213
|
||||
OOO0OO00OO0OO0O0O =dp .sql ("templates").select ()[::-1 ]#line:214
|
||||
if not isinstance (OOO0OO00OO0OO0O0O ,list ):#line:215
|
||||
OOO0OO00OO0OO0O0O =[]#line:216
|
||||
OOOO0O000OO0OO0O0 ={"template":OOO0OO00OO0OO0O0O ,"installed":OOOO0OO00OOOO0O0O .check_docker_program (),"service_status":OOOO0OO00OOOO0O0O .get_service_status ()}#line:221
|
||||
return public .return_msg_gettext (True ,OOOO0O000OO0OO0O0 )#line:222
|
||||
def remove_template (O0O0O0OOOOO0O000O ,OO0OO0OO00O000OOO ):#line:224
|
||||
""#line:230
|
||||
O00OO00O0OOO0000O =dp .sql ("templates").where ("id=?",(OO0OO0OO00O000OOO .template_id ,)).find ()#line:231
|
||||
if not O00OO00O0OOO0000O :#line:232
|
||||
return public .return_msg_gettext (False ,"This template was not found!")#line:233
|
||||
if os .path .exists (O00OO00O0OOO0000O ['path']):#line:234
|
||||
os .remove (O00OO00O0OOO0000O ['path'])#line:235
|
||||
dp .sql ("templates").delete (id =OO0OO0OO00O000OOO .template_id )#line:236
|
||||
dp .write_log ("Delete template [{}] successful!".format (O00OO00O0OOO0000O ['name']))#line:237
|
||||
return public .return_msg_gettext (True ,"Successfully deleted!")#line:238
|
||||
def edit_project_remark (OOO0O0000OO000000 ,OO00000OO000OOOO0 ):#line:240
|
||||
""#line:247
|
||||
O0OOOOOO000OOO0OO =dp .sql ("stacks").where ("id=?",(OO00000OO000OOOO0 .project_id ,)).find ()#line:248
|
||||
if not O0OOOOOO000OOO0OO :#line:249
|
||||
return public .return_msg_gettext (False ,"The item was not found!")#line:250
|
||||
OO0OOO00OO0OOO000 ={"remark":OO00000OO000OOOO0 .remark }#line:253
|
||||
dp .write_log ("Modify the item[{}] remarks [{}] to [{}] success!".format (O0OOOOOO000OOO0OO ['name'],O0OOOOOO000OOO0OO ['remark'],OO00000OO000OOOO0 .remark ))#line:254
|
||||
dp .sql ("stacks").where ("id=?",(OO00000OO000OOOO0 .project_id ,)).update (OO0OOO00OO0OOO000 )#line:255
|
||||
def edit_template_remark (O000000OOOOO0O000 ,OOOO0OOOO0O0O0OO0 ):#line:257
|
||||
""#line:264
|
||||
OO0OO00OOOOO0OO00 =dp .sql ("templates").where ("id=?",(OOOO0OOOO0O0O0OO0 .templates_id ,)).find ()#line:265
|
||||
if not OO0OO00OOOOO0OO00 :#line:266
|
||||
return public .return_msg_gettext (False ,"The template was not found!")#line:267
|
||||
OO0O0O0OO0OOOOOOO ={"remark":OOOO0OOOO0O0O0OO0 .remark }#line:270
|
||||
dp .write_log ("Modify the template [{}] remarks [{}] to [{}] successful!".format (OO0OO00OOOOO0OO00 ['name'],OO0OO00OOOOO0OO00 ['remark'],OOOO0OOOO0O0O0OO0 .remark ))#line:271
|
||||
dp .sql ("templates").where ("id=?",(OOOO0OOOO0O0O0OO0 .templates_id ,)).update (OO0O0O0OO0OOOOOOO )#line:272
|
||||
def create_project_in_path (OO00000O0000O0O00 ,O0OO0OOOO0000OO00 ,O000O0O0O0OO00000 ):#line:274
|
||||
OO000OO000O0O00O0 ="cd {} && /usr/bin/docker-compose -p {} up -d &> {}".format ("/".join (O000O0O0O0OO00000 .split ("/")[:-1 ]),O0OO0OOOO0000OO00 ,OO00000O0000O0O00 .__O00OO0OO00O0OO000 )#line:275
|
||||
public .ExecShell (OO000OO000O0O00O0 )#line:276
|
||||
def create_project_in_file (O00OO0O0OO0OO00OO ,O0O0O0O00O000000O ,O00000O0OOOO0OOOO ):#line:278
|
||||
O0000OO0O0O000OO0 ="{}/{}".format (O00OO0O0OO0OO00OO .compose_path ,O0O0O0O00O000000O )#line:279
|
||||
O000OO00OOOOO00OO ="{}/docker-compose.yaml".format (O0000OO0O0O000OO0 )#line:280
|
||||
if not os .path .exists (O0000OO0O0O000OO0 ):#line:281
|
||||
os .makedirs (O0000OO0O0O000OO0 )#line:282
|
||||
O00OOO000O000O000 =public .readFile (O00000O0OOOO0OOOO )#line:283
|
||||
public .writeFile (O000OO00OOOOO00OO ,O00OOO000O000O000 )#line:284
|
||||
O000O0OOOO0OO0O0O ="/usr/bin/docker-compose -p {} -f {} up -d &> {}".format (O0O0O0O00O000000O ,O000OO00OOOOO00OO ,O00OO0O0OO0OO00OO .__O00OO0OO00O0OO000 )#line:285
|
||||
public .ExecShell (O000O0OOOO0OO0O0O )#line:286
|
||||
def check_project_container_name (OOOO00OO0OOOOO0OO ,OO0OOOO0O00OO0OO0 ,OOO0OO00OO0OO00OO ):#line:288
|
||||
""#line:292
|
||||
import re #line:293
|
||||
import projectModel .bt_docker .dk_container as dc #line:294
|
||||
OO00OOOOO0O0OOOOO =[]#line:295
|
||||
O0OOOO000O00OOO0O =re .findall ("container_name\s*:\s*[\"\']+(.*)[\'\"]",OO0OOOO0O00OO0OO0 )#line:296
|
||||
O0O0OO0O00OOO0O00 =dc .main ().get_list (OOO0OO00OO0OO00OO )#line:297
|
||||
if not O0O0OO0O00OOO0O00 ["status"]:#line:298
|
||||
return public .return_msg_gettext (False ,"Error getting container list!")#line:299
|
||||
O0O0OO0O00OOO0O00 =O0O0OO0O00OOO0O00 ['msg']['container_list']#line:300
|
||||
for O0OOO0O0OO0O0OO00 in O0O0OO0O00OOO0O00 :#line:301
|
||||
if O0OOO0O0OO0O0OO00 ['name']in O0OOOO000O00OOO0O :#line:302
|
||||
OO00OOOOO0O0OOOOO .append (O0OOO0O0OO0O0OO00 ['name'])#line:303
|
||||
if OO00OOOOO0O0OOOOO :#line:304
|
||||
return public .return_msg_gettext (False ,"The container name in the template: <br>[{}] already exists!".format (", ".join (OO00OOOOO0O0OOOOO )))#line:305
|
||||
OO0000O0OO00OO0O0 ="(\d+):\d+"#line:307
|
||||
O00O00OOOO0OO00O0 =re .findall (OO0000O0OO00OO0O0 ,OO0OOOO0O00OO0OO0 )#line:308
|
||||
for O0OOO00O00O0OOOOO in O00O00OOOO0OO00O0 :#line:309
|
||||
if dp .check_socket (O0OOO00O00O0OOOOO ):#line:310
|
||||
return public .return_msg_gettext (False ,"The port [{}] in the template is already in use, please modify the server port in the template!".format (O0OOO00O00O0OOOOO ))#line:311
|
||||
def create (OO0O00O0OO00O0OO0 ,O0O0O0O00OO0OOOO0 ):#line:314
|
||||
""#line:321
|
||||
OOO00OO0O00OOOO0O =public .md5 (O0O0O0O00OO0OOOO0 .project_name )#line:322
|
||||
OO000O00O00O0000O =dp .sql ("templates").where ("id=?",(O0O0O0O00OO0OOOO0 .template_id ,)).find ()#line:323
|
||||
if not os .path .exists (OO000O00O00O0000O ['path']):#line:324
|
||||
return public .return_msg_gettext (False ,"Template file not found")#line:325
|
||||
O00O0OOOOO0OO0OOO =OO0O00O0OO00O0OO0 .check_project_container_name (public .readFile (OO000O00O00O0000O ['path']),O0O0O0O00OO0OOOO0 )#line:326
|
||||
if O00O0OOOOO0OO0OOO :#line:327
|
||||
return O00O0OOOOO0OO0OOO #line:328
|
||||
O000000O0000OOOOO =dp .sql ("stacks").where ("name=?",(OOO00OO0O00OOOO0O )).find ()#line:329
|
||||
if not O000000O0000OOOOO :#line:330
|
||||
O0OOO0OOO0O0OO0OO ={"name":O0O0O0O00OO0OOOO0 .project_name ,"status":"1","path":OO000O00O00O0000O ['path'],"template_id":O0O0O0O00OO0OOOO0 .template_id ,"time":time .time (),"remark":O0O0O0O00OO0OOOO0 .remark }#line:338
|
||||
dp .sql ("stacks").insert (O0OOO0OOO0O0OO0OO )#line:339
|
||||
else :#line:340
|
||||
return public .return_msg_gettext (False ,"This project name already exists!")#line:341
|
||||
if OO000O00O00O0000O ['add_in_path']==1 :#line:342
|
||||
OO0O00O0OO00O0OO0 .create_project_in_path (OOO00OO0O00OOOO0O ,OO000O00O00O0000O ['path'])#line:346
|
||||
else :#line:347
|
||||
OO0O00O0OO00O0OO0 .create_project_in_file (OOO00OO0O00OOOO0O ,OO000O00O00O0000O ['path'])#line:351
|
||||
dp .write_log ("Project [{}] is successfully deployed!".format (OOO00OO0O00OOOO0O ))#line:352
|
||||
return public .return_msg_gettext (True ,"Deployment succeeded!")#line:354
|
||||
def compose_project_list (OOOOOO0OO00O0OO0O ,OO0O0000O00O0O000 ):#line:370
|
||||
""#line:373
|
||||
OO0O0000O00O0O000 .url ="unix:///var/run/docker.sock"#line:374
|
||||
O0O000O0000OOO000 =dc .main ().get_list (OO0O0000O00O0O000 )#line:375
|
||||
if not O0O000O0000OOO000 ['status']:#line:376
|
||||
return public .return_msg_gettext (False ,"Failed to get the container, maybe the docker service is not started!")#line:377
|
||||
if not O0O000O0000OOO000 ['msg']['service_status']or not O0O000O0000OOO000 ['msg']['installed']:#line:378
|
||||
OO0OOO0OO00000OO0 ={"project_list":[],"template":[],"service_status":O0O000O0000OOO000 ['msg']['service_status'],"installed":O0O000O0000OOO000 ['msg']['installed']}#line:384
|
||||
return public .return_msg_gettext (True ,OO0OOO0OO00000OO0 )#line:385
|
||||
OO000O00000O00O0O =dp .sql ("stacks").select ()#line:386
|
||||
if isinstance (OO000O00000O00O0O ,list ):#line:387
|
||||
for O0OOOO0O000O00O00 in OO000O00000O00O0O :#line:388
|
||||
OOOOOO0OO00OOOO0O =[]#line:389
|
||||
for O0000OOO000000OOO in O0O000O0000OOO000 ['msg']["container_list"]:#line:390
|
||||
try :#line:391
|
||||
if 'com.docker.compose.project'not in O0000OOO000000OOO ["detail"]['Config']['Labels']:#line:392
|
||||
continue #line:393
|
||||
except :#line:394
|
||||
continue #line:395
|
||||
if O0000OOO000000OOO ["detail"]['Config']['Labels']['com.docker.compose.project']==public .md5 (O0OOOO0O000O00O00 ['name']):#line:396
|
||||
OOOOOO0OO00OOOO0O .append (O0000OOO000000OOO )#line:397
|
||||
O00OOOOO0O0OO0000 =OOOOOO0OO00OOOO0O #line:398
|
||||
O0OOOO0O000O00O00 ['container']=O00OOOOO0O0OO0000 #line:399
|
||||
else :#line:400
|
||||
OO000O00000O00O0O =[]#line:401
|
||||
OO0OOO0OO0OO00OOO =OOOOOO0OO00O0OO0O .template_list (OO0O0000O00O0O000 )#line:402
|
||||
if not OO0OOO0OO0OO00OOO ['status']:#line:403
|
||||
OO0OOO0OO0OO00OOO =list ()#line:404
|
||||
else :#line:405
|
||||
OO0OOO0OO0OO00OOO =OO0OOO0OO0OO00OOO ['msg']['template']#line:406
|
||||
OO0O0O00OOO000O0O =ds .main ()#line:407
|
||||
OO0OOO0OO00000OO0 ={"project_list":OO000O00000O00O0O ,"template":OO0OOO0OO0OO00OOO ,"service_status":OO0O0O00OOO000O0O .get_service_status (),"installed":OO0O0O00OOO000O0O .check_docker_program ()}#line:413
|
||||
return public .return_msg_gettext (True ,OO0OOO0OO00000OO0 )#line:414
|
||||
def remove (O0O0O0O0OO00OOOOO ,OOO0O00OOO0OOOO00 ):#line:417
|
||||
""#line:422
|
||||
O0OO0OOO00O000OOO =dp .sql ("stacks").where ("id=?",(OOO0O00OOO0OOOO00 .project_id ,)).find ()#line:423
|
||||
if not O0OO0OOO00O000OOO :#line:424
|
||||
return public .return_msg_gettext (True ,"The project configuration was not found!")#line:425
|
||||
OO0000000000O000O ="/usr/bin/docker-compose -p {} -f {} down &> {}".format (public .md5 (O0OO0OOO00O000OOO ['name']),O0OO0OOO00O000OOO ['path'],O0O0O0O0OO00OOOOO .__O00OO0OO00O0OO000 )#line:426
|
||||
OO0O0OOO00O00OO00 ,O00OO00O0000000O0 =public .ExecShell (OO0000000000O000O )#line:427
|
||||
dp .sql ("stacks").delete (id =OOO0O00OOO0OOOO00 .project_id )#line:428
|
||||
dp .write_log ("Delete item [{}] succeeded!".format (O0OO0OOO00O000OOO ['name']))#line:429
|
||||
return public .return_msg_gettext (True ,"Successfully deleted!")#line:430
|
||||
def stop (O0OOO0OOOOOO00O00 ,OOOO0OOO0OO00OO00 ):#line:433
|
||||
""#line:439
|
||||
O00O000O00OOO00O0 =dp .sql ("stacks").where ("id=?",(OOOO0OOO0OO00OO00 .project_id ,)).find ()#line:440
|
||||
if not O00O000O00OOO00O0 :#line:441
|
||||
return public .return_msg_gettext (True ,"The project configuration was not found!")#line:442
|
||||
OO0OO0OOO0O0O00O0 ="/usr/bin/docker-compose -p {} -f {} stop &> {}".format (public .md5 (O00O000O00OOO00O0 ['name']),O00O000O00OOO00O0 ['path'],O0OOO0OOOOOO00O00 .__O00OO0OO00O0OO000 )#line:444
|
||||
OO0O00O0000OOOOOO ,O0OO00000O0OO00O0 =public .ExecShell (OO0OO0OOO0O0O00O0 )#line:445
|
||||
dp .write_log ("Stop project [{}] succeeded!".format (O00O000O00OOO00O0 ['name']))#line:446
|
||||
return public .return_msg_gettext (True ,"Set up successfully!")#line:447
|
||||
def start (O000OO00OOO0000O0 ,O0000O000OO0OOOO0 ):#line:450
|
||||
""#line:455
|
||||
OO00O000000OO00O0 =dp .sql ("stacks").where ("id=?",(O0000O000OO0OOOO0 .project_id ,)).find ()#line:456
|
||||
if not OO00O000000OO00O0 :#line:457
|
||||
return public .return_msg_gettext (False ,"The project configuration was not found!")#line:458
|
||||
O0OO000O0OOO0OO0O ="/usr/bin/docker-compose -p {} -f {} start > {}".format (public .md5 (OO00O000000OO00O0 ['name']),OO00O000000OO00O0 ['path'],O000OO00OOO0000O0 .__O00OO0OO00O0OO000 )#line:459
|
||||
O00O000OOO00O000O ,O0O00OO0OO0OO0OOO =public .ExecShell (O0OO000O0OOO0OO0O )#line:460
|
||||
dp .write_log ("Startup project [{}] succeeded!".format (OO00O000000OO00O0 ['name']))#line:461
|
||||
return public .return_msg_gettext (True ,"Set up successfully!")#line:462
|
||||
def restart (O0OO00OO0O0OOO00O ,O000OOOOOOO00O0OO ):#line:465
|
||||
""#line:470
|
||||
OO000OOOOO0OO0O0O =dp .sql ("stacks").where ("id=?",(O000OOOOOOO00O0OO .project_id ,)).find ()#line:471
|
||||
if not OO000OOOOO0OO0O0O :#line:472
|
||||
return public .return_msg_gettext (True ,"The project configuration was not found!")#line:473
|
||||
O00O00O000OO00O0O ="/usr/bin/docker-compose -p {} -f {} restart &> {}".format (public .md5 (OO000OOOOO0OO0O0O ['name']),OO000OOOOO0OO0O0O ['path'],O0OO00OO0O0OOO00O .__O00OO0OO00O0OO000 )#line:474
|
||||
O00OO0000O0000OO0 ,O0OOOOO000OO0O0O0 =public .ExecShell (O00O00O000OO00O0O )#line:475
|
||||
dp .write_log ("Restart the project [{}] successfully!".format (OO000OOOOO0OO0O0O ['name']))#line:476
|
||||
return public .return_msg_gettext (True ,"Set up successfully!")#line:477
|
||||
def pull (OOO0OO00O0OO00OO0 ,OO0OOOOOO00000OO0 ):#line:480
|
||||
""#line:485
|
||||
O0OO0OO0OO0O0OOO0 =dp .sql ("templates").where ("id=?",(OO0OOOOOO00000OO0 .template_id ,)).find ()#line:486
|
||||
if not O0OO0OO0OO0O0OOO0 :#line:487
|
||||
return public .return_msg_gettext (True ,"The template was not found!")#line:488
|
||||
O0OOOO0O000O0O000 ="/usr/bin/docker-compose -p {} -f {} pull &> {}".format (O0OO0OO0OO0O0OOO0 ['name'],O0OO0OO0OO0O0OOO0 ['path'],OOO0OO00O0OO00OO0 .__O00OO0OO00O0OO000 )#line:489
|
||||
O0O00OOO0O0O0OO00 ,OO000OOO0O000OOO0 =public .ExecShell (O0OOOO0O000O0O000 )#line:490
|
||||
dp .write_log ("The mirror image of the template [{}] was pulled successfully!".format (O0OO0OO0OO0O0OOO0 ['name']))#line:491
|
||||
return public .return_msg_gettext (True ,"Pull success!")#line:492
|
||||
def pause (OOO00O0OO00O00O0O ,O0OOOOO000OO0000O ):#line:495
|
||||
""#line:500
|
||||
OO0O0000OOO000O00 =dp .sql ("stacks").where ("id=?",(O0OOOOO000OO0000O .project_id ,)).find ()#line:501
|
||||
if not OO0O0000OOO000O00 :#line:502
|
||||
return public .return_msg_gettext (True ,"The project configuration was not found!")#line:503
|
||||
O0O0OOO0000O0O00O ="/usr/bin/docker-compose -p {} -f {} pause &> {}".format (public .md5 (OO0O0000OOO000O00 ['name']),OO0O0000OOO000O00 ['path'],OOO00O0OO00O00O0O .__O00OO0OO00O0OO000 )#line:504
|
||||
O0000OO0OOO00OOOO ,O0O0O0OOO0O0O0OOO =public .ExecShell (O0O0OOO0000O0O00O )#line:505
|
||||
dp .write_log ("Pause [{}] success!".format (OO0O0000OOO000O00 ['name']))#line:506
|
||||
return public .return_msg_gettext (True ,"Set up successfully!")#line:507
|
||||
def unpause (O0O0O0OOO00OOOO00 ,O0O00O000OOO00OO0 ):#line:510
|
||||
""#line:515
|
||||
OO0O0OO00OOO00O00 =dp .sql ("stacks").where ("id=?",(O0O00O000OOO00OO0 .project_id ,)).find ()#line:516
|
||||
if not OO0O0OO00OOO00O00 :#line:517
|
||||
return public .return_msg_gettext (True ,"The project configuration was not found!")#line:518
|
||||
OOO00O00OOOO0OO00 ="/usr/bin/docker-compose -p {} -f {} unpause &> {}".format (public .md5 (OO0O0OO00OOO00O00 ['name']),OO0O0OO00OOO00O00 ['path'],O0O0O0OOO00OOOO00 .__O00OO0OO00O0OO000 )#line:519
|
||||
O00000OOO000OOO0O ,O00OO00O0O0O00OO0 =public .ExecShell (OOO00O00OOOO0OO00 )#line:520
|
||||
dp .write_log ("Unsuspended project [{}] succeeded!".format (OO0O0OO00OOO00O00 ['name']))#line:521
|
||||
return public .return_msg_gettext (True ,"Set up successfully!")#line:522
|
||||
def scan_compose_file (OOO000OO000OOOOOO ,O00000OOO00O00OOO ,O000O00O0OOO0O0OO ):#line:525
|
||||
""#line:531
|
||||
O0OOOO0O00OOO00O0 =os .listdir (O00000OOO00O00OOO )#line:532
|
||||
for OO00000OOO00OOOO0 in O0OOOO0O00OOO00O0 :#line:533
|
||||
OO0O0OO00OO0OO000 =os .path .join (O00000OOO00O00OOO ,OO00000OOO00OOOO0 )#line:534
|
||||
if os .path .isdir (OO0O0OO00OO0OO000 ):#line:536
|
||||
OOO000OO000OOOOOO .scan_compose_file (OO0O0OO00OO0OO000 ,O000O00O0OOO0O0OO )#line:537
|
||||
else :#line:538
|
||||
if OO00000OOO00OOOO0 =="docker-compose.yaml"or OO00000OOO00OOOO0 =="docker-compose.yam"or OO00000OOO00OOOO0 =="docker-compose.yml":#line:539
|
||||
if "/www/server/panel/data/compose"in OO0O0OO00OO0OO000 :#line:540
|
||||
continue #line:541
|
||||
O000O00O0OOO0O0OO .append (OO0O0OO00OO0OO000 )#line:542
|
||||
return O000O00O0OOO0O0OO #line:543
|
||||
def get_compose_project (OOO000O00OO000OO0 ,O0OOOO0OOOOO0000O ):#line:546
|
||||
""#line:552
|
||||
O0O0OO00OO0000O0O =list ()#line:553
|
||||
if O0OOOO0OOOOO0000O .path =="/":#line:554
|
||||
return public .return_msg_gettext (False ,"Can't start scanning from root directory!")#line:555
|
||||
if O0OOOO0OOOOO0000O .path [-1 ]=="/":#line:556
|
||||
O0OOOO0OOOOO0000O .path =O0OOOO0OOOOO0000O .path [:-1 ]#line:557
|
||||
if str (O0OOOO0OOOOO0000O .sub_dir )=="1":#line:558
|
||||
O000OOOO0OO00OOOO =OOO000O00OO000OO0 .scan_compose_file (O0OOOO0OOOOO0000O .path ,O0O0OO00OO0000O0O )#line:559
|
||||
if not O000OOOO0OO00OOOO :#line:560
|
||||
O000OOOO0OO00OOOO =[]#line:561
|
||||
else :#line:562
|
||||
O00O0O0OOO0OO0O00 =list ()#line:563
|
||||
for O0O00O0O0OOOO000O in O000OOOO0OO00OOOO :#line:564
|
||||
O00O0O0OOO0OO0O00 .append ({"project_name":O0O00O0O0OOOO000O .split ("/")[-2 ],"conf_file":"/".join (O0O00O0O0OOOO000O .split ("/")),"remark":"Add by local path"})#line:571
|
||||
O000OOOO0OO00OOOO =O00O0O0OOO0OO0O00 #line:572
|
||||
else :#line:573
|
||||
O00O0O00O00O0000O ="{}/docker-compose.yaml".format (O0OOOO0OOOOO0000O .path )#line:574
|
||||
OOO00OOO00O0O0OOO ="{}/docker-compose.yam".format (O0OOOO0OOOOO0000O .path )#line:575
|
||||
if os .path .exists (O00O0O00O00O0000O ):#line:576
|
||||
O000OOOO0OO00OOOO =[{"project_name":O0OOOO0OOOOO0000O .path .split ("/")[-1 ],"conf_file":O00O0O00O00O0000O ,"remark":"Add by local path"}]#line:581
|
||||
elif os .path .exists (OOO00OOO00O0O0OOO ):#line:582
|
||||
O000OOOO0OO00OOOO =[{"project_name":O0OOOO0OOOOO0000O .path .split ("/")[-1 ],"conf_file":OOO00OOO00O0O0OOO ,"remark":"Add by local path"}]#line:587
|
||||
else :#line:588
|
||||
O000OOOO0OO00OOOO =list ()#line:589
|
||||
return O000OOOO0OO00OOOO #line:591
|
||||
def add_template_in_path (O0O00000O0OO00OO0 ,OOO0OO0OO0O00O00O ):#line:594
|
||||
""#line:599
|
||||
OO0O000OO000O0OO0 =dict ()#line:600
|
||||
OO00OOO00000OOOOO =dict ()#line:601
|
||||
for OO0OO0OOO00O0OO00 in OOO0OO0OO0O00O00O .template_list :#line:602
|
||||
O0O0OO00O00O00000 =OO0OO0OOO00O0OO00 ['conf_file']#line:603
|
||||
O00O000OOOO0O00OO =OO0OO0OOO00O0OO00 ['project_name']#line:604
|
||||
OOOOO00O00O0O0OO0 =OO0OO0OOO00O0OO00 ['remark']#line:605
|
||||
O00O0O0O000O00O00 =O0O00000O0OO00OO0 .template_list (OOO0OO0OO0O00O00O )['msg']['template']#line:606
|
||||
for O00O0O0OOO0O0OOOO in O00O0O0O000O00O00 :#line:607
|
||||
if O00O000OOOO0O00OO ==O00O0O0OOO0O0OOOO ['name']:#line:608
|
||||
OO0O000OO000O0OO0 [O00O000OOOO0O00OO ]="Template already exists!"#line:609
|
||||
continue #line:610
|
||||
if not os .path .exists (O0O0OO00O00O00000 ):#line:612
|
||||
OO0O000OO000O0OO0 [O00O000OOOO0O00OO ]="The template was not found!"#line:613
|
||||
continue #line:614
|
||||
O000O0O0OOO00000O =O0O00000O0OO00OO0 .check_conf (O0O0OO00O00O00000 )#line:616
|
||||
if not O000O0O0OOO00000O ['status']:#line:617
|
||||
OO0O000OO000O0OO0 [O00O000OOOO0O00OO ]="Template validation failed, possibly malformed!"#line:618
|
||||
continue #line:619
|
||||
OO0OOO0OOOOO0O00O ={"name":O00O000OOOO0O00OO ,"remark":OOOOO00O00O0O0OO0 ,"path":O0O0OO00O00O00000 ,"add_in_path":1 }#line:626
|
||||
print (OO0OOO0OOOOO0O00O )#line:627
|
||||
dp .sql ("templates").insert (OO0OOO0OOOOO0O00O )#line:628
|
||||
OO00OOO00000OOOOO [O00O000OOOO0O00OO ]="Template added successfully!"#line:629
|
||||
print (OO0O000OO000O0OO0 )#line:631
|
||||
for O00O0O0OOO0O0OOOO in OO0O000OO000O0OO0 :#line:632
|
||||
if O00O0O0OOO0O0OOOO in OO00OOO00000OOOOO :#line:633
|
||||
del (OO00OOO00000OOOOO [O00O0O0OOO0O0OOOO ])#line:634
|
||||
else :#line:635
|
||||
dp .write_log ("Add template [{}] from path successfully!".format (O00O0O0OOO0O0OOOO ))#line:636
|
||||
if not OO0O000OO000O0OO0 and OO00OOO00000OOOOO :#line:637
|
||||
return {'status':True ,'msg':'Add template successfully: [{}]'.format (','.join (OO00OOO00000OOOOO ))}#line:638
|
||||
elif not OO00OOO00000OOOOO and OO0O000OO000O0OO0 :#line:639
|
||||
return {'status':True ,'msg':'Failed to add template: template name already exists or format validation error [{}]'.format (','.join (OO0O000OO000O0OO0 ))}#line:640
|
||||
return {'status':True ,'msg':'Add template successfully: [{}]<br>Add template failed: template name already exists or format validation error [{}]'.format (','.join (OO00OOO00000OOOOO ),','.join (OO0O000OO000O0OO0 ))}#line:641
|
||||
@@ -0,0 +1,473 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public
|
||||
import docker.errors
|
||||
import projectModel.bt_docker.dk_public as dp
|
||||
class main:
|
||||
|
||||
def __init__(self):
|
||||
self.alter_table()
|
||||
|
||||
def alter_table(self):
|
||||
if not dp.sql('sqlite_master').where('type=? AND name=? AND sql LIKE ?',
|
||||
('table', 'container', '%sid%')).count():
|
||||
dp.sql('container').execute("alter TABLE container add container_name VARCHAR DEFAULT ''", ())
|
||||
|
||||
def docker_client(self,url):
|
||||
return dp.docker_client(url)
|
||||
|
||||
# 添加容器
|
||||
def run(self,args):
|
||||
"""
|
||||
:param name:容器名
|
||||
:param image: 镜像
|
||||
:param publish_all_ports 暴露所有端口 1/0
|
||||
:param ports 暴露某些端口 {'1111/tcp': ('127.0.0.1', 1111)}
|
||||
:param command 命令
|
||||
:param entrypoint 配置容器启动后执行的命令
|
||||
:param environment 环境变量 xxx=xxx 一行一条
|
||||
:param auto_remove 当容器进程退出时,在守护进程端启用自动移除容器。 0/1
|
||||
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
if not hasattr(args,'ports'):
|
||||
args.ports = False
|
||||
if not hasattr(args,'volumes'):
|
||||
args.volumes = False
|
||||
#检测端口是否已经在使用
|
||||
if args.ports:
|
||||
for i in args.ports:
|
||||
if dp.check_socket(args.ports[i]):
|
||||
return public.returnMsg(False,"The server port [{}] has been used, please replace it with another port!".format(args.ports[i]))
|
||||
if not args.image:
|
||||
return public.returnMsg(False, "If there is no image selected, please go to the image tab to pull the image you need!")
|
||||
if args.restart_policy['Name'] == "always":
|
||||
args.restart_policy = {"Name":"always"}
|
||||
# return args.restart_policy
|
||||
# if
|
||||
args.cpu_quota = float(args.cpuset_cpus) * 100000
|
||||
# if not args.volumes:
|
||||
# args.volumes = {"/sys/fs/cgroup":{"bind":"/sys/fs/cgroup","mode":"rw"}}
|
||||
# else:
|
||||
# if not "/sys/fs/cgroup" in args.volumes:
|
||||
# args.volumes['/sys/fs/cgroup'] = {"bind":"/sys/fs/cgroup","mode":"rw"}
|
||||
try:
|
||||
if not args.name:
|
||||
args.name = "{}-{}".format(args.image,public.GetRandomString(8))
|
||||
if int(args.cpu_quota) / 100000 > dp.get_cpu_count():
|
||||
return public.returnMsg(False,"The CPU quota has exceeded the number of cores available!")
|
||||
mem_limit_byte = dp.byte_conversion(args.mem_limit)
|
||||
if mem_limit_byte > dp.get_mem_info():
|
||||
return public.returnMsg(False, "The memory quota has exceeded the available number!")
|
||||
res = self.docker_client(args.url).containers.run(
|
||||
name=args.name,
|
||||
image=args.image,
|
||||
detach=True,
|
||||
publish_all_ports=True if args.publish_all_ports == "1" else False,
|
||||
ports=args.ports if args.ports else None,
|
||||
command=args.command,
|
||||
auto_remove=True if str(args.auto_remove) == "1" else False,
|
||||
environment=dp.set_kv(args.environment), #"HOME=/value\nHOME11=value1"
|
||||
volumes=args.volumes, #一个字典对象 {'服务器路径/home/user1/': {'bind': '容器路径/mnt/vol2', 'mode': 'rw'},'/var/www': {'bind': '/mnt/vol1', 'mode': 'ro'}}
|
||||
# cpuset_cpus=args.cpuset_cpus ,#指定容器使用的cpu个数
|
||||
cpu_quota=int(args.cpu_quota),
|
||||
mem_limit=args.mem_limit, #b,k,m,g
|
||||
restart_policy=args.restart_policy,
|
||||
labels=dp.set_kv(args.labels), #"key=value\nkey1=value1"
|
||||
tty=True,
|
||||
stdin_open=True,
|
||||
privileged=True
|
||||
|
||||
)
|
||||
if res:
|
||||
pdata = {
|
||||
"cpu_limit": str(args.cpu_quota),
|
||||
"container_name": args.name
|
||||
}
|
||||
dp.sql('container').insert(pdata)
|
||||
public.set_module_logs('docker', 'run_container', 1)
|
||||
dp.write_log("Create container [{}] successful!".format(args.name))
|
||||
return public.returnMsg(True,"The container was created successfully!")
|
||||
return public.returnMsg(False, 'Create failed!')
|
||||
except docker.errors.APIError as e:
|
||||
if "container to be able to reuse that name." in str(e):
|
||||
return public.returnMsg(False, "The container name already exists!")
|
||||
if "Invalid container name" in str(e):
|
||||
return public.returnMsg(False, "The container name is illegal, please do not use Chinese container name!")
|
||||
if "bind: address already in use" in str(e):
|
||||
port = ""
|
||||
for i in args.ports:
|
||||
if ":{}:".format(args.ports[i]) in str(e):
|
||||
port = args.ports[i]
|
||||
args.id = args.name
|
||||
self.del_container(args)
|
||||
return public.returnMsg(False, "Server port {} is in use! Please change other ports".format(port))
|
||||
return public.returnMsg(False, 'Create failed! {}'.format(public.get_error_info()))
|
||||
|
||||
# 保存为镜像
|
||||
def commit(self,args):
|
||||
"""
|
||||
:param repository 推送到的仓库
|
||||
:param tag 镜像标签 jose:v1
|
||||
:param message 提交的信息
|
||||
:param author 镜像作者
|
||||
:param changes
|
||||
:param conf dict
|
||||
:param path 导出路径
|
||||
:param name 导出文件名
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
if not hasattr(args,'conf') or not args.conf:
|
||||
args.conf = None
|
||||
if args.repository == "docker.io":
|
||||
args.repository = ""
|
||||
container = self.docker_client(args.url).containers.get(args.id)
|
||||
container.commit(
|
||||
repository=args.repository if args.repository else None,
|
||||
tag=args.tag if args.tag else None,
|
||||
message=args.message if args.message else None,
|
||||
author=args.author if args.author else None,
|
||||
# changes=args.changes if args.changes else None,
|
||||
conf=args.conf
|
||||
)
|
||||
if hasattr(args,"path") and args.path:
|
||||
args.id = "{}:{}".format(args.name,args.tag)
|
||||
import projectModel.bt_docker.dk_image as dk
|
||||
return dk.main().save(args)
|
||||
dp.write_log("Submitting container [{}] as image [{}] succeeded!".format(container.attrs['Name'],args.tag))
|
||||
return public.returnMsg(True,"提交成功!")
|
||||
|
||||
# 容器执行命令
|
||||
def docker_shell(self, args):
|
||||
"""
|
||||
:param container_id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
self.docker_client(args.url).containers.get(args.container_id)
|
||||
cmd = 'docker container exec -it {} /bin/bash'.format(args.container_id)
|
||||
return public.returnMsg(True, cmd)
|
||||
except docker.errors.APIError as ex:
|
||||
return public.returnMsg(False, 'Failed to get container')
|
||||
|
||||
# 导出容器为tar 没有导入方法,目前弃用
|
||||
def export(self,args):
|
||||
"""
|
||||
:param path 保存路径
|
||||
:param name 包名
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
from os import path as ospath
|
||||
from os import makedirs as makedirs
|
||||
try:
|
||||
if "tar" in args.name:
|
||||
file_name = '{}/{}'.format(args.path,args.name)
|
||||
else:
|
||||
file_name = '{}/{}.tar'.format(args.path, args.name)
|
||||
if not ospath.exists(args.path):
|
||||
makedirs(args.path)
|
||||
public.writeFile(file_name,'')
|
||||
f = open(file_name, 'wb')
|
||||
container = self.docker_client(args.url).containers.get(args.id)
|
||||
data = container.export()
|
||||
for i in data:
|
||||
f.write(i)
|
||||
f.close()
|
||||
return public.returnMsg(True, "Successfully exported to: {}".format(file_name))
|
||||
except:
|
||||
return public.returnMsg(False, 'Operation failed:' + str(public.get_error_info()))
|
||||
|
||||
# 删除容器
|
||||
def del_container(self,args):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
import projectModel.bt_docker.dk_public as dp
|
||||
container = self.docker_client(args.url).containers.get(args.id)
|
||||
container.remove(force=True)
|
||||
dp.sql("cpu_stats").where("container_id=?", (args.id,)).delete()
|
||||
dp.sql("io_stats").where("container_id=?", (args.id,)).delete()
|
||||
dp.sql("mem_stats").where("container_id=?", (args.id,)).delete()
|
||||
dp.sql("net_stats").where("container_id=?", (args.id,)).delete()
|
||||
dp.sql("container").where("container_nam=?", (container.attrs['Name'])).delete()
|
||||
dp.write_log("Delete container [{}] succeeded!".format(container.attrs['Name']))
|
||||
return public.returnMsg(True,"Successfully deleted!")
|
||||
|
||||
# 设置容器状态
|
||||
def set_container_status(self,args):
|
||||
import time
|
||||
container = self.docker_client(args.url).containers.get(args.id)
|
||||
if args.act == "start":
|
||||
container.start()
|
||||
elif args.act == "stop":
|
||||
container.stop()
|
||||
elif args.act == "pause":
|
||||
container.pause()
|
||||
elif args.act == "unpause":
|
||||
container.unpause()
|
||||
elif args.act == "reload":
|
||||
container.reload()
|
||||
else:
|
||||
container.restart()
|
||||
time.sleep(1)
|
||||
tmp = self.docker_client(args.url).containers.get(args.id)
|
||||
return {"name":container.attrs['Name'].replace('/',''),"status":tmp.attrs['State']['Status']} #返回设置后的状态
|
||||
|
||||
|
||||
# 停止容器
|
||||
def stop(self,args):
|
||||
"""
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
args.act = "stop"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "exited":
|
||||
return public.returnMsg(False, "Stop failing!")
|
||||
dp.write_log("Stop container [{}] succeeded!".format(data['name']))
|
||||
return public.returnMsg(True, "Stop success!")
|
||||
except docker.errors.APIError as e:
|
||||
if "is already paused" in str(e):
|
||||
return public.returnMsg(False,"The container has been suspended!")
|
||||
if "No such container" in str(e):
|
||||
return public.returnMsg(True, "The container has been stopped and deleted because the container has the option to automatically delete after stopping!")
|
||||
return public.returnMsg(False,"Stop failing!{}".format(e))
|
||||
|
||||
def start(self,args):
|
||||
"""
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
args.act = "start"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "running":
|
||||
return public.returnMsg(False, "Startup failed!")
|
||||
dp.write_log("Start the container [{}] successfully!".format(data['name']))
|
||||
return public.returnMsg(True, "Started successfully!")
|
||||
except docker.errors.APIError as e:
|
||||
if "cannot start a paused container, try unpause instead" in str(e):
|
||||
return self.unpause(args)
|
||||
|
||||
def pause(self,args):
|
||||
"""
|
||||
Pauses all processes within this container.
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
args.act = "pause"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "paused":
|
||||
return public.returnMsg(False, "Container pause failed!")
|
||||
dp.write_log("Suspended container [{}] succeeded!".format(data['name']))
|
||||
return public.returnMsg(True, "Container paused successfully!")
|
||||
except docker.errors.APIError as e:
|
||||
if "is already paused" in str(e):
|
||||
return public.returnMsg(False,"The container has been suspended!")
|
||||
if "is not running" in str(e):
|
||||
return public.returnMsg(False, "The container is not started and cannot be paused!")
|
||||
if "is not paused" in str(e):
|
||||
return public.returnMsg(False, "The container has not been suspended!")
|
||||
return str(e)
|
||||
|
||||
def unpause(self,args):
|
||||
"""
|
||||
unPauses all processes within this container.
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
args.act = "unpause"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "running":
|
||||
return public.returnMsg(False, "Startup failed!")
|
||||
dp.write_log("Unpausing the container [{}] succeeded!".format(data['name']))
|
||||
return public.returnMsg(True, "Container unpause succeeded!")
|
||||
except docker.errors.APIError as e:
|
||||
if "is already paused" in str(e):
|
||||
return public.returnMsg(False,"The container has been suspended!")
|
||||
if "is not running" in str(e):
|
||||
return public.returnMsg(False, "The container is not started and cannot be paused!")
|
||||
if "is not paused" in str(e):
|
||||
return public.returnMsg(False, "The container has not been suspended!")
|
||||
return str(e)
|
||||
|
||||
def reload(self,args):
|
||||
"""
|
||||
Load this object from the server again and update attrs with the new data.
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
args.act = "reload"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "running":
|
||||
return public.returnMsg(False, "Startup failed!")
|
||||
dp.write_log("Reloading container [{}] succeeded!".format(data['name']))
|
||||
return public.returnMsg(True, "Container reload succeeded!")
|
||||
|
||||
def restart(self,args):
|
||||
"""
|
||||
Restart this container. Similar to the docker restart command.
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
args.act = "restart"
|
||||
data = self.set_container_status(args)
|
||||
if data['status'] != "running":
|
||||
return public.returnMsg(False, "Startup failed!")
|
||||
dp.write_log("Restarting the container [{}] succeeded!".format(data['name']))
|
||||
return public.returnMsg(True, "The container restarted successfully!")
|
||||
|
||||
def get_container_ip(self,container_networks):
|
||||
data = list()
|
||||
for network in container_networks:
|
||||
data.append(container_networks[network]['IPAddress'])
|
||||
return data
|
||||
|
||||
def get_container_path(self,detail):
|
||||
import os
|
||||
if not "GraphDriver" in detail:
|
||||
return False
|
||||
if "Data" not in detail["GraphDriver"]:
|
||||
return False
|
||||
if "MergedDir" not in detail["GraphDriver"]["Data"]:
|
||||
return False
|
||||
path = detail["GraphDriver"]["Data"]["MergedDir"]
|
||||
if not os.path.exists(path):
|
||||
return ""
|
||||
return path
|
||||
|
||||
# 获取容器列表所需的外部数据
|
||||
def get_other_data_for_container_list(self,args):
|
||||
import projectModel.bt_docker.dk_image as di
|
||||
import projectModel.bt_docker.dk_volume as dv
|
||||
import projectModel.bt_docker.dk_compose as dc
|
||||
import projectModel.bt_docker.dk_setup as ds
|
||||
# 获取镜像列表
|
||||
images = di.main().image_list(args)
|
||||
if images['status']:
|
||||
images = images['msg']['images_list']
|
||||
else:
|
||||
images = list()
|
||||
# 获取卷列表
|
||||
volumes = dv.main().get_volume_list(args)
|
||||
if volumes['status']:
|
||||
volumes = volumes['msg']['volume']
|
||||
else:
|
||||
volumes = list()
|
||||
# 获取模板列表
|
||||
template = dc.main().template_list(args)
|
||||
if template['status']:
|
||||
template = template['msg']['template']
|
||||
else:
|
||||
template = list()
|
||||
online_cpus = dp.get_cpu_count()
|
||||
mem_total = dp.get_mem_info()
|
||||
docker_setup = ds.main()
|
||||
return {
|
||||
"images":images,
|
||||
"volumes":volumes,
|
||||
"template":template,
|
||||
"online_cpus":online_cpus,
|
||||
"mem_total":mem_total,
|
||||
"installed":docker_setup.check_docker_program(),
|
||||
"service_status":docker_setup.get_service_status()
|
||||
}
|
||||
|
||||
# 获取容器列表
|
||||
def get_list(self,args):
|
||||
"""
|
||||
:param url
|
||||
:return:
|
||||
"""
|
||||
# 判断docker是否安装
|
||||
import projectModel.bt_docker.dk_setup as ds
|
||||
data = self.get_other_data_for_container_list(args)
|
||||
if not ds.main().check_docker_program():
|
||||
data['container_list'] = list()
|
||||
return public.returnMsg(True,data)
|
||||
client = self.docker_client(args.url)
|
||||
if not client:
|
||||
|
||||
return public.returnMsg(True,data)
|
||||
containers = client.containers
|
||||
attr_list = self.get_container_attr(containers)
|
||||
# data = self.get_other_data_for_container_list(args)
|
||||
container_detail = list()
|
||||
for attr in attr_list:
|
||||
cpu_usage = dp.sql("cpu_stats").where("container_id=?",(attr["Id"],)).select()
|
||||
if cpu_usage and isinstance(cpu_usage,list):
|
||||
cpu_usage = cpu_usage[-1]['cpu_usage']
|
||||
else:
|
||||
cpu_usage = "0.0"
|
||||
tmp = {
|
||||
"id": attr["Id"],
|
||||
"name": attr['Name'].replace("/",""),
|
||||
"status": attr["State"]["Status"],
|
||||
"image": attr["Config"]["Image"],
|
||||
"time": attr["Created"],
|
||||
"merged": self.get_container_path(attr),
|
||||
"ip": self.get_container_ip(attr["NetworkSettings"]['Networks']),
|
||||
"ports": attr["NetworkSettings"]["Ports"],
|
||||
"detail": attr,
|
||||
"cpu_usage":cpu_usage if attr["State"]["Status"] == "running" else ""
|
||||
}
|
||||
container_detail.append(tmp)
|
||||
data['container_list'] = container_detail
|
||||
return public.returnMsg(True,data)
|
||||
|
||||
# 获取容器的attr
|
||||
def get_container_attr(self,containers):
|
||||
c_list = containers.list(all=True)
|
||||
return [container_info.attrs for container_info in c_list]
|
||||
|
||||
# 获取容器日志
|
||||
def get_logs(self,args):
|
||||
"""
|
||||
:param url
|
||||
:param id
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
container = self.docker_client(args.url).containers.get(args.id)
|
||||
res = container.logs().decode()
|
||||
return public.returnMsg(True,res)
|
||||
except docker.errors.APIError as e:
|
||||
if "configured logging driver does not support reading" in str(e):
|
||||
return public.returnMsg(False,"The container has no log files!")
|
||||
|
||||
|
||||
|
||||
# 登录容器
|
||||
|
||||
|
||||
# 获取容器配置文件
|
||||
@@ -0,0 +1,42 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# Docker模型
|
||||
# ------------------------------
|
||||
import public #line:1
|
||||
import projectModel .bt_docker .dk_public as dp #line:2
|
||||
class main :#line:4
|
||||
def get_list (O0000O0OOO0OO0O00 ,args =None ):#line:7
|
||||
OO000O0OOO00OO00O =dp .sql ("hosts").select ()#line:8
|
||||
for OO0000O00OOO0OOO0 in OO000O0OOO00OO00O :#line:9
|
||||
if dp .docker_client (OO0000O00OOO0OOO0 ['url']):#line:10
|
||||
OO0000O00OOO0OOO0 ['status']=True #line:11
|
||||
else :#line:12
|
||||
OO0000O00OOO0OOO0 ['status']=False #line:13
|
||||
return OO000O0OOO00OO00O #line:14
|
||||
def add (O0OO00O0O000O0000 ,O00O0000O00000O0O ):#line:17
|
||||
""#line:22
|
||||
import time #line:23
|
||||
O00OO0OOO000OO0O0 =O0OO00O0O000O0000 .get_list ()#line:24
|
||||
for O0O0OO00O00OOOOOO in O00OO0OOO000OO0O0 :#line:25
|
||||
if O0O0OO00O00OOOOOO ['url']==O00O0000O00000O0O .url :#line:26
|
||||
return public .returnMsg (False ,"This host already exists!")#line:27
|
||||
if not dp .docker_client (O00O0000O00000O0O .url ):#line:29
|
||||
return public .returnMsg (False ,"Failed to connect to the server, please check if docker has been started!")#line:30
|
||||
O0O0OO0OOOOO0OOO0 ={"url":O00O0000O00000O0O .url ,"remark":O00O0000O00000O0O .remark ,"time":int (time .time ())}#line:35
|
||||
dp .write_log ("Add host [{}] successful!".format (O00O0000O00000O0O .url ))#line:36
|
||||
dp .sql ('hosts').insert (O0O0OO0OOOOO0OOO0 )#line:37
|
||||
return public .returnMsg (True ,"Add docker host successfully!")#line:38
|
||||
def delete (O0OOOO0000000O00O ,O0O0O0O000000OOOO ):#line:40
|
||||
""#line:44
|
||||
OOO00OO0OO0OOO00O =dp .sql ('hosts').where ('id=?',O0O0O0O000000OOOO (O0O0O0O000000OOOO .id ,)).find ()#line:45
|
||||
dp .sql ('hosts').delete (id =O0O0O0O000000OOOO .id )#line:46
|
||||
dp .write_log ("Delete host [{}] succeeded!".format (OOO00OO0OO0OOO00O ['url']))#line:47
|
||||
return public .returnMsg (True ,"Delete host successfully!")
|
||||
@@ -0,0 +1,226 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import os #line:13
|
||||
import public #line:14
|
||||
import docker .errors #line:15
|
||||
import projectModel .bt_docker .dk_public as dp #line:16
|
||||
class main :#line:18
|
||||
__O000O000OOOO0OO00 ='/tmp/dockertmp.log'#line:19
|
||||
def docker_client (O0O0OOO00O0000O0O ,OOOO0O000O000OO00 ):#line:20
|
||||
import projectModel .bt_docker .dk_public as dp #line:21
|
||||
return dp .docker_client (OOOO0O000O000OO00 )#line:22
|
||||
def save (O0O000OO0O0O00OO0 ,OOOO0000OO0O0OOOO ):#line:25
|
||||
""#line:33
|
||||
try :#line:34
|
||||
if "tar"in OOOO0000OO0O0OOOO .name :#line:35
|
||||
O00OOOO00OO0OO0OO ='{}/{}'.format (OOOO0000OO0O0OOOO .path ,OOOO0000OO0O0OOOO .name )#line:36
|
||||
else :#line:37
|
||||
O00OOOO00OO0OO0OO ='{}/{}.tar'.format (OOOO0000OO0O0OOOO .path ,OOOO0000OO0O0OOOO .name )#line:38
|
||||
if not os .path .exists (OOOO0000OO0O0OOOO .path ):#line:39
|
||||
os .makedirs (OOOO0000OO0O0OOOO .path )#line:40
|
||||
public .writeFile (O00OOOO00OO0OO0OO ,"")#line:41
|
||||
O0000O0OOOOO000OO =open (O00OOOO00OO0OO0OO ,'wb')#line:42
|
||||
O000OOOOOO00OOO00 =O0O000OO0O0O00OO0 .docker_client (OOOO0000OO0O0OOOO .url ).images .get (OOOO0000OO0O0OOOO .id )#line:43
|
||||
for OO0O0O0O0O0OO0OOO in O000OOOOOO00OOO00 .save (named =True ):#line:44
|
||||
O0000O0OOOOO000OO .write (OO0O0O0O0O0OO0OOO )#line:45
|
||||
O0000O0OOOOO000OO .close ()#line:46
|
||||
dp .write_log ("Image [{}] exported to [{}] successfully!".format (OOOO0000OO0O0OOOO .id ,O00OOOO00OO0OO0OO ))#line:47
|
||||
return public .returnMsg (True ,"Saved successfully to: {}".format (O00OOOO00OO0OO0OO ))#line:48
|
||||
except docker .errors .APIError as OOOO000OOO0O000O0 :#line:49
|
||||
if "empty export - not implemented"in str (OOOO000OOO0O000O0 ):#line:50
|
||||
return public .returnMsg (False ,"Empty images cannot be exported!")#line:51
|
||||
return public .get_error_info ()#line:52
|
||||
def load (OOO000O000OOOOOO0 ,O00OO0OOOO000O000 ):#line:55
|
||||
""#line:60
|
||||
OOOOO000O000O0000 =OOO000O000OOOOOO0 .docker_client (O00OO0OOOO000O000 .url ).images #line:61
|
||||
with open (O00OO0OOOO000O000 .path ,'rb')as OO00O0O00000000O0 :#line:62
|
||||
OOOOO000O000O0000 .load (OO00O0O00000000O0 )#line:65
|
||||
dp .write_log ("Image [{}] imported successfully!".format (O00OO0OOOO000O000 .path ))#line:66
|
||||
return public .returnMsg (True ,"Import successful! {}".format (O00OO0OOOO000O000 .path ))#line:67
|
||||
def image_list (OO0O0OOO0OOOOO00O ,OO0O0OO000O0OOOOO ):#line:70
|
||||
""#line:75
|
||||
import projectModel .bt_docker .dk_registry as dr #line:76
|
||||
import projectModel .bt_docker .dk_setup as ds #line:77
|
||||
OOO00000OOO00000O =list ()#line:78
|
||||
OO0OO00OOOO0O0O00 =OO0O0OOO0OOOOO00O .docker_client (OO0O0OO000O0OOOOO .url )#line:79
|
||||
OO0OOO00OOO0O0OO0 =ds .main ()#line:80
|
||||
O0OO0000O0O0O00O0 =OO0OOO00OOO0O0OO0 .check_docker_program ()#line:81
|
||||
O00OOO0000OO0O0OO =OO0OOO00OOO0O0OO0 .get_service_status ()#line:82
|
||||
if not OO0OO00OOOO0O0O00 :#line:83
|
||||
OOO00000OOO00000O ={"images_list":[],"registry_list":[],"installed":O0OO0000O0O0O00O0 ,"service_status":O00OOO0000OO0O0OO }#line:89
|
||||
return public .returnMsg (True ,OOO00000OOO00000O )#line:90
|
||||
OOOO000O0OO00O00O =OO0OO00OOOO0O0O00 .images #line:91
|
||||
OO0OO0OO000OOO000 =OO0O0OOO0OOOOO00O .get_image_attr (OOOO000O0OO00O00O )#line:92
|
||||
OO000O0OO000O0000 =dr .main ().registry_list (OO0O0OO000O0OOOOO )#line:93
|
||||
if OO000O0OO000O0000 ['status']:#line:94
|
||||
OO000O0OO000O0000 =OO000O0OO000O0000 ['msg']['registry']#line:95
|
||||
else :#line:96
|
||||
OO000O0OO000O0000 =[]#line:97
|
||||
for OO0O0O000000O00O0 in OO0OO0OO000OOO000 :#line:98
|
||||
if len (OO0O0O000000O00O0 ['RepoTags'])==1 :#line:99
|
||||
O0O0O0O0000OO0O00 ={"id":OO0O0O000000O00O0 ["Id"],"tags":OO0O0O000000O00O0 ["RepoTags"],"time":OO0O0O000000O00O0 ["Created"],"name":OO0O0O000000O00O0 ['RepoTags'][0 ],"size":OO0O0O000000O00O0 ["Size"],"detail":OO0O0O000000O00O0 }#line:107
|
||||
OOO00000OOO00000O .append (O0O0O0O0000OO0O00 )#line:108
|
||||
elif len (OO0O0O000000O00O0 ['RepoTags'])>1 :#line:109
|
||||
for O0OO0O0O00O000O0O in range (len (OO0O0O000000O00O0 ['RepoTags'])):#line:110
|
||||
O0O0O0O0000OO0O00 ={"id":OO0O0O000000O00O0 ["Id"],"tags":OO0O0O000000O00O0 ["RepoTags"],"time":OO0O0O000000O00O0 ["Created"],"name":OO0O0O000000O00O0 ['RepoTags'][O0OO0O0O00O000O0O ],"size":OO0O0O000000O00O0 ["Size"],"detail":OO0O0O000000O00O0 }#line:118
|
||||
OOO00000OOO00000O .append (O0O0O0O0000OO0O00 )#line:119
|
||||
elif not OO0O0O000000O00O0 ['RepoTags']:#line:120
|
||||
O0O0O0O0000OO0O00 ={"id":OO0O0O000000O00O0 ["Id"],"tags":OO0O0O000000O00O0 ["RepoTags"],"time":OO0O0O000000O00O0 ["Created"],"name":OO0O0O000000O00O0 ["Id"],"size":OO0O0O000000O00O0 ["Size"],"detail":OO0O0O000000O00O0 }#line:128
|
||||
OOO00000OOO00000O .append (O0O0O0O0000OO0O00 )#line:129
|
||||
OOO00000OOO00000O ={"images_list":OOO00000OOO00000O ,"registry_list":OO000O0OO000O0000 ,"installed":O0OO0000O0O0O00O0 ,"service_status":O00OOO0000OO0O0OO }#line:135
|
||||
return public .returnMsg (True ,OOO00000OOO00000O )#line:136
|
||||
def get_image_attr (O00OOOO0O00OOO00O ,O000O00OOOOOOO000 ):#line:138
|
||||
OOO00O0O00OO00OO0 =O000O00OOOOOOO000 .list ()#line:139
|
||||
return [OO0000OOO0OO0O0OO .attrs for OO0000OOO0OO0O0OO in OOO00O0O00OO00OO0 ]#line:140
|
||||
def get_logs (OO000O0O000000O0O ,OOOO000000O000O0O ):#line:142
|
||||
import files #line:143
|
||||
O0O0O0O0O0OOOOOO0 =OOOO000000O000O0O .logs_file #line:144
|
||||
return public .returnMsg (True ,files .files ().GetLastLine (O0O0O0O0O0OOOOOO0 ,20 ))#line:145
|
||||
def build (OOOO0OOO00O000O0O ,O00O0OOO00O00O0O0 ):#line:148
|
||||
""#line:156
|
||||
public .writeFile (OOOO0OOO00O000O0O .__O000O000OOOO0OO00 ,"Start building images!")#line:157
|
||||
public .writeFile ('/tmp/dockertmp.log',"Start building the mirror")#line:158
|
||||
if not hasattr (O00O0OOO00O00O0O0 ,"pull"):#line:159
|
||||
O00O0OOO00O00O0O0 .pull =False #line:160
|
||||
if hasattr (O00O0OOO00O00O0O0 ,"data")and O00O0OOO00O00O0O0 .data :#line:161
|
||||
O00O0OOO00O00O0O0 .path ="/tmp/dockerfile"#line:162
|
||||
public .writeFile (O00O0OOO00O00O0O0 .path ,O00O0OOO00O00O0O0 .data )#line:163
|
||||
with open (O00O0OOO00O00O0O0 .path ,'rb')as OOO000000O000OOOO :#line:164
|
||||
OO000OOOO0O0OO0O0 ,O000OOO0O0OOOO00O =OOOO0OOO00O000O0O .docker_client (O00O0OOO00O00O0O0 .url ).images .build (pull =True if O00O0OOO00O00O0O0 .pull =="1"else False ,fileobj =OOO000000O000OOOO ,tag =O00O0OOO00O00O0O0 .tag )#line:169
|
||||
os .remove (O00O0OOO00O00O0O0 .path )#line:170
|
||||
else :#line:171
|
||||
if not os .path .isdir (O00O0OOO00O00O0O0 .path ):#line:172
|
||||
O00O0OOO00O00O0O0 .path ='/'.join (O00O0OOO00O00O0O0 .path .split ('/')[:-1 ])#line:173
|
||||
OO000OOOO0O0OO0O0 ,O000OOO0O0OOOO00O =OOOO0OOO00O000O0O .docker_client (O00O0OOO00O00O0O0 .url ).images .build (pull =True if O00O0OOO00O00O0O0 .pull =="1"else False ,path =O00O0OOO00O00O0O0 .path ,tag =O00O0OOO00O00O0O0 .tag )#line:178
|
||||
dp .log_docker (O000OOO0O0OOOO00O ,"Docker build tasks")#line:180
|
||||
dp .write_log ("Building image [{}] succeeded!".format (O00O0OOO00O00O0O0 .tag ))#line:181
|
||||
return public .returnMsg (True ,"Building image successfully!")#line:182
|
||||
def remove (OOOOO00000OO0OO0O ,O0000O000000OOO00 ):#line:185
|
||||
""#line:193
|
||||
try :#line:194
|
||||
OOOOO00000OO0OO0O .docker_client (O0000O000000OOO00 .url ).images .remove (O0000O000000OOO00 .name )#line:195
|
||||
dp .write_log ("Delete mirror【{}】successful!".format (O0000O000000OOO00 .name ))#line:196
|
||||
return public .returnMsg (True ,"Mirror deleted successfully!")#line:197
|
||||
except docker .errors .ImageNotFound as OOO00OOOO00OOO0O0 :#line:198
|
||||
return public .returnMsg (False ,"Failed to delete the mirror, maybe the mirror does not exist!")#line:199
|
||||
except docker .errors .APIError as OOO00OOOO00OOO0O0 :#line:200
|
||||
if "image is referenced in multiple repositories"in str (OOO00OOOO00OOO0O0 ):#line:201
|
||||
return public .returnMsg (False ,"The image ID is used in multiple images, please check [Force Delete]!")#line:202
|
||||
if "using its referenced image"in str (OOO00OOOO00OOO0O0 ):#line:203
|
||||
return public .returnMsg (False ,"The image is in use, please delete the container and then delete it!")#line:204
|
||||
return public .returnMsg (False ,"Delete mirror failed!<br> {}".format (OOO00OOOO00OOO0O0 ))#line:205
|
||||
def pull_from_some_registry (O00OOOOOOOOO00000 ,O0O0O0OOO0O0OO0O0 ):#line:208
|
||||
""#line:215
|
||||
import projectModel .bt_docker .dk_registry as br #line:216
|
||||
O00O00OO00OOOOO00 =br .main ().registry_info (O0O0O0OOO0O0OO0O0 .name )#line:217
|
||||
O0000OO00OO0OO000 =br .main ().login (O0O0O0OOO0O0OO0O0 .url ,O00O00OO00OOOOO00 ['url'],O00O00OO00OOOOO00 ['username'],O00O00OO00OOOOO00 ['password'])['status']#line:218
|
||||
if not O0000OO00OO0OO000 :#line:219
|
||||
return O0000OO00OO0OO000 #line:220
|
||||
O0O0O0OOO0O0OO0O0 .username =O00O00OO00OOOOO00 ['username']#line:221
|
||||
O0O0O0OOO0O0OO0O0 .password =O00O00OO00OOOOO00 ['password']#line:222
|
||||
O0O0O0OOO0O0OO0O0 .registry =O00O00OO00OOOOO00 ['url']#line:223
|
||||
O0O0O0OOO0O0OO0O0 .namespace =O00O00OO00OOOOO00 ['namespace']#line:224
|
||||
return O00OOOOOOOOO00000 .pull (O0O0O0OOO0O0OO0O0 )#line:225
|
||||
def push (OO0O0OOO0O0O00O0O ,OO000OOO0OO000O0O ):#line:228
|
||||
""#line:236
|
||||
if "/"in OO000OOO0OO000O0O .tag :#line:237
|
||||
return public .returnMsg (False ,"The pushed image name cannot contain the symbol [/] , please use the following format: image:v1 (image_name:version_number)")#line:238
|
||||
if ":"not in OO000OOO0OO000O0O .tag :#line:239
|
||||
return public .returnMsg (False ,"The pushed image name must contain the symbol [ : ] , please use the following format: image:v1 (image_name:version_number)")#line:240
|
||||
public .writeFile (OO0O0OOO0O0O00O0O .__O000O000OOOO0OO00 ,"Start pushing mirrors!\n")#line:241
|
||||
import projectModel .bt_docker .dk_registry as br #line:242
|
||||
O00O0O0O0O0O0O000 =br .main ().registry_info (OO000OOO0OO000O0O .name )#line:243
|
||||
if OO000OOO0OO000O0O .name =="docker official"and O00O0O0O0O0O0O000 ['url']=="docker.io":#line:244
|
||||
public .writeFile (OO0O0OOO0O0O00O0O .__O000O000OOOO0OO00 ,"The image cannot be pushed to the Docker public repository!\n")#line:245
|
||||
return public .returnMsg (False ,"Unable to push to Docker public repo!")#line:246
|
||||
O0O0000OOO0OOO00O =br .main ().login (OO000OOO0OO000O0O .url ,O00O0O0O0O0O0O000 ['url'],O00O0O0O0O0O0O000 ['username'],O00O0O0O0O0O0O000 ['password'])['status']#line:247
|
||||
O00OOO0O0O0O0O0O0 =OO000OOO0OO000O0O .tag #line:248
|
||||
if not O0O0000OOO0OOO00O :#line:249
|
||||
return O0O0000OOO0OOO00O #line:250
|
||||
OO00O0000000OO000 ={"username":O00O0O0O0O0O0O000 ['username'],"password":O00O0O0O0O0O0O000 ['password'],"registry":O00O0O0O0O0O0O000 ['url']}#line:254
|
||||
if ":"not in O00OOO0O0O0O0O0O0 :#line:256
|
||||
O00OOO0O0O0O0O0O0 ="{}:latest".format (O00OOO0O0O0O0O0O0 )#line:257
|
||||
OOOO000OOOOO0O00O =O00O0O0O0O0O0O000 ['url']#line:258
|
||||
O0OO00O0OO000O0OO ="{}/{}/{}".format (OOOO000OOOOO0O00O ,O00O0O0O0O0O0O000 ['namespace'],OO000OOO0OO000O0O .tag )#line:259
|
||||
OO0O0OOO0O0O00O0O .tag (OO000OOO0OO000O0O .url ,OO000OOO0OO000O0O .id ,O0OO00O0OO000O0OO )#line:260
|
||||
O000OOOO00O0OO000 =OO0O0OOO0O0O00O0O .docker_client (OO000OOO0OO000O0O .url ).images .push (repository =O0OO00O0OO000O0OO .split (":")[0 ],tag =O00OOO0O0O0O0O0O0 .split (":")[-1 ],auth_config =OO00O0000000OO000 ,stream =True )#line:266
|
||||
dp .log_docker (O000OOOO00O0OO000 ,"Image push task")#line:267
|
||||
OO000OOO0OO000O0O .name =O0OO00O0OO000O0OO #line:269
|
||||
OO0O0OOO0O0O00O0O .remove (OO000OOO0OO000O0O )#line:270
|
||||
dp .write_log ("The image [{}] was pushed successfully!".format (O0OO00O0OO000O0OO ))#line:271
|
||||
return public .returnMsg (True ,"推送成功!{}".format (str (O000OOOO00O0OO000 )))#line:272
|
||||
def tag (OOO0OO00OO0OO0O00 ,O000O0OOO00O000OO ,OOOO0O0OOO0000O00 ,OO0O0000OO00O00O0 ):#line:274
|
||||
""#line:281
|
||||
OOO000O000000OOO0 =OO0O0000OO00O00O0 .split (":")[0 ]#line:282
|
||||
O00OOO0OOOO0O000O =OO0O0000OO00O00O0 .split (":")[1 ]#line:283
|
||||
OOO0OO00OO0OO0O00 .docker_client (O000O0OOO00O000OO ).images .get (OOOO0O0OOO0000O00 ).tag (repository =OOO000O000000OOO0 ,tag =O00OOO0OOOO0O000O )#line:287
|
||||
return public .returnMsg (True ,"Set successfully")#line:288
|
||||
def pull (O0O0O0000OOOOOOO0 ,OO00OOO00OO000O00 ):#line:290
|
||||
""#line:299
|
||||
public .writeFile (O0O0O0000OOOOOOO0 .__O000O000OOOO0OO00 ,"Start pulling images!")#line:300
|
||||
import docker .errors #line:301
|
||||
try :#line:302
|
||||
if ':'not in OO00OOO00OO000O00 .image :#line:303
|
||||
OO00OOO00OO000O00 .image ='{}:latest'.format (OO00OOO00OO000O00 .image )#line:304
|
||||
O0O00OO000O000OO0 ={"username":OO00OOO00OO000O00 .username ,"password":OO00OOO00OO000O00 .password ,"registry":OO00OOO00OO000O00 .registry if OO00OOO00OO000O00 .registry else None }if OO00OOO00OO000O00 .username else None #line:308
|
||||
if not hasattr (OO00OOO00OO000O00 ,"tag"):#line:309
|
||||
OO00OOO00OO000O00 .tag =OO00OOO00OO000O00 .image .split (":")[-1 ]#line:310
|
||||
if OO00OOO00OO000O00 .registry !="docker.io":#line:311
|
||||
OO00OOO00OO000O00 .image ="{}/{}/{}".format (OO00OOO00OO000O00 .registry ,OO00OOO00OO000O00 .namespace ,OO00OOO00OO000O00 .image )#line:312
|
||||
OOO0OOOO000O000O0 =dp .docker_client_low (OO00OOO00OO000O00 .url ).pull (repository =OO00OOO00OO000O00 .image ,auth_config =O0O00OO000O000OO0 ,tag =OO00OOO00OO000O00 .tag ,stream =True )#line:318
|
||||
dp .log_docker (OOO0OOOO000O000O0 ,"Image pull task")#line:319
|
||||
if OOO0OOOO000O000O0 :#line:320
|
||||
dp .write_log ("The image [{}:{}] was pulled successfully!".format (OO00OOO00OO000O00 .image ,OO00OOO00OO000O00 .tag ))#line:321
|
||||
return public .returnMsg (True ,'Pulling the image succeeded.')#line:322
|
||||
else :#line:323
|
||||
return public .returnMsg (False ,'There may not be this image.')#line:324
|
||||
except docker .errors .ImageNotFound as O0O0OO00OO000O0O0 :#line:325
|
||||
if "pull access denied for"in str (O0O0OO00OO000O0O0 ):#line:326
|
||||
return public .returnMsg (False ,"The pull failed, the image is a private image, you need to enter the account password of dockerhub!")#line:327
|
||||
return public .returnMsg (False ,"Pull failed<br><br>reasons: {}".format (O0O0OO00OO000O0O0 ))#line:329
|
||||
except docker .errors .NotFound as O0O0OO00OO000O0O0 :#line:331
|
||||
if "not found: manifest unknown"in str (O0O0OO00OO000O0O0 ):#line:332
|
||||
return public .returnMsg (False ,"The pull failed, the repository does not have the mirror!")#line:333
|
||||
return public .returnMsg (False ,"Pull failed<br><br>reason:{}".format (O0O0OO00OO000O0O0 ))#line:334
|
||||
except docker .errors .APIError as O0O0OO00OO000O0O0 :#line:335
|
||||
if "invalid tag format"in str (O0O0OO00OO000O0O0 ):#line:336
|
||||
return public .returnMsg (False ,"The pull failed, the image format is wrong, the format should be: nginx:v 1!")#line:337
|
||||
return public .returnMsg (False ,"Pull failed!{}".format (O0O0OO00OO000O0O0 ))#line:338
|
||||
def pull_high_api (OO0O0O0O000O000O0 ,O0000O0O000O0O0O0 ):#line:342
|
||||
""#line:351
|
||||
import docker .errors #line:352
|
||||
try :#line:353
|
||||
if ':'not in O0000O0O000O0O0O0 .image :#line:354
|
||||
O0000O0O000O0O0O0 .image ='{}:latest'.format (O0000O0O000O0O0O0 .image )#line:355
|
||||
O0O0O00O0O0O00000 ={"username":O0000O0O000O0O0O0 .username ,"password":O0000O0O000O0O0O0 .password ,"registry":O0000O0O000O0O0O0 .registry if O0000O0O000O0O0O0 .registry else None }if O0000O0O000O0O0O0 .username else None #line:359
|
||||
if O0000O0O000O0O0O0 .registry !="docker.io":#line:361
|
||||
O0000O0O000O0O0O0 .image ="{}/{}/{}".format (O0000O0O000O0O0O0 .registry ,O0000O0O000O0O0O0 .namespace ,O0000O0O000O0O0O0 .image )#line:362
|
||||
OOOOOOOO0O0OOOO0O =OO0O0O0O000O000O0 .docker_client (O0000O0O000O0O0O0 .url ).images .pull (repository =O0000O0O000O0O0O0 .image ,auth_config =O0O0O00O0O0O00000 ,)#line:366
|
||||
if OOOOOOOO0O0OOOO0O :#line:367
|
||||
return public .returnMsg (True ,'Pulling the image succeeded.')#line:368
|
||||
else :#line:369
|
||||
return public .returnMsg (False ,'There may not be this mirror.')#line:370
|
||||
except docker .errors .ImageNotFound as O0O0O0OOO0O0OO0OO :#line:371
|
||||
if "pull access denied for"in str (O0O0O0OOO0O0OO0OO ):#line:372
|
||||
return public .returnMsg (False ,"The pull failed, the image is a private image, you need to enter the account password of dockerhub!")#line:373
|
||||
return public .returnMsg (False ,"Pull failed<br><br>reason: {}".format (O0O0O0OOO0O0OO0OO ))#line:374
|
||||
def image_for_host (O00O0O0O000OOO0O0 ,O000OO0OOOOO000O0 ):#line:376
|
||||
""#line:381
|
||||
O00O000OO0OO000OO =O00O0O0O000OOO0O0 .image_list (O000OO0OOOOO000O0 )#line:382
|
||||
if not O00O000OO0OO000OO ['status']:#line:383
|
||||
return O00O000OO0OO000OO #line:384
|
||||
OO000O0000O000000 =len (O00O000OO0OO000OO ['msg']['images_list'])#line:385
|
||||
O0OOOO0OO000OO0OO =0 #line:386
|
||||
for OO00OOO0000OO0O00 in O00O000OO0OO000OO ['msg']['images_list']:#line:387
|
||||
O0OOOO0OO000OO0OO +=OO00OOO0000OO0O00 ['size']#line:388
|
||||
return public .returnMsg (True ,{'num':OO000O0000O000000 ,'size':O0OOOO0OO000OO0OO })
|
||||
@@ -0,0 +1,92 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import sys #line:1
|
||||
import threading #line:2
|
||||
sys .path .insert (0 ,"/www/server/panel/class/")#line:3
|
||||
sys .path .insert (1 ,"/www/server/panel/")#line:4
|
||||
import projectModel .bt_docker .dk_public as dp #line:5
|
||||
import projectModel .bt_docker .dk_container as dc #line:6
|
||||
import projectModel .bt_docker .dk_status as ds #line:7
|
||||
import projectModel .bt_docker .dk_image as di #line:8
|
||||
import public #line:9
|
||||
import time #line:11
|
||||
class main :#line:12
|
||||
__OOOOO0OOO0OO00O00 =None #line:14
|
||||
__OOOOOO0OO0OOOOOO0 =86400 #line:15
|
||||
def __init__ (O00O000000O0OO0OO ,OO00OO00O0O00OO0O ):#line:17
|
||||
if not OO00OO00O0O00OO0O :#line:18
|
||||
O00O000000O0OO0OO .__OOOOO0OOO0OO00O00 =30 #line:19
|
||||
else :#line:20
|
||||
O00O000000O0OO0OO .__OOOOO0OOO0OO00O00 =OO00OO00O0O00OO0O #line:21
|
||||
def docker_client (OOOOO000OO0O00OO0 ,OO00OOO0000OO0000 ):#line:23
|
||||
return dp .docker_client (OO00OOO0000OO0000 )#line:24
|
||||
def get_all_host_stats (O0000O0000OO0O000 ,O000O0O00OO00O00O ):#line:26
|
||||
""#line:31
|
||||
OO000O0OO0O0O0000 =dp .sql ('hosts').select ()#line:32
|
||||
for O00O0OO00O0O000O0 in OO000O0OO0O0O0000 :#line:33
|
||||
O0OO00O0O00O0000O =threading .Thread (target =O000O0O00OO00O00O ,args =(O00O0OO00O0O000O0 ,))#line:34
|
||||
O0OO00O0O00O0000O .setDaemon (True )#line:35
|
||||
O0OO00O0O00O0000O .start ()#line:36
|
||||
def container_status_for_all_hosts (OO0O00OO0O0OOOO0O ,OOOOOOO000OO0OOO0 ):#line:39
|
||||
""#line:44
|
||||
O000OO000O0O00O00 =public .to_dict_obj ({})#line:46
|
||||
O000OO000O0O00O00 .url =OOOOOOO000OO0OOO0 ['url']#line:47
|
||||
O0O0O0O000O00O0OO =dc .main ().get_list (O000OO000O0O00O00 )['msg']#line:48
|
||||
for O00OOOOOOOO00OOO0 in O0O0O0O000O00O0OO ['container_list']:#line:49
|
||||
O000OO000O0O00O00 .id =O00OOOOOOOO00OOO0 ['id']#line:50
|
||||
O000OO000O0O00O00 .write =1 #line:51
|
||||
O000OO000O0O00O00 .save_date =OO0O00OO0O0OOOO0O .__OOOOO0OOO0OO00O00 #line:52
|
||||
ds .main ().stats (O000OO000O0O00O00 )#line:53
|
||||
def container_count (OO0000O0O0O0OOO00 ):#line:57
|
||||
O0O000O0O000O000O =dp .sql ('hosts').select ()#line:59
|
||||
O0O00O00O0O00OOO0 =0 #line:60
|
||||
for O0O0O00OO0OO0O0O0 in O0O000O0O000O000O :#line:61
|
||||
O00OOOO00OO0OOO00 =public .to_dict_obj ({})#line:62
|
||||
O00OOOO00OO0OOO00 .url =O0O0O00OO0OO0O0O0 ['url']#line:63
|
||||
OO00OO00O0O00O00O =dc .main ().get_list (O00OOOO00OO0OOO00 )['msg']#line:64
|
||||
O0O00O00O0O00OOO0 +=len (OO00OO00O0O00O00O )#line:65
|
||||
O0000000000000000 ={"time":int (time .time ()),"container_count":O0O00O00O0O00OOO0 }#line:69
|
||||
OOOOO0OO00OOO0O0O =time .time ()-(OO0000O0O0O0OOO00 .__OOOOO0OOO0OO00O00 *OO0000O0O0O0OOO00 .__OOOOOO0OO0OOOOOO0 )#line:70
|
||||
dp .sql ("container_count").where ("time<?",(OOOOO0OO00OOO0O0O ,)).delete ()#line:71
|
||||
dp .sql ("container_count").insert (O0000000000000000 )#line:72
|
||||
def image_for_all_host (OO0O00O000OO00O0O ):#line:75
|
||||
OO000OO0OOO00OO0O =dp .sql ('hosts').select ()#line:77
|
||||
OOO0OOO00O000OOOO =0 #line:78
|
||||
O0O00000OO0O0O000 =0 #line:79
|
||||
for O00OOO00O0000O00O in OO000OO0OOO00OO0O :#line:80
|
||||
O0O00O0OOOO0O00O0 =public .to_dict_obj ({})#line:81
|
||||
O0O00O0OOOO0O00O0 .url =O00OOO00O0000O00O ['url']#line:82
|
||||
OO00O0000O0000O00 =di .main ().image_for_host (O0O00O0OOOO0O00O0 )#line:83
|
||||
if not OO00O0000O0000O00 ['status']:#line:84
|
||||
continue #line:85
|
||||
print (OO00O0000O0000O00 )#line:86
|
||||
OOO0OOO00O000OOOO +=OO00O0000O0000O00 ['msg']['num']#line:87
|
||||
O0O00000OO0O0O000 +=OO00O0000O0000O00 ['msg']['size']#line:88
|
||||
O0OO0O00O000000OO ={"time":int (time .time ()),"num":OOO0OOO00O000OOOO ,"size":int (O0O00000OO0O0O000 )}#line:93
|
||||
O0O000O00OO0OO0O0 =time .time ()-(OO0O00O000OO00O0O .__OOOOO0OOO0OO00O00 *OO0O00O000OO00O0O .__OOOOOO0OO0OOOOOO0 )#line:94
|
||||
dp .sql ("image_infos").where ("time<?",(O0O000O00OO0OO0O0 ,)).delete ()#line:95
|
||||
dp .sql ("image_infos").insert (O0OO0O00O000000OO )#line:96
|
||||
def monitor ():#line:99
|
||||
while True :#line:102
|
||||
O0OOO000OOO0OOO00 =dp .docker_conf ()['SAVE']#line:103
|
||||
O000OO0O0O0OO0000 =main (O0OOO000OOO0OOO00 )#line:104
|
||||
O000OO0O0O0OO0000 .get_all_host_stats (O000OO0O0O0OO0000 .container_status_for_all_hosts )#line:105
|
||||
O0000OO0000000O00 =threading .Thread (target =O000OO0O0O0OO0000 .container_count )#line:107
|
||||
O0000OO0000000O00 .setDaemon (True )#line:108
|
||||
O0000OO0000000O00 .start ()#line:109
|
||||
O0000OO0000000O00 =threading .Thread (target =O000OO0O0O0OO0000 .image_for_all_host )#line:111
|
||||
O0000OO0000000O00 .setDaemon (True )#line:112
|
||||
O0000OO0000000O00 .start ()#line:113
|
||||
time .sleep (60 )#line:114
|
||||
if __name__ =="__main__":#line:119
|
||||
monitor ()
|
||||
@@ -0,0 +1,69 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public #line:1
|
||||
import projectModel .bt_docker .dk_public as dp #line:2
|
||||
import docker .errors #line:3
|
||||
class main :#line:5
|
||||
def docker_client (O00O0O000OO0000O0 ,OOO0OOOO0O0000OO0 ):#line:7
|
||||
import projectModel .bt_docker .dk_public as dp #line:8
|
||||
return dp .docker_client (OOO0OOOO0O0000OO0 )#line:9
|
||||
def get_host_network (OO0O00O000O000O0O ,O00OO00OO00OOOOOO ):#line:11
|
||||
""#line:16
|
||||
import projectModel .bt_docker .dk_setup as ds #line:17
|
||||
O00OO00O00000000O =ds .main ()#line:18
|
||||
O000O0O0O00OO000O =O00OO00O00000000O .check_docker_program ()#line:19
|
||||
O0O00O000OOO0OO0O =O00OO00O00000000O .get_service_status ()#line:20
|
||||
OO0O0O00OO0OO0OO0 =OO0O00O000O000O0O .docker_client (O00OO00OO00OOOOOO .url )#line:21
|
||||
if not OO0O0O00OO0OO0OO0 :#line:22
|
||||
O0000O0000O0O0OO0 ={"images_list":[],"registry_list":[],"installed":O000O0O0O00OO000O ,"service_status":O0O00O000OOO0OO0O }#line:28
|
||||
return public .returnMsg (True ,O0000O0000O0O0OO0 )#line:29
|
||||
O000OO0OO00OOOO0O =OO0O0O00OO0OO0OO0 .networks #line:30
|
||||
O0OOO0O00O00OO000 =OO0O00O000O000O0O .get_network_attr (O000OO0OO00OOOO0O )#line:31
|
||||
O0000O0000O0O0OO0 =list ()#line:32
|
||||
for OOOO0O0OOOO0O00O0 in O0OOO0O00O00OO000 :#line:33
|
||||
OOOO00OOOO0O0000O =""#line:34
|
||||
O00O000OOOO000O0O =""#line:35
|
||||
if OOOO0O0OOOO0O00O0 ["IPAM"]["Config"]:#line:36
|
||||
if "Subnet"in OOOO0O0OOOO0O00O0 ["IPAM"]["Config"][0 ]:#line:37
|
||||
OOOO00OOOO0O0000O =OOOO0O0OOOO0O00O0 ["IPAM"]["Config"][0 ]["Subnet"]#line:38
|
||||
if "Gateway"in OOOO0O0OOOO0O00O0 ["IPAM"]["Config"][0 ]:#line:39
|
||||
O00O000OOOO000O0O =OOOO0O0OOOO0O00O0 ["IPAM"]["Config"][0 ]["Gateway"]#line:40
|
||||
OOOOO000000OO000O ={"id":OOOO0O0OOOO0O00O0 ["Id"],"name":OOOO0O0OOOO0O00O0 ["Name"],"time":OOOO0O0OOOO0O00O0 ["Created"],"driver":OOOO0O0OOOO0O00O0 ["IPAM"]["Driver"],"subnet":OOOO00OOOO0O0000O ,"gateway":O00O000OOOO000O0O ,"labels":OOOO0O0OOOO0O00O0 ["Labels"]}#line:49
|
||||
O0000O0000O0O0OO0 .append (OOOOO000000OO000O )#line:50
|
||||
OOOOOOO000O0O0O0O ={"network":O0000O0000O0O0OO0 ,"installed":O000O0O0O00OO000O ,"service_status":O0O00O000OOO0OO0O }#line:56
|
||||
return public .returnMsg (True ,OOOOOOO000O0O0O0O )#line:57
|
||||
def get_network_attr (OO0O00O00O000OO00 ,O0OO0000O0OOO0O0O ):#line:59
|
||||
O000OOOO0OOO00O00 =O0OO0000O0OOO0O0O .list ()#line:60
|
||||
return [O00O0000O0OO00O00 .attrs for O00O0000O0OO00O00 in O000OOOO0OOO00O00 ]#line:61
|
||||
def add (O0OOO0O0O0000OO0O ,O0OOO0O000000000O ):#line:63
|
||||
""#line:75
|
||||
import docker #line:76
|
||||
O0O0000OO00OO00OO =docker .types .IPAMPool (subnet =O0OOO0O000000000O .subnet ,gateway =O0OOO0O000000000O .gateway ,iprange =O0OOO0O000000000O .iprange )#line:81
|
||||
OOOO00000O000OO0O =docker .types .IPAMConfig (pool_configs =[O0O0000OO00OO00OO ])#line:84
|
||||
O0OOO0O0O0000OO0O .docker_client (O0OOO0O000000000O .url ).networks .create (name =O0OOO0O000000000O .name ,options =O0OOO0O000000000O .options if O0OOO0O000000000O .options else None ,driver ="bridge",ipam =OOOO00000O000OO0O ,labels =dp .set_kv (O0OOO0O000000000O .labels ))#line:91
|
||||
dp .write_log ("Add network [{}] [{}] successful!".format (O0OOO0O000000000O .name ,O0OOO0O000000000O .iprange ))#line:92
|
||||
return public .returnMsg (True ,"Added successfully!")#line:93
|
||||
def del_network (OOOOO0OO0O00O000O ,OOO0OOOO0O0O0O0O0 ):#line:95
|
||||
""#line:100
|
||||
try :#line:101
|
||||
O000O0OO00O0OO000 =OOOOO0OO0O00O000O .docker_client (OOO0OOOO0O0O0O0O0 .url ).networks .get (OOO0OOOO0O0O0O0O0 .id )#line:103
|
||||
O0OOOOOO0OO0O0OOO =O000O0OO00O0OO000 .attrs #line:104
|
||||
if O0OOOOOO0OO0O0OOO ['Name']in ["bridge","none"]:#line:105
|
||||
return public .returnMsg (False ,"The system default network cannot be deleted!")#line:106
|
||||
O000O0OO00O0OO000 .remove ()#line:107
|
||||
dp .write_log ("Delete network [{}] successful!".format (O0OOOOOO0OO0O0OOO ['Name']))#line:108
|
||||
return public .returnMsg (True ,"Successfully deleted!")#line:109
|
||||
except docker .errors .APIError as OOOOOO0O00O0O0OO0 :#line:110
|
||||
if " has active endpoints"in str (OOOOOO0O00O0O0OO0 ):#line:111
|
||||
return public .returnMsg (False ,"The network is in use and cannot be deleted!")#line:112
|
||||
return public .returnMsg (False ,"Failed to delete! {}".format (str (OOOOOO0O00O0O0OO0 )))
|
||||
@@ -0,0 +1,135 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
|
||||
import db #line:1
|
||||
import public #line:2
|
||||
import json #line:3
|
||||
def sql (O000O0O0O00000OO0 ):#line:5
|
||||
with db .Sql ()as O000000OOO00O0000 :#line:6
|
||||
O000000OOO00O0000 .dbfile ("docker")#line:7
|
||||
return O000000OOO00O0000 .table (O000O0O0O00000OO0 )#line:8
|
||||
def docker_client (url ="unix:///var/run/docker.sock"):#line:11
|
||||
import docker #line:12
|
||||
"""
|
||||
目前仅支持本地服务器
|
||||
:param url: unix:///var/run/docker.sock
|
||||
:return:
|
||||
"""#line:17
|
||||
try :#line:18
|
||||
O00O00O00000OO0OO =docker .DockerClient (base_url =url )#line:19
|
||||
O00O00O00000OO0OO .networks .list ()#line:20
|
||||
return O00O00O00000OO0OO #line:21
|
||||
except :#line:22
|
||||
return False #line:23
|
||||
def docker_client_low (url ="unix:///var/run/docker.sock"):#line:25
|
||||
""#line:30
|
||||
import docker #line:31
|
||||
try :#line:32
|
||||
O0OO0000000O0OOOO =docker .APIClient (base_url =url )#line:33
|
||||
return O0OO0000000O0OOOO #line:34
|
||||
except docker .errors .DockerException :#line:35
|
||||
return False #line:36
|
||||
def get_cpu_count ():#line:39
|
||||
import re #line:40
|
||||
OOO00O00O0000O00O =open ('/proc/cpuinfo','r').read ()#line:41
|
||||
OO00O0000OO000OOO ="processor\s*:"#line:42
|
||||
OO0OOO0O00O0O0OOO =re .findall (OO00O0000OO000OOO ,OOO00O00O0000O00O )#line:43
|
||||
if not OO0OOO0O00O0O0OOO :#line:44
|
||||
return 0 #line:45
|
||||
return len (OO0OOO0O00O0O0OOO )#line:46
|
||||
def set_kv (OO0OO0OOO0O00O0OO ):#line:48
|
||||
""#line:53
|
||||
if not OO0OO0OOO0O00O0OO :#line:54
|
||||
return None #line:55
|
||||
O00OOOOO0O0OOOO00 =OO0OO0OOO0O00O0OO .split ('\n')#line:56
|
||||
O000OOO0OO00O00OO =dict ()#line:57
|
||||
for OOOOO0OO00OO0O0OO in O00OOOOO0O0OOOO00 :#line:58
|
||||
OOOOO0OO00OO0O0OO =OOOOO0OO00OO0O0OO .strip ()#line:59
|
||||
if not OOOOO0OO00OO0O0OO :#line:60
|
||||
continue #line:61
|
||||
OOO00OO000O000000 ,OO00O0O00000OOO00 =OOOOO0OO00OO0O0OO .split ('=')#line:62
|
||||
O000OOO0OO00O00OO [OOO00OO000O000000 ]=OO00O0O00000OOO00 #line:63
|
||||
return O000OOO0OO00O00OO #line:64
|
||||
def get_mem_info ():#line:66
|
||||
import psutil #line:68
|
||||
O0O0OOO000OO0OOO0 =psutil .virtual_memory ()#line:69
|
||||
O00OOO0O0O00O0O0O =int (O0O0OOO000OO0OOO0 .total )#line:70
|
||||
return O00OOO0O0O00O0O0O #line:71
|
||||
def byte_conversion (OO000000O00OOO0O0 ):#line:73
|
||||
if "b"in OO000000O00OOO0O0 :#line:74
|
||||
return int (OO000000O00OOO0O0 .replace ('b',''))#line:75
|
||||
elif "KB"in OO000000O00OOO0O0 :#line:76
|
||||
return int (OO000000O00OOO0O0 .replace ('KB',''))*1024 #line:77
|
||||
elif "MB"in OO000000O00OOO0O0 :#line:78
|
||||
return int (OO000000O00OOO0O0 .replace ('MB',''))*1024 *1024 #line:79
|
||||
elif "GB"in OO000000O00OOO0O0 :#line:80
|
||||
return int (OO000000O00OOO0O0 .replace ('GB',''))*1024 *1024 *1024 #line:81
|
||||
else :#line:82
|
||||
return False #line:83
|
||||
def log_docker (OO000O00O0OOO0000 ,O0OO0O0O0O0OOO0O0 ):#line:85
|
||||
__OO0000000OO0OO0O0 ='/tmp/dockertmp.log'#line:86
|
||||
while True :#line:87
|
||||
try :#line:88
|
||||
O000O0OOOOO0OOOO0 =OO000O00O0OOO0000 .__next__ ()#line:89
|
||||
try :#line:90
|
||||
O000O0OOOOO0OOOO0 =json .loads (O000O0OOOOO0OOOO0 )#line:91
|
||||
if 'status'in O000O0OOOOO0OOOO0 :#line:92
|
||||
O0OOO00OO0O0OO00O ="{}\n".format (O000O0OOOOO0OOOO0 ['status'])#line:93
|
||||
public .writeFile (__OO0000000OO0OO0O0 ,O0OOO00OO0O0OO00O ,'a+')#line:94
|
||||
except :#line:95
|
||||
public .writeFile (__OO0000000OO0OO0O0 ,public .get_error_info (),'a+')#line:96
|
||||
if 'stream'in O000O0OOOOO0OOOO0 :#line:97
|
||||
O0OOO00OO0O0OO00O =O000O0OOOOO0OOOO0 ['stream']#line:98
|
||||
public .writeFile (__OO0000000OO0OO0O0 ,O0OOO00OO0O0OO00O ,'a+')#line:99
|
||||
except StopIteration :#line:100
|
||||
public .writeFile (__OO0000000OO0OO0O0 ,f'{O0OO0O0O0O0OOO0O0} complete.','a+')#line:101
|
||||
break #line:102
|
||||
except ValueError :#line:103
|
||||
public .writeFile (log_path ,f'Error parsing output from {O0OO0O0O0O0OOO0O0}: {O000O0OOOOO0OOOO0}','a+')#line:104
|
||||
def docker_conf ():#line:106
|
||||
""#line:112
|
||||
OO0OOO0000OO0000O =public .readFile ("{}/data/docker.conf".format (public .get_panel_path ()))#line:113
|
||||
if not OO0OOO0000OO0000O :#line:114
|
||||
return {"SAVE":30 }#line:115
|
||||
O0O0OOOO0000OO0OO =dict ()#line:116
|
||||
for OO0OOO0O0OOO000O0 in OO0OOO0000OO0000O .split ("\n"):#line:117
|
||||
if not OO0OOO0O0OOO000O0 :#line:118
|
||||
continue #line:119
|
||||
O0OOO00O0O0OOOO00 ,OOOO00O0OOO00O00O =OO0OOO0O0OOO000O0 .split ("=")#line:120
|
||||
if O0OOO00O0O0OOOO00 =="SAVE":#line:121
|
||||
OOOO00O0OOO00O00O =int (OOOO00O0OOO00O00O )#line:122
|
||||
O0O0OOOO0000OO0OO [O0OOO00O0O0OOOO00 ]=OOOO00O0OOO00O00O #line:123
|
||||
return O0O0OOOO0000OO0OO #line:124
|
||||
def get_process_id (OOOO0000O00OO00OO ,O0OO0OO0OOO0OOOOO ):#line:126
|
||||
import psutil #line:127
|
||||
OOOO000O0000OO0OO =psutil .pids ()#line:128
|
||||
for OO000O0000OOOO0O0 in OOOO000O0000OO0OO :#line:129
|
||||
try :#line:130
|
||||
O0OOO0000OOOO00O0 =psutil .Process (OO000O0000OOOO0O0 )#line:131
|
||||
if O0OOO0000OOOO00O0 .name ()==OOOO0000O00OO00OO and O0OO0OO0OOO0OOOOO in O0OOO0000OOOO00O0 .cmdline ():#line:132
|
||||
return OO000O0000OOOO0O0 #line:133
|
||||
except :#line:134
|
||||
pass #line:135
|
||||
return False #line:136
|
||||
def write_log (OOO0OO0O0O00OO0O0 ):#line:138
|
||||
public .WriteLog ("Docker module",OOO0OO0O0O00OO0O0 )#line:139
|
||||
def check_socket (O0000O0O000O0O000 ):#line:141
|
||||
import socket #line:142
|
||||
OO0O0O0OO0OO0000O =socket .socket (socket .AF_INET ,socket .SOCK_STREAM )#line:143
|
||||
O0O0OO00OOOO000O0 =("127.0.0.1",int (O0000O0O000O0O000 ))#line:144
|
||||
O000O00OO00O0000O =OO0O0O0OO0OO0000O .connect_ex (O0O0OO00OOOO000O0 )#line:145
|
||||
OO0O0O0OO0OO0000O .close ()#line:146
|
||||
if O000O00OO00O0000O ==0 :#line:147
|
||||
return True #line:148
|
||||
else :#line:149
|
||||
return False
|
||||
@@ -0,0 +1,81 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public #line:1
|
||||
import os #line:2
|
||||
import json #line:3
|
||||
import projectModel .bt_docker .dk_public as dp #line:4
|
||||
class main :#line:6
|
||||
def docker_client (O0OOOO000OOOO0OOO ,O0OO0000O00OO0OO0 ):#line:8
|
||||
return dp .docker_client (O0OO0000O00OO0OO0 )#line:9
|
||||
def add (O0OOO0OO00OO0O0O0 ,OOO0000O0O000O0OO ):#line:11
|
||||
""#line:22
|
||||
if not OOO0000O0O000O0OO .registry :#line:24
|
||||
OOO0000O0O000O0OO .registry ="docker.io"#line:25
|
||||
O000O00O000O0O00O =O0OOO0OO00OO0O0O0 .login (OOO0000O0O000O0OO .url ,OOO0000O0O000O0OO .registry ,OOO0000O0O000O0OO .username ,OOO0000O0O000O0OO .password )#line:26
|
||||
if not O000O00O000O0O00O ['status']:#line:27
|
||||
return O000O00O000O0O00O #line:28
|
||||
O000OO0O00OO00OOO =O0OOO0OO00OO0O0O0 .registry_list ("get")['msg']['registry']#line:29
|
||||
for OOOOOOO0O000O0OOO in O000OO0O00OO00OOO :#line:30
|
||||
if OOOOOOO0O000O0OOO ['name']==OOO0000O0O000O0OO .name :#line:31
|
||||
return public .returnMsg (False ,"Name already exists! <br><br>Name: {}".format (OOO0000O0O000O0OO .name ))#line:32
|
||||
if OOOOOOO0O000O0OOO ['username']==OOO0000O0O000O0OO .username and OOO0000O0O000O0OO .registry ==OOOOOOO0O000O0OOO ['url']:#line:33
|
||||
return public .returnMsg (False ,"The repository information already exists!")#line:34
|
||||
O0OO0000OOO0OO00O ={"name":OOO0000O0O000O0OO .name ,"url":OOO0000O0O000O0OO .registry ,"namespace":OOO0000O0O000O0OO .namespace ,"username":OOO0000O0O000O0OO .username ,"password":OOO0000O0O000O0OO .password ,"remark":OOO0000O0O000O0OO .remark }#line:42
|
||||
dp .sql ("registry").insert (O0OO0000OOO0OO00O )#line:43
|
||||
dp .write_log ("Add repository [{}] [{}] successful!".format (OOO0000O0O000O0OO .name ,OOO0000O0O000O0OO .registry ))#line:44
|
||||
return public .returnMsg (True ,"Added successfully!")#line:45
|
||||
def edit (O0O0O0O000O00OOO0 ,O0O000OO000000OOO ):#line:47
|
||||
""#line:58
|
||||
if str (O0O000OO000000OOO .id )=="1":#line:60
|
||||
return public .returnMsg (False ,"[Docker official repository] cannot be edited!")#line:61
|
||||
if not O0O000OO000000OOO .registry :#line:62
|
||||
O0O000OO000000OOO .registry ="docker.io"#line:63
|
||||
O00O00O0O0O0000OO =O0O0O0O000O00OOO0 .login (O0O000OO000000OOO .url ,O0O000OO000000OOO .registry ,O0O000OO000000OOO .username ,O0O000OO000000OOO .password )#line:64
|
||||
if not O00O00O0O0O0000OO ['status']:#line:65
|
||||
return O00O00O0O0O0000OO #line:66
|
||||
O00O00O0O0O0000OO =dp .sql ("registry").where ("id=?",(O0O000OO000000OOO .id ,)).find ()#line:67
|
||||
if not O00O00O0O0O0000OO :#line:68
|
||||
return public .returnMsg (False ,"This repository was not found")#line:69
|
||||
OO0OOOOO0O000OOOO ={"name":O0O000OO000000OOO .name ,"url":O0O000OO000000OOO .registry ,"username":O0O000OO000000OOO .username ,"password":O0O000OO000000OOO .password ,"namespace":O0O000OO000000OOO .namespace ,"remark":O0O000OO000000OOO .remark }#line:77
|
||||
dp .sql ("registry").where ("id=?",(O0O000OO000000OOO .id ,)).update (OO0OOOOO0O000OOOO )#line:78
|
||||
dp .write_log ("Editing repository [{}][{}] succeeded!".format (O0O000OO000000OOO .name ,O0O000OO000000OOO .registry ))#line:79
|
||||
return public .returnMsg (True ,"Edited successfully!")#line:80
|
||||
def remove (OO0OO00O00OO0O000 ,O0O00O0OO0000OO00 ):#line:82
|
||||
""#line:88
|
||||
if str (O0O00O0OO0000OO00 .id )=="1":#line:89
|
||||
return public .returnMsg (False ,"[Docker official repository] cannot be deleted!")#line:90
|
||||
OO00O0OO00000000O =dp .sql ("registry").where ("id=?",(O0O00O0OO0000OO00 .id )).find ()#line:91
|
||||
dp .sql ("registry").where ("id=?",(O0O00O0OO0000OO00 .id ,)).delete ()#line:92
|
||||
dp .write_log ("Deleting repository [{}][{}] succeeded!".format (OO00O0OO00000000O ['name'],OO00O0OO00000000O ['url']))#line:93
|
||||
return public .returnMsg (True ,"Successfully deleted!")#line:94
|
||||
def registry_list (OO0OOOO0000O00OOO ,O000OO0O00OO0O0OO ):#line:96
|
||||
""#line:100
|
||||
import projectModel .bt_docker .dk_setup as ds #line:101
|
||||
OO0OO0000OO0O0O00 =dp .sql ("registry").select ()#line:102
|
||||
if not isinstance (OO0OO0000OO0O0O00 ,list ):#line:103
|
||||
OO0OO0000OO0O0O00 =[]#line:104
|
||||
OOOO0OO000O000O00 =ds .main ()#line:105
|
||||
OO0O0O0OOO0O0000O ={"registry":OO0OO0000OO0O0O00 ,"installed":OOOO0OO000O000O00 .check_docker_program (),"service_status":OOOO0OO000O000O00 .get_service_status ()}#line:110
|
||||
return public .returnMsg (True ,OO0O0O0OOO0O0000O )#line:111
|
||||
def registry_info (OOO0OO0O0OOOO0O00 ,O0OOO00O0O00000OO ):#line:113
|
||||
return dp .sql ("registry").where ("name=?",(O0OOO00O0O00000OO ,)).find ()#line:114
|
||||
def login (O0O0OO0O000000O00 ,OO00O00O0O0OOOOO0 ,OO0O000O000O00000 ,O0OOO000000000O00 ,O00OO0O00O000OO0O ):#line:116
|
||||
""#line:121
|
||||
import docker .errors #line:122
|
||||
try :#line:123
|
||||
O0OOO0OO00OOOOOO0 =O0O0OO0O000000O00 .docker_client (OO00O00O0O0OOOOO0 ).login (registry =OO0O000O000O00000 ,username =O0OOO000000000O00 ,password =O00OO0O00O000OO0O ,reauth =False )#line:129
|
||||
return public .returnMsg (True ,str (O0OOO0OO00OOOOOO0 ))#line:130
|
||||
except docker .errors .APIError as OOOO0OOO0O00O0000 :#line:131
|
||||
if "unauthorized: incorrect username or password"in str (OOOO0OOO0O00O0000 ):#line:132
|
||||
return public .returnMsg (False ,"Login test failed! <br><br>Reason: The account password is incorrect! {}".format (OOOO0OOO0O00O0000 ))#line:133
|
||||
return public .returnMsg (False ,"Login test failed! <br><br>Reason: {}".format (OOOO0OOO0O00O0000 ))
|
||||
@@ -0,0 +1,67 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import projectModel.bt_docker.dk_public as dp
|
||||
import time
|
||||
|
||||
class main :#line:1
|
||||
def get_status (O00OO00O00O0OO00O ,OOO0000O00O0OOO0O ):#line:3
|
||||
""#line:9
|
||||
O000OO00O0O0OOO0O =dict ()#line:10
|
||||
O000OO00O0O0OOO0O ['container_count']=O00OO00O00O0OO00O .__O0OO000000O0OO0O0 (OOO0000O00O0OOO0O )#line:12
|
||||
O000OO00O0O0OOO0O ['image_info']=dp .sql ("image_infos").where ("time>=? and time<=?",(OOO0000O00O0OOO0O .start_time ,OOO0000O00O0OOO0O .stop_time )).select ()#line:14
|
||||
O000OO00O0O0OOO0O ['host']=len (dp .sql ('hosts').select ())#line:16
|
||||
O000OO00O0O0OOO0O ['container_top']={"cpu":O00OO00O00O0OO00O .__OO0OOO00O0OOO0OOO (),"mem":O00OO00O00O0OO00O .__O0OO00OOO00O00OOO ()}#line:18
|
||||
return O000OO00O0O0OOO0O #line:19
|
||||
def __O0OO000000O0OO0O0 (OOOO0OO0O00O0OOOO ,OO0OO0OO000O00O0O ):#line:21
|
||||
O0OOO000O0OOOO0O0 =dp .sql ('container_count').where ("time>=? and time<=?",(OO0OO0OO000O00O0O .start_time ,OO0OO0OO000O00O0O .stop_time )).select ()#line:22
|
||||
if not O0OOO000O0OOOO0O0 :#line:23
|
||||
return 0 #line:24
|
||||
return O0OOO000O0OOOO0O0 [-1 ]#line:25
|
||||
def __O0OO00OOO00O00OOO (OOO0OOO0O00OOOOO0 ):#line:27
|
||||
O000OO0O00O0O00OO =int (time .time ())#line:28
|
||||
O0OO0O0OO0O00O0O0 =O000OO0O00O0O00OO -3600 #line:29
|
||||
OO0O000OO00OO0OOO =dp .sql ("mem_stats").where ("time>=? and time<=?",(O0OO0O0OO0O00O0O0 ,O000OO0O00O0O00OO )).select ()#line:30
|
||||
O000O0OO00OOOO0O0 =list ()#line:31
|
||||
O0O0O000OO00OOOOO =dict ()#line:32
|
||||
for O00OOOO0OOOO00000 in OO0O000OO00OO0OOO :#line:34
|
||||
O000O0OO00OOOO0O0 .append (O00OOOO0OOOO00000 ['container_id'])#line:35
|
||||
O000O0OO00OOOO0O0 =set (O000O0OO00OOOO0O0 )#line:37
|
||||
for OO0O0OO000OO0OO00 in O000O0OO00OOOO0O0 :#line:38
|
||||
OO0000OOOOOOOO000 =0 #line:39
|
||||
OO0000O00O000000O =0 #line:40
|
||||
for O00OOOO0OOOO00000 in OO0O000OO00OO0OOO :#line:41
|
||||
if O00OOOO0OOOO00000 ['container_id']==OO0O0OO000OO0OO00 :#line:42
|
||||
OO0000OOOOOOOO000 +=1 #line:43
|
||||
OO0000O00O000000O +=float (O00OOOO0OOOO00000 ['usage'])#line:44
|
||||
if OO0000OOOOOOOO000 !=0 :#line:45
|
||||
O0O0O000OO00OOOOO [OO0O0OO000OO0OO00 ]=OO0000O00O000000O /OO0000OOOOOOOO000 #line:46
|
||||
return O0O0O000OO00OOOOO #line:47
|
||||
def __OO0OOO00O0OOO0OOO (O0O0O0O000OOO000O ):#line:49
|
||||
O0O0OO0OO00OO0000 =int (time .time ())#line:50
|
||||
OO000OOO00OO0OOO0 =O0O0OO0OO00OO0000 -3600 #line:51
|
||||
OO000O0OOOO0OO00O =dp .sql ("cpu_stats").where ("time>=? and time<=?",(OO000OOO00OO0OOO0 ,O0O0OO0OO00OO0000 )).select ()#line:52
|
||||
OOO00O00O0OO0O0OO =list ()#line:53
|
||||
OO0OOOOOO000OO000 =dict ()#line:54
|
||||
for O0000O0O0000O0OOO in OO000O0OOOO0OO00O :#line:56
|
||||
OOO00O00O0OO0O0OO .append (O0000O0O0000O0OOO ['container_id'])#line:57
|
||||
OOO00O00O0OO0O0OO =set (OOO00O00O0OO0O0OO )#line:59
|
||||
for OO0OO00OOOOOO0O0O in OOO00O00O0OO0O0OO :#line:60
|
||||
OO00O0000000OO0OO =0 #line:61
|
||||
OO0OOOO0OOOO000O0 =0 #line:62
|
||||
for O0000O0O0000O0OOO in OO000O0OOOO0OO00O :#line:63
|
||||
if O0000O0O0000O0OOO ['container_id']==OO0OO00OOOOOO0O0O :#line:64
|
||||
OO00O0000000OO0OO +=1 #line:65
|
||||
OO0OOOO0OOOO000O0 +=float (0 if O0000O0O0000O0OOO ['cpu_usage']=='0.0'else O0000O0O0000O0OOO ['cpu_usage'])#line:66
|
||||
if OO00O0000000OO0OO !=0 :#line:67
|
||||
OO0OOOOOO000OO000 [OO0OO00OOOOOO0O0O ]=OO0OOOO0OOOO000O0 /OO00O0000000OO0OO #line:68
|
||||
return OO0OOOOOO000OO000
|
||||
@@ -0,0 +1,155 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
|
||||
import os
|
||||
import json
|
||||
import public
|
||||
import projectModel.bt_docker.dk_public as dp
|
||||
|
||||
class main :#line:1
|
||||
def get_config (O0OO0OO0O0OOO0OOO ,O0OOOO000OOOO0000 ):#line:3
|
||||
import projectModel .bt_docker .dk_public as dp #line:4
|
||||
O00O0OOO0O0O0OO00 =O0OO0OO0O0OOO0OOO .get_registry_mirrors (O0OOOO000OOOO0000 )#line:6
|
||||
if not O00O0OOO0O0O0OO00 ["status"]:#line:7
|
||||
return O00O0OOO0O0O0OO00 #line:8
|
||||
else :#line:9
|
||||
O00O0OOO0O0O0OO00 =O00O0OOO0O0O0OO00 ['msg']#line:10
|
||||
OOO00O00O00000000 =O0OO0OO0O0OOO0OOO .get_service_status ()#line:11
|
||||
return public .returnMsg (True ,{"registry_mirrors":O00O0OOO0O0O0OO00 ,"service_status":OOO00O00O00000000 ,"installed":O0OO0OO0O0OOO0OOO .check_docker_program (),"monitor_status":O0OO0OO0O0OOO0OOO .get_monitor_status (),"monitor_save_date":dp .docker_conf ()['SAVE']})#line:18
|
||||
def set_monitor_save_date (O0OO0000000O0OO0O ,OO0OO0O0O00OO0OOO ):#line:20
|
||||
""#line:25
|
||||
import re #line:26
|
||||
OOOO0O0OO00O00O00 ="{}/data/docker.conf".format (public .get_panel_path ())#line:27
|
||||
O00OO000O0OO0000O =public .readFile (OOOO0O0OO00O00O00 )#line:28
|
||||
try :#line:29
|
||||
OOO00O0000000OO0O =int (OO0OO0O0O00OO0OOO .save_date )#line:30
|
||||
except :#line:31
|
||||
return public .returnMsg (False ,"The monitoring save time needs to be a positive integer!")#line:32
|
||||
if OOO00O0000000OO0O >999 :#line:33
|
||||
return public .returnMsg (False ,"Monitoring data cannot be retained for more than 999 days!")#line:34
|
||||
if not O00OO000O0OO0000O :#line:35
|
||||
O00OO000O0OO0000O ="SAVE={}".format (OOO00O0000000OO0O )#line:36
|
||||
public .writeFile (OOOO0O0OO00O00O00 ,O00OO000O0OO0000O )#line:37
|
||||
return public .returnMsg (True ,"Set up successfully!")#line:38
|
||||
O00OO000O0OO0000O =re .sub ("SAVE\s*=\s*\d+","SAVE={}".format (OOO00O0000000OO0O ),O00OO000O0OO0000O )#line:39
|
||||
public .writeFile (OOOO0O0OO00O00O00 ,O00OO000O0OO0000O )#line:40
|
||||
dp .write_log ("Set the monitoring time to [] days!".format (OOO00O0000000OO0O ))#line:41
|
||||
return public .returnMsg (True ,"Set up successfully!")#line:42
|
||||
def get_service_status (OO0O0OOOO00O0000O ):#line:44
|
||||
import projectModel .bt_docker .dk_public as dp #line:45
|
||||
OOOO0OO00O00O0O0O ='/var/run/docker.pid'#line:46
|
||||
if os .path .exists (OOOO0OO00O00O0O0O ):#line:47
|
||||
try :#line:48
|
||||
O0O0O0OOO0OO0OOOO =dp .docker_client ()#line:49
|
||||
if O0O0O0OOO0OO0OOOO :#line:50
|
||||
return True #line:51
|
||||
else :#line:52
|
||||
return False #line:53
|
||||
except :#line:54
|
||||
return False #line:55
|
||||
else :#line:56
|
||||
return False #line:57
|
||||
def docker_service (O00OOO000O0000O0O ,OOO00OO000000OOOO ):#line:60
|
||||
""#line:65
|
||||
import public #line:66
|
||||
O000O0OOO0O0O000O ={'start':'start','stop':'stop','restart':'restart'}#line:67
|
||||
if OOO00OO000000OOOO .act not in O000O0OOO0O0O000O :#line:68
|
||||
return public .returnMsg (False ,'There is no way to do this!')#line:69
|
||||
O0000OO0O0OOOOOO0 ='systemctl {} docker'.format (OOO00OO000000OOOO .act )#line:70
|
||||
if OOO00OO000000OOOO .act =="stop":#line:71
|
||||
O0000OO0O0OOOOOO0 +="&& systemctl {} docker.socket".format (OOO00OO000000OOOO .act )#line:72
|
||||
public .ExecShell (O0000OO0O0OOOOOO0 )#line:73
|
||||
dp .write_log ("Set the Docker service status to [{}] successful".format (O000O0OOO0O0O000O [OOO00OO000000OOOO .act ]))#line:74
|
||||
return public .returnMsg (True ,"Set the status to [{}] successful".format (O000O0OOO0O0O000O [OOO00OO000000OOOO .act ]))#line:75
|
||||
def get_registry_mirrors (O000O0OO0O00O0000 ,OO00O0OOO000O00O0 ):#line:78
|
||||
try :#line:79
|
||||
if not os .path .exists ('/etc/docker/daemon.json'):#line:80
|
||||
return public .returnMsg (True ,[])#line:81
|
||||
O00000OOOOOOOO0O0 =json .loads (public .readFile ('/etc/docker/daemon.json'))#line:82
|
||||
if "registry-mirrors"not in O00000OOOOOOOO0O0 :#line:83
|
||||
return public .returnMsg (True ,[])#line:84
|
||||
return public .returnMsg (True ,O00000OOOOOOOO0O0 ['registry-mirrors'])#line:85
|
||||
except :#line:86
|
||||
return public .returnMsg (False ,'Get failed! Reason for failure: {}'.format (public .get_error_info ()))#line:87
|
||||
def set_registry_mirrors (OO0OO0000OO0OOOO0 ,OOOO000OO0O00O000 ):#line:90
|
||||
""#line:95
|
||||
import re #line:96
|
||||
try :#line:97
|
||||
O0000O0O0O000O00O ={}#line:98
|
||||
if os .path .exists ('/etc/docker/daemon.json'):#line:99
|
||||
O0000O0O0O000O00O =json .loads (public .readFile ('/etc/docker/daemon.json'))#line:100
|
||||
if not OOOO000OO0O00O000 .registry_mirrors_address .strip ():#line:101
|
||||
if 'registry-mirrors'not in O0000O0O0O000O00O :#line:103
|
||||
return public .returnMsg (True ,'Set successfully')#line:104
|
||||
del (O0000O0O0O000O00O ['registry-mirrors'])#line:105
|
||||
else :#line:106
|
||||
O0O0O0O00OOOO0O0O =OOOO000OO0O00O000 .registry_mirrors_address .strip ().split ('\n')#line:107
|
||||
for O0000OOO0OO0000O0 in O0O0O0O00OOOO0O0O :#line:108
|
||||
if not re .search ('https?://',O0000OOO0OO0000O0 ):#line:109
|
||||
return public .returnMsg (False ,'The acceleration address [{}] is malformed<br>Reference: https://mirror.ccs.tencentyun.com'.format (O0000OOO0OO0000O0 ))#line:110
|
||||
O0000O0O0O000O00O ['registry-mirrors']=O0O0O0O00OOOO0O0O #line:112
|
||||
public .writeFile ('/etc/docker/daemon.json',json .dumps (O0000O0O0O000O00O ,indent =2 ))#line:115
|
||||
dp .write_log ("Set up Docker acceleration successfully!")#line:116
|
||||
return public .returnMsg (True ,'Set successfully')#line:117
|
||||
except :#line:118
|
||||
return public .returnMsg (False ,'Setup failed! Reason for failure:{}'.format (public .get_error_info ()))#line:119
|
||||
def get_monitor_status (OO0O00O0OO0O0O000 ):#line:121
|
||||
""#line:124
|
||||
O00O000O00OO00000 =public .process_exists ("python",cmdline ="/www/server/panel/class/projectModel/bt_docker/dk_monitor.py")#line:126
|
||||
if O00O000O00OO00000 :#line:127
|
||||
return O00O000O00OO00000 #line:128
|
||||
O00O000O00OO00000 =public .process_exists ("python3",cmdline ="/www/server/panel/class/projectModel/bt_docker/dk_monitor.py")#line:129
|
||||
if O00O000O00OO00000 :#line:130
|
||||
return O00O000O00OO00000 #line:131
|
||||
return O00O000O00OO00000 #line:132
|
||||
def set_docker_monitor (OO0OOOOOOO0O00OO0 ,O0O0O0000O0OOO000 ):#line:134
|
||||
""#line:139
|
||||
import time #line:140
|
||||
import projectModel .bt_docker .dk_public as dp #line:141
|
||||
OOO000O0O0O0OOOO0 ="/www/server/panel/pyenv/bin/python"#line:142
|
||||
if not os .path .exists (OOO000O0O0O0OOOO0 ):#line:143
|
||||
OOO000O0O0O0OOOO0 ="/www/server/panel/pyenv/bin/python3"#line:144
|
||||
O0O000O0O00O0O000 ="/www/server/panel/class/projectModel/bt_docker/dk_monitor.py"#line:145
|
||||
if O0O0O0000O0OOO000 .act =="start":#line:146
|
||||
OOO0O00OO0OO0O00O ="nohup {} {} &".format (OOO000O0O0O0OOOO0 ,O0O000O0O00O0O000 )#line:147
|
||||
public .ExecShell (OOO0O00OO0OO0O00O )#line:148
|
||||
time .sleep (1 )#line:149
|
||||
if OO0OOOOOOO0O00OO0 .get_monitor_status ():#line:150
|
||||
dp .write_log ("Docker monitoring started successfully!")#line:151
|
||||
return public .returnMsg (True ,"Start monitoring successfully!")#line:152
|
||||
return public .returnMsg (False ,"Failed to start monitoring!")#line:153
|
||||
else :#line:154
|
||||
O0O0OOOOOOOO0O0OO =dp .get_process_id ("python","/www/server/panel/class/projectModel/bt_docker/dk_monitor.py")#line:155
|
||||
if not O0O0OOOOOOOO0O0OO :#line:156
|
||||
O0O0OOOOOOOO0O0OO =dp .get_process_id ("python3","/www/server/panel/class/projectModel/bt_docker/dk_monitor.py")#line:157
|
||||
public .ExecShell ("kill -9 {}".format (O0O0OOOOOOOO0O0OO ))#line:158
|
||||
dp .write_log ("Docker monitoring stopped successfully!")#line:159
|
||||
return public .returnMsg (True ,"Stop monitoring successfully!")#line:160
|
||||
def check_docker_program (O0O00O00OOOO0O000 ):#line:162
|
||||
""#line:166
|
||||
O0O0O00O000OOO000 ="/usr/bin/docker"#line:167
|
||||
O00OO00OO0OOOOOO0 ="/usr/bin/docker-compose"#line:168
|
||||
if not os .path .exists (O0O0O00O000OOO000 )or not os .path .exists (O00OO00OO0OOOOOO0 ):#line:169
|
||||
return False #line:170
|
||||
return True #line:171
|
||||
def install_docker_program (OOO0000OOO0O0O0O0 ,O0O000O0OO000OO0O ):#line:173
|
||||
""#line:178
|
||||
import time #line:179
|
||||
O000O000O0OO00O00 ="Install Docker service"#line:180
|
||||
O00O000OOOOOOO000 ="/bin/bash /www/server/panel/install/install_soft.sh 0 install docker_install_en"#line:183
|
||||
public .M ('tasks').add ('id,name,type,status,addtime,execstr',(None ,O000O000O0OO00O00 ,'execshell','0',time .strftime ('%Y-%m-%d %H:%M:%S'),O00O000OOOOOOO000 ))#line:184
|
||||
public .httpPost (public .GetConfigValue ('home')+'/api/panel/plugin_total',{"pid":"1111111",'p_name':"Docker商用模块"},3 )#line:185
|
||||
public.arequests('post', 'https://www.aapanel.com/api/setupCount/setupPlugin',
|
||||
data={"pid": "1111111", 'p_name': "Dockerpaymodel"}, timeout=3)
|
||||
|
||||
return public .returnMsg (True ,"Install task added to queue!")#line:186
|
||||
@@ -0,0 +1,160 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public #line:13
|
||||
import time #line:14
|
||||
import projectModel .bt_docker .dk_public as dp #line:15
|
||||
class main :#line:18
|
||||
__OOOO00OOO0O00O0O0 =dict ()#line:20
|
||||
__OO0O0O00OO0OOO000 =None #line:21
|
||||
def docker_client (OOOOOO000OOOO0OOO ,OO0OOO0O0O00O0000 ):#line:23
|
||||
if not OOOOOO000OOOO0OOO .__OO0O0O00OO0OOO000 :#line:24
|
||||
OOOOOO000OOOO0OOO .__OO0O0O00OO0OOO000 =dp .docker_client (OO0OOO0O0O00O0000 )#line:25
|
||||
return OOOOOO000OOOO0OOO .__OO0O0O00OO0OOO000 #line:26
|
||||
def io_stats (O00OOOOO000OO00OO ,O00O0OO0000OO0O0O ,write =None ):#line:28
|
||||
O0O0OO0OOO0OO0000 =O00O0OO0000OO0O0O ['blkio_stats']['io_service_bytes_recursive']#line:29
|
||||
if len (O0O0OO0OOO0OO0000 )<=2 :#line:30
|
||||
try :#line:31
|
||||
O0OO0OO0O000OOOOO =O0O0OO0OOO0OO0000 [0 ]['value']#line:32
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['read_total']=O0OO0OO0O000OOOOO #line:33
|
||||
except :#line:34
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['read_total']=0 #line:35
|
||||
try :#line:36
|
||||
O0OO0OO0O000OOOOO =O0O0OO0OOO0OO0000 [1 ]['value']#line:37
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['write_total']=O0OO0OO0O000OOOOO #line:38
|
||||
except :#line:39
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['write_total']=0 #line:40
|
||||
else :#line:41
|
||||
try :#line:42
|
||||
O0OO0OO0O000OOOOO =O0O0OO0OOO0OO0000 [0 ]['value']+O0O0OO0OOO0OO0000 [2 ]['value']#line:43
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['read_total']=O0OO0OO0O000OOOOO #line:44
|
||||
except :#line:45
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['read_total']=0 #line:46
|
||||
try :#line:47
|
||||
O0OO0OO0O000OOOOO =O0O0OO0OOO0OO0000 [1 ]['value']+O0O0OO0OOO0OO0000 [3 ]['value']#line:48
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['write_total']=O0OO0OO0O000OOOOO #line:49
|
||||
except :#line:50
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['write_total']=0 #line:51
|
||||
if write :#line:52
|
||||
O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 ['container_id']=O00O0OO0000OO0O0O ['id']#line:53
|
||||
O00OOOOO000OO00OO .write_io (O00OOOOO000OO00OO .__OOOO00OOO0O00O0O0 )#line:54
|
||||
def net_stats (OOO0000O0O0O00O0O ,O0O0OOO00O0000OOO ,OO0O0O000OOO000OO ,write =None ):#line:56
|
||||
try :#line:57
|
||||
OO00OOOO0O0000OOO =O0O0OOO00O0000OOO ['networks']['eth0']#line:58
|
||||
OOO00O00O0O00OOOO =OO0O0O000OOO000OO ['networks']['eth0']#line:59
|
||||
except :#line:60
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx_total']=0 #line:61
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx']=0 #line:62
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx_total']=0 #line:63
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx']=0 #line:64
|
||||
if write :#line:65
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['container_id']=O0O0OOO00O0000OOO ['id']#line:66
|
||||
OOO0000O0O0O00O0O .write_net (OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 )#line:67
|
||||
return #line:68
|
||||
O0000OO00OO0OOO00 =O0O0OOO00O0000OOO ["time"]#line:69
|
||||
O0000OO0OO0OOOOOO =OO0O0O000OOO000OO ["time"]#line:70
|
||||
try :#line:71
|
||||
O0O000O00O0OO0OO0 =OO00OOOO0O0000OOO ["rx_bytes"]#line:72
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx_total']=O0O000O00O0OO0OO0 #line:73
|
||||
O0000OOO0OO00OOO0 =OOO00O00O0O00OOOO ["rx_bytes"]#line:74
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx']=int ((O0O000O00O0OO0OO0 -O0000OOO0OO00OOO0 )/(O0000OO00OO0OOO00 -O0000OO0OO0OOOOOO ))#line:75
|
||||
except :#line:76
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx_total']=0 #line:77
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['rx']=0 #line:78
|
||||
try :#line:79
|
||||
O0O000O00O0OO0OO0 =OO00OOOO0O0000OOO ["tx_bytes"]#line:80
|
||||
O0000OOO0OO00OOO0 =OOO00O00O0O00OOOO ["tx_bytes"]#line:81
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx_total']=O0O000O00O0OO0OO0 #line:82
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx']=int ((O0O000O00O0OO0OO0 -O0000OOO0OO00OOO0 )/(O0000OO00OO0OOO00 -O0000OO0OO0OOOOOO ))#line:83
|
||||
except :#line:84
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx_total']=0 #line:85
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['tx']=0 #line:86
|
||||
if write :#line:87
|
||||
OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 ['container_id']=O0O0OOO00O0000OOO ['id']#line:88
|
||||
OOO0000O0O0O00O0O .write_net (OOO0000O0O0O00O0O .__OOOO00OOO0O00O0O0 )#line:89
|
||||
def mem_stats (O0OO000OOO0O0O000 ,O00OOO0OO00OOO000 ,write =None ):#line:92
|
||||
OOO0000OO0OOO000O =O00OOO0OO00OOO000 ['memory_stats']#line:93
|
||||
try :#line:94
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['limit']=OOO0000OO0OOO000O ['limit']#line:95
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['usage_total']=OOO0000OO0OOO000O ['usage']#line:96
|
||||
if 'cache'not in OOO0000OO0OOO000O ['stats']:#line:97
|
||||
OOO0000OO0OOO000O ['stats']['cache']=0 #line:98
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['usage']=OOO0000OO0OOO000O ['usage']-OOO0000OO0OOO000O ['stats']['cache']#line:99
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['cache']=OOO0000OO0OOO000O ['stats']['cache']#line:100
|
||||
except :#line:102
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['limit']=0 #line:104
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['usage']=0 #line:105
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['cache']=0 #line:106
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['usage_total']=0 #line:107
|
||||
if write :#line:109
|
||||
O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 ['container_id']=O00OOO0OO00OOO000 ['id']#line:110
|
||||
O0OO000OOO0O0O000 .write_mem (O0OO000OOO0O0O000 .__OOOO00OOO0O00O0O0 )#line:111
|
||||
def cpu_stats (OO0OO000OO000O000 ,OO0000OOO00OO0O0O ,write =None ):#line:114
|
||||
try :#line:120
|
||||
OOOOO0O0OO0O00O0O =OO0000OOO00OO0O0O ['cpu_stats']['cpu_usage']['total_usage']-OO0000OOO00OO0O0O ['precpu_stats']['cpu_usage']['total_usage']#line:121
|
||||
except :#line:122
|
||||
OOOOO0O0OO0O00O0O =0 #line:123
|
||||
try :#line:124
|
||||
OO00000O0O0OO0O00 =OO0000OOO00OO0O0O ['cpu_stats']['system_cpu_usage']-OO0000OOO00OO0O0O ['precpu_stats']['system_cpu_usage']#line:125
|
||||
except :#line:126
|
||||
OO00000O0O0OO0O00 =0 #line:127
|
||||
try :#line:128
|
||||
OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['online_cpus']=OO0000OOO00OO0O0O ['cpu_stats']['online_cpus']#line:129
|
||||
except :#line:130
|
||||
OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['online_cpus']=0 #line:131
|
||||
if OOOOO0O0OO0O00O0O >0 and OO00000O0O0OO0O00 >0 :#line:132
|
||||
OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['cpu_usage']=round ((OOOOO0O0OO0O00O0O /OO00000O0O0OO0O00 )*100 *OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['online_cpus'],2 )#line:133
|
||||
else :#line:134
|
||||
OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['cpu_usage']=0.0 #line:135
|
||||
if write :#line:136
|
||||
OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 ['container_id']=OO0000OOO00OO0O0O ['id']#line:137
|
||||
OO0OO000OO000O000 .write_cpu (OO0OO000OO000O000 .__OOOO00OOO0O00O0O0 )#line:138
|
||||
def stats (OO0OOOO00OO0OO000 ,OO00OO0OO00OOO0O0 ):#line:141
|
||||
""#line:148
|
||||
OOOOO00O00000OOO0 =OO0OOOO00OO0OO000 .docker_client (OO00OO0OO00OOO0O0 .url ).containers .get (OO00OO0OO00OOO0O0 .id )#line:149
|
||||
O00O0OOOO000O0O0O =OOOOO00O00000OOO0 .stats (decode =None ,stream =False )#line:150
|
||||
O00O0OOOO000O0O0O ['time']=time .time ()#line:151
|
||||
OOOOOOOOO0OO0O00O =public .cache_get ('stats')#line:152
|
||||
if not OOOOOOOOO0OO0O00O :#line:153
|
||||
OOOOOOOOO0OO0O00O =O00O0OOOO000O0O0O #line:154
|
||||
public .cache_set ('stats',O00O0OOOO000O0O0O )#line:155
|
||||
OOO000O0000O0OO0O =None #line:156
|
||||
if hasattr (OO00OO0OO00OOO0O0 ,"write"):#line:157
|
||||
OOO000O0000O0OO0O =OO00OO0OO00OOO0O0 .write #line:158
|
||||
OO0OOOO00OO0OO000 .__OOOO00OOO0O00O0O0 ['expired']=time .time ()-(OO00OO0OO00OOO0O0 .save_date *86400 )#line:159
|
||||
O00O0OOOO000O0O0O ['id']=OO00OO0OO00OOO0O0 .id #line:160
|
||||
OO0OOOO00OO0OO000 .io_stats (O00O0OOOO000O0O0O ,OOO000O0000O0OO0O )#line:161
|
||||
OO0OOOO00OO0OO000 .net_stats (O00O0OOOO000O0O0O ,OOOOOOOOO0OO0O00O ,OOO000O0000O0OO0O )#line:162
|
||||
OO0OOOO00OO0OO000 .cpu_stats (O00O0OOOO000O0O0O ,OOO000O0000O0OO0O )#line:163
|
||||
OO0OOOO00OO0OO000 .mem_stats (O00O0OOOO000O0O0O ,OOO000O0000O0OO0O )#line:164
|
||||
public .cache_set ('stats',O00O0OOOO000O0O0O )#line:165
|
||||
OO0OOOO00OO0OO000 .__OOOO00OOO0O00O0O0 ['detail']=O00O0OOOO000O0O0O #line:166
|
||||
return public .returnMsg (True ,OO0OOOO00OO0OO000 .__OOOO00OOO0O00O0O0 )#line:167
|
||||
def write_cpu (O0OOO000OOOO00OO0 ,OO0O0O0OO0OOO0000 ):#line:169
|
||||
OOOO0OO0OOOO00O00 ={"time":time .time (),"cpu_usage":OO0O0O0OO0OOO0000 ['cpu_usage'],"online_cpus":OO0O0O0OO0OOO0000 ['online_cpus'],"container_id":OO0O0O0OO0OOO0000 ['container_id']}#line:175
|
||||
dp .sql ("cpu_stats").where ("time<?",(O0OOO000OOOO00OO0 .__OOOO00OOO0O00O0O0 ['expired'],)).delete ()#line:176
|
||||
dp .sql ("cpu_stats").insert (OOOO0OO0OOOO00O00 )#line:177
|
||||
def write_io (OOOO00O0O00OO0OO0 ,OOOOO000OOOOO00O0 ):#line:179
|
||||
O000OO0O000OOOOOO ={"time":time .time (),"write_total":OOOOO000OOOOO00O0 ['write_total'],"read_total":OOOOO000OOOOO00O0 ['read_total'],"container_id":OOOOO000OOOOO00O0 ['container_id']}#line:185
|
||||
dp .sql ("io_stats").where ("time<?",(OOOO00O0O00OO0OO0 .__OOOO00OOO0O00O0O0 ['expired'],)).delete ()#line:186
|
||||
dp .sql ("io_stats").insert (O000OO0O000OOOOOO )#line:187
|
||||
def write_net (O0000000OO0O00OO0 ,O0O0O00O0OO0OO0O0 ):#line:189
|
||||
O00O00OO0OO0OOOOO ={"time":time .time (),"tx_total":O0O0O00O0OO0OO0O0 ['tx_total'],"rx_total":O0O0O00O0OO0OO0O0 ['rx_total'],"tx":O0O0O00O0OO0OO0O0 ['tx'],"rx":O0O0O00O0OO0OO0O0 ['rx'],"container_id":O0O0O00O0OO0OO0O0 ['container_id']}#line:197
|
||||
dp .sql ("net_stats").where ("time<?",(O0000000OO0O00OO0 .__OOOO00OOO0O00O0O0 ['expired'],)).delete ()#line:198
|
||||
dp .sql ("net_stats").insert (O00O00OO0OO0OOOOO )#line:199
|
||||
def write_mem (OO0O00O0O000O00OO ,O0000OO0O0OOO00OO ):#line:201
|
||||
O00OOOOOOO000O00O ={"time":time .time (),"mem_limit":O0000OO0O0OOO00OO ['limit'],"cache":O0000OO0O0OOO00OO ['cache'],"usage":O0000OO0O0OOO00OO ['usage'],"usage_total":O0000OO0O0OOO00OO ['usage_total'],"container_id":O0000OO0O0OOO00OO ['container_id']}#line:209
|
||||
dp .sql ("mem_stats").where ("time<?",(OO0O00O0O000O00OO .__OOOO00OOO0O00O0O0 ['expired'],)).delete ()#line:210
|
||||
dp .sql ("mem_stats").insert (O00OOOOOOO000O00O )#line:211
|
||||
def get_container_count (O0OO00O0OOO0O0000 ,OO0OOOOOO0OO0O0OO ):#line:214
|
||||
O0O00OO0O0OOOO000 =OO0OOOOOO0OO0O0OO .url #line:215
|
||||
return len (O0OO00O0OOO0O0000 .docker_client (O0O00OO0O0OOOO000 ).containers .list ())#line:216
|
||||
@@ -0,0 +1,73 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# Docker模型
|
||||
#------------------------------
|
||||
import public
|
||||
import projectModel.bt_docker.dk_public as dp
|
||||
import docker.errors
|
||||
|
||||
class main :#line:1
|
||||
__O0O0O00O00OOO00O0 =None #line:3
|
||||
def docker_client (OO0000OOOO0O00000 ,O00000O0O00OO0O0O ):#line:5
|
||||
import projectModel .bt_docker .dk_public as dp #line:6
|
||||
return dp .docker_client (O00000O0O00OO0O0O )#line:7
|
||||
def get_volume_container_name (O0O000O0OOO00O0O0 ,O0O00OOOOO0O0O00O ):#line:10
|
||||
OO000OO00OOOOOOO0 =O0O000O0OOO00O0O0 .docker_client (O0O000O0OOO00O0O0 .__O0O0O00O00OOO00O0 ).containers #line:11
|
||||
O0O0OOOO00000OO0O =OO000OO00OOOOOOO0 .list (all =True )#line:12
|
||||
O0000O00OOOO00O00 =[O000OO00OOOO00O0O .attrs for O000OO00OOOO00O0O in O0O0OOOO00000OO0O ]#line:14
|
||||
for O00OOO00000OO0OOO in O0000O00OOOO00O00 :#line:15
|
||||
if not O00OOO00000OO0OOO ['Mounts']:#line:16
|
||||
continue #line:17
|
||||
for O0O00O0O0OOO000OO in O00OOO00000OO0OOO ['Mounts']:#line:18
|
||||
if "Name"not in O0O00O0O0OOO000OO :#line:19
|
||||
continue #line:20
|
||||
if O0O00OOOOO0O0O00O ['Name']==O0O00O0O0OOO000OO ['Name']:#line:21
|
||||
O0O00OOOOO0O0O00O ['container']=O00OOO00000OO0OOO ['Name'].replace ("/","")#line:22
|
||||
if 'container'not in O0O00OOOOO0O0O00O :#line:23
|
||||
O0O00OOOOO0O0O00O ['container']=''#line:24
|
||||
return O0O00OOOOO0O0O00O #line:25
|
||||
def get_volume_list (O0O0OOO0OO000000O ,OO0OO0O0OOOO0OO0O ):#line:27
|
||||
""#line:31
|
||||
import projectModel .bt_docker .dk_setup as ds #line:32
|
||||
O0O0OOO0OO000000O .__O0O0O00O00OOO00O0 =OO0OO0O0OOOO0OO0O .url #line:33
|
||||
O0O0O0OOO0OOO0O00 =O0O0OOO0OO000000O .docker_client (OO0OO0O0OOOO0OO0O .url )#line:34
|
||||
O0O000O0OOOOOO00O =ds .main ()#line:35
|
||||
OO0OO00000OOOOOO0 =O0O000O0OOOOOO00O .check_docker_program ()#line:36
|
||||
OOOOO0OOOO000OOOO =O0O000O0OOOOOO00O .get_service_status ()#line:37
|
||||
if not O0O0O0OOO0OOO0O00 :#line:38
|
||||
O000O0000OOO000OO ={"volume":[],"installed":OO0OO00000OOOOOO0 ,"service_status":OOOOO0OOOO000OOOO }#line:43
|
||||
return public .returnMsg (True ,O000O0000OOO000OO )#line:44
|
||||
OO00O00OOO0O000O0 =O0O0O0OOO0OOO0O00 .volumes #line:45
|
||||
O000O0000OOO000OO ={"volume":O0O0OOO0OO000000O .get_volume_attr (OO00O00OOO0O000O0 ),"installed":OO0OO00000OOOOOO0 ,"service_status":OOOOO0OOOO000OOOO }#line:51
|
||||
return public .returnMsg (True ,O000O0000OOO000OO )#line:52
|
||||
def get_volume_attr (O00O000OO00000O00 ,O0O0OO0OO0OO0O0OO ):#line:54
|
||||
OOO00O0O0000O0O0O =O0O0OO0OO0OO0O0OO .list ()#line:55
|
||||
O00O00OOOOO00O000 =list ()#line:56
|
||||
for OO0OOOOOOOOO0OO00 in OOO00O0O0000O0O0O :#line:57
|
||||
OO0OOOOOOOOO0OO00 =O00O000OO00000O00 .get_volume_container_name (OO0OOOOOOOOO0OO00 .attrs )#line:58
|
||||
O00O00OOOOO00O000 .append (OO0OOOOOOOOO0OO00 )#line:59
|
||||
return O00O00OOOOO00O000 #line:60
|
||||
def add (O000O0OOOO0O0OOOO ,O0OO00O0O0OO0O0OO ):#line:62
|
||||
""#line:70
|
||||
O000O0OOOO0O0OOOO .docker_client (O0OO00O0O0OO0O0OO .url ).volumes .create (name =O0OO00O0O0OO0O0OO .name ,driver =O0OO00O0O0OO0O0OO .driver ,driver_opts =O0OO00O0O0OO0O0OO .driver_opts if O0OO00O0O0OO0O0OO .driver_opts else None ,labels =dp .set_kv (O0OO00O0O0OO0O0OO .labels ))#line:76
|
||||
dp .write_log ("Adding storage volume [[]] succeeded!".format (O0OO00O0O0OO0O0OO .name ))#line:77
|
||||
return public .returnMsg (True ,"Added successfully!")#line:78
|
||||
def remove (O0OOO000000OO0OOO ,O0OO00OO0OOO00000 ):#line:80
|
||||
""#line:86
|
||||
try :#line:87
|
||||
O0000O0OO000O0O0O =O0OOO000000OO0OOO .docker_client (O0OO00OO0OOO00000 .url ).volumes .get (O0OO00OO0OOO00000 .name )#line:88
|
||||
O0000O0OO000O0O0O .remove ()#line:89
|
||||
dp .write_log ("Delete storage volume [[]] successful!".format (O0OO00OO0OOO00000 .name ))#line:90
|
||||
return public .returnMsg (True ,"Successfully deleted")#line:91
|
||||
except docker .errors .APIError as OO00OO0O000O0O0O0 :#line:92
|
||||
if "volume is in use"in str (OO00OO0O000O0O0O0 ):#line:93
|
||||
return public .returnMsg (False ,"Storage volume is in use and cannot be deleted!")#line:94
|
||||
return public .returnMsg (False ,"Failed to delete! {}".format (OO00OO0O000O0O0O0 ))#line:95
|
||||
@@ -0,0 +1,58 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: zouhw <zhw@bt.cn>
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# 项目管理控制器
|
||||
# ------------------------------
|
||||
import os ,public ,json ,re ,time #line:13
|
||||
class main :#line:15
|
||||
def __init__ (O00000000O0OO000O ):#line:17
|
||||
pass #line:18
|
||||
def model (O0O0OOO0OO0OO00OO ,OO0O0O000O00O00O0 ):#line:20
|
||||
""#line:29
|
||||
import panelPlugin #line:30
|
||||
OO00OO0OOOO0OO0O0 =public .to_dict_obj ({})#line:31
|
||||
OO00OO0OOOO0OO0O0 .focre =1 #line:32
|
||||
O0OO000000O0000O0 =panelPlugin .panelPlugin ().get_soft_list (OO00OO0OOOO0OO0O0 )#line:33
|
||||
__OO000O0000OO000OO =int (O0OO000000O0000O0 ['ltd'])>1 #line:34
|
||||
try :#line:40
|
||||
OO0O0O000O00O00O0 .def_name =OO0O0O000O00O00O0 .dk_def_name #line:41
|
||||
OO0O0O000O00O00O0 .mod_name =OO0O0O000O00O00O0 .dk_model_name #line:42
|
||||
if OO0O0O000O00O00O0 ['mod_name']in ['base']:return public .return_status_code (1000 ,'Wrong call!')#line:43
|
||||
public .exists_args ('def_name,mod_name',OO0O0O000O00O00O0 )#line:44
|
||||
if OO0O0O000O00O00O0 ['def_name'].find ('__')!=-1 :return public .return_status_code (1000 ,'The called method name cannot contain the "__" characterrong call!')#line:45
|
||||
if not re .match (r"^\w+$",OO0O0O000O00O00O0 ['mod_name']):return public .return_status_code (1000 ,'The called module name cannot contain characters other than \w')#line:46
|
||||
if not re .match (r"^\w+$",OO0O0O000O00O00O0 ['def_name']):return public .return_status_code (1000 ,'The called module name cannot contain characters other than \w')#line:47
|
||||
except :#line:48
|
||||
return public .get_error_object ()#line:49
|
||||
O0OOO0O0O00O00O0O ="dk_{}".format (OO0O0O000O00O00O0 ['mod_name'].strip ())#line:51
|
||||
OO00OO0OOOO0OOOOO =OO0O0O000O00O00O0 ['def_name'].strip ()#line:52
|
||||
OO00OO0O0OOOOO000 ="{}/projectModel/bt_docker/{}.py".format (public .get_class_path (),O0OOO0O0O00O00O0O )#line:55
|
||||
if not os .path .exists (OO00OO0O0OOOOO000 ):#line:56
|
||||
return public .return_status_code (1003 ,O0OOO0O0O00O00O0O )#line:57
|
||||
OO00O00OOOOOO0000 =public .get_script_object (OO00OO0O0OOOOO000 )#line:59
|
||||
if not OO00O00OOOOOO0000 :return public .return_status_code (1000 ,'{} model not found'.format (O0OOO0O0O00O00O0O ))#line:60
|
||||
OOO0O000O0OOOOO0O =getattr (OO00O00OOOOOO0000 .main (),OO00OO0OOOO0OOOOO ,None )#line:61
|
||||
if not OOO0O000O0OOOOO0O :return public .return_status_code (1000 ,'{} method not found in {} model'.format (O0OOO0O0O00O00O0O ,OO00OO0OOOO0OOOOO ))#line:62
|
||||
O00O0O00O000O0000 ='{}_{}_LAST'.format (O0OOO0O0O00O00O0O .upper (),OO00OO0OOOO0OOOOO .upper ())#line:76
|
||||
O0OO0OOOOO00OOOO0 =public .exec_hook (O00O0O00O000O0000 ,OO0O0O000O00O00O0 )#line:77
|
||||
if isinstance (O0OO0OOOOO00OOOO0 ,public .dict_obj ):#line:78
|
||||
OOO0OOOOOOO000O0O =O0OO0OOOOO00OOOO0 #line:79
|
||||
elif isinstance (O0OO0OOOOO00OOOO0 ,dict ):#line:80
|
||||
return O0OO0OOOOO00OOOO0 #line:81
|
||||
elif isinstance (O0OO0OOOOO00OOOO0 ,bool ):#line:82
|
||||
if not O0OO0OOOOO00OOOO0 :#line:83
|
||||
return public .return_data (False ,{},error_msg ='Pre-HOOK interrupt operation')#line:84
|
||||
OO000OOOO000OOO0O =OOO0O000O0OOOOO0O (OO0O0O000O00O00O0 )#line:87
|
||||
O00O0O00O000O0000 ='{}_{}_END'.format (O0OOO0O0O00O00O0O .upper (),OO00OO0OOOO0OOOOO .upper ())#line:90
|
||||
O0O000OO0O00O0OOO =public .to_dict_obj ({'args':OO0O0O000O00O00O0 ,'result':OO000OOOO000OOO0O })#line:94
|
||||
O0OO0OOOOO00OOOO0 =public .exec_hook (O00O0O00O000O0000 ,O0O000OO0O00O0OOO )#line:95
|
||||
if isinstance (O0OO0OOOOO00OOOO0 ,dict ):#line:96
|
||||
OO000OOOO000OOO0O =O0OO0OOOOO00OOOO0 ['result']#line:97
|
||||
return OO000OOOO000OOO0O #line:98
|
||||
@@ -123,6 +123,12 @@ class main(projectBase):
|
||||
if not os.path.exists(self._nodejs_path): return nodejs_list
|
||||
for v in os.listdir(self._nodejs_path):
|
||||
if v[0] != 'v' or v.find('.') == -1: continue
|
||||
node_path = os.path.join(self._nodejs_path,v)
|
||||
node_bin = '{}/bin/node'.format(node_path)
|
||||
if not os.path.exists(node_bin):
|
||||
if os.path.exists(node_path + '/bin'):
|
||||
public.ExecShell('rm -rf {}'.format(node_path))
|
||||
continue
|
||||
nodejs_list.append(v)
|
||||
return nodejs_list
|
||||
|
||||
@@ -193,12 +199,12 @@ class main(projectBase):
|
||||
_bin = '{}/node_modules/.bin'.format(project_cwd)
|
||||
if os.path.exists(_bin):
|
||||
nodejs_bin_path = _bin + ':' + nodejs_bin_path
|
||||
|
||||
|
||||
last_env = '''PATH={nodejs_bin_path}:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
'''.format(nodejs_bin_path = nodejs_bin_path)
|
||||
return last_env
|
||||
|
||||
|
||||
|
||||
def install_packages(self,get):
|
||||
'''
|
||||
@@ -658,7 +664,7 @@ export PATH
|
||||
'''
|
||||
project_find = self.get_project_find(get.project_name)
|
||||
if not project_find:
|
||||
return public.return_error('The specified item does not exist')
|
||||
return public.return_error('The specified item does not exist',data='')
|
||||
project_id = project_find['id']
|
||||
|
||||
domains = get.domains
|
||||
@@ -1297,6 +1303,7 @@ echo $! > {pid_file}
|
||||
n+=1
|
||||
if not os.path.exists(pid_file):
|
||||
p = '\n'.join(p)
|
||||
public.writeFile(log_file,p,"a+")
|
||||
if p.find('[Errno 0]') != -1:
|
||||
if os.path.exists('{}/bt_security'.format(public.get_plugin_path())):
|
||||
return public.return_error('The start command was intercepted by [Fort Tower Defense Privilege], please turn off {} user protection'.format(project_find['project_config']['run_user']))
|
||||
@@ -1369,6 +1376,11 @@ cd {}
|
||||
if not res['status']: return res
|
||||
return public.return_data(True, 'Successful restart')
|
||||
|
||||
# xss 防御
|
||||
def xsssec(self,text):
|
||||
return text.replace('<', '<').replace('>', '>')
|
||||
|
||||
|
||||
def get_project_log(self,get):
|
||||
'''
|
||||
@name 获取项目日志
|
||||
@@ -1380,7 +1392,7 @@ cd {}
|
||||
'''
|
||||
log_file = "{}/{}.log".format(self._node_logs_path,get.project_name)
|
||||
if not os.path.exists(log_file): return public.return_error('Log file does not exist')
|
||||
return public.GetNumLines(log_file,200)
|
||||
return self.xsssec(public.GetNumLines(log_file,200))
|
||||
|
||||
|
||||
def get_project_load_info(self,get = None,project_name = None):
|
||||
@@ -1528,8 +1540,10 @@ cd {}
|
||||
@param p: Process<进程对像>
|
||||
@return list
|
||||
'''
|
||||
|
||||
skey = "io_speed_{}".format(p.pid)
|
||||
old_pio = cache.get(skey)
|
||||
if not hasattr(p,'io_counters'): return 0,0
|
||||
pio = p.io_counters()
|
||||
if not old_pio:
|
||||
cache.set(skey,[pio,time.time()],3600)
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#------------------------------
|
||||
# 磁盘配额管理
|
||||
#------------------------------
|
||||
import os ,public ,psutil ,json ,time ,re
|
||||
from projectModel .base import projectBase
|
||||
class main (projectBase ):
|
||||
xfs_quota ="xfs_quota"
|
||||
__O0O000000OO000000 ='{}/config/quota.json'.format (public .get_panel_path ())
|
||||
__O00OOOO00OO0OO0OO ='{}/config/mysql_quota.json'.format (public .get_panel_path ())
|
||||
__O0O00000000OOO0O0 =public .to_string ([84 ,104 ,105 ,115 ,32 ,102 ,101 ,97 ,116 ,117 ,114 ,101 ,32 ,105 ,115 ,32 ,101 ,120 ,99 ,108 ,117 ,115 ,105 ,118 ,101 ,32 ,116 ,111 ,32 ,116 ,104 ,101 ,32 ,112 ,114 ,111 ,32 ,101 ,100 ,105 ,116 ,105 ,111 ,110 ,44 ,32 ,112 ,108 ,101 ,97 ,115 ,101 ,32 ,97 ,99 ,116 ,105 ,118 ,97 ,116 ,101 ,32 ,105 ,116 ,32 ,102 ,105 ,114 ,115 ,116 ])
|
||||
def __init__ (OOO0000OO0OO0O00O ):
|
||||
_O0OOO0O00O0O0O000 ='{}/data/quota_install.pl'.format (public .get_panel_path ())
|
||||
if not os .path .exists (_O0OOO0O00O0O0O000 ):
|
||||
O0OO0OOO0OO0O0O00 ='/usr/sbin/xfs_quota'
|
||||
if not os .path .exists (O0OO0OOO0OO0O0O00 ):
|
||||
if os .path .exists ('/usr/bin/apt-get'):
|
||||
public .ExecShell ('nohup apt-get install xfsprogs -y > /dev/null &')
|
||||
else :
|
||||
public .ExecShell ('nohup yum install xfsprogs -y > /dev/null &')
|
||||
public .writeFile (_O0OOO0O00O0O0O000 ,'True')
|
||||
if os .path .exists ("/sbin/xfs_quota"):
|
||||
OOO0000OO0OO0O00O .xfs_quota ="/sbin/xfs_quota"
|
||||
def __OO00OO00O0000O0OO (O00OOO0000000000O ,args =None ):
|
||||
""
|
||||
OO00000OO0O00O0O0 =[]
|
||||
for OO00O0OO0O0000OOO in psutil .disk_partitions ():
|
||||
if OO00O0OO0O0000OOO .fstype =='xfs':
|
||||
OO00000OO0O00O0O0 .append ((OO00O0OO0O0000OOO .mountpoint ,OO00O0OO0O0000OOO .device ,psutil .disk_usage (OO00O0OO0O0000OOO .mountpoint ).free ,OO00O0OO0O0000OOO .opts .split (',')))
|
||||
return OO00000OO0O00O0O0
|
||||
def __O00OOOO0OO00O0OO0 (O000O00O0O0000O00 ,args =None ):
|
||||
""
|
||||
return O000O00O0O0000O00 .__O000O0O0000OOOOOO (args .path )
|
||||
def __O000000O0O0000OOO (O00OOO00000OOOO00 ,O000O00O00O00OOOO ):
|
||||
""
|
||||
O0OOO000OO000OOO0 =O00OOO00000OOOO00 .__OO00OO00O0000O0OO ()
|
||||
OO0OO000OO00O0OO0 =None
|
||||
for O0O0OOOO00O00OOO0 in O0OOO000OO000OOO0 :
|
||||
if O0O0OOOO00O00OOO0 [0 ]=="/":
|
||||
OO0OO000OO00O0OO0 =O0O0OOOO00O00OOO0
|
||||
if O000O00O00O00OOOO .find (O0O0OOOO00O00OOO0 [0 ]+'/')==0 :
|
||||
if not 'prjquota'in O0O0OOOO00O00OOO0 [3 ]:
|
||||
return O0O0OOOO00O00OOO0
|
||||
return O0O0OOOO00O00OOO0 [1 ]
|
||||
if OO0OO000OO00O0OO0 and O000O00O00O00OOOO .find (OO0OO000OO00O0OO0 [0 ])==0 :
|
||||
if not 'prjquota'in OO0OO000OO00O0OO0 [3 ]:
|
||||
return OO0OO000OO00O0OO0
|
||||
return OO0OO000OO00O0OO0 [1 ]
|
||||
return ''
|
||||
def __O000O0O0000OOOOOO (OO0OOO00OO000000O ,O0O0O0OOOOO0OOO0O ):
|
||||
""
|
||||
if not os .path .exists (O0O0O0OOOOO0OOO0O ):return -1
|
||||
if not os .path .isdir (O0O0O0OOOOO0OOO0O ):return -2
|
||||
OO0O0OO0O0000000O =OO0OOO00OO000000O .__OO00OO00O0000O0OO ()
|
||||
O0O00OO00O0O0O00O =None
|
||||
for O0OO0O0O00O00OO00 in OO0O0OO0O0000000O :
|
||||
if O0OO0O0O00O00OO00 [0 ]=="/":
|
||||
O0O00OO00O0O0O00O =O0OO0O0O00O00OO00
|
||||
if O0O0O0OOOOO0OOO0O .find (O0OO0O0O00O00OO00 [0 ]+'/')==0 :
|
||||
return O0OO0O0O00O00OO00 [2 ]/1024 /1024
|
||||
if O0O00OO00O0O0O00O and O0O0O0OOOOO0OOO0O .find (O0O00OO00O0O0O00O [0 ])==0 :
|
||||
return O0O00OO00O0O0O00O [2 ]/1024 /1024
|
||||
return -3
|
||||
def get_quota_path_list (OOOO000OO000O000O ,args =None ,get_path =None ):
|
||||
""
|
||||
if not os .path .exists (OOOO000OO000O000O .__O0O000000OO000000 ):
|
||||
public .writeFile (OOOO000OO000O000O .__O0O000000OO000000 ,'[]')
|
||||
O00OO00OO000O0OO0 =json .loads (public .readFile (OOOO000OO000O000O .__O0O000000OO000000 ))
|
||||
OO00OOO0O00OOOO00 =[]
|
||||
for O0OOOO0O0O000O0O0 in O00OO00OO000O0OO0 :
|
||||
if not os .path .exists (O0OOOO0O0O000O0O0 ['path'])or not os .path .isdir (O0OOOO0O0O000O0O0 ['path'])or os .path .islink (O0OOOO0O0O000O0O0 ['path']):continue
|
||||
if get_path :
|
||||
if O0OOOO0O0O000O0O0 ['path']==get_path :
|
||||
OOO00OO0OOO0O0OO0 =psutil .disk_usage (O0OOOO0O0O000O0O0 ['path'])
|
||||
O0OOOO0O0O000O0O0 ['used']=OOO00OO0OOO0O0OO0 .used
|
||||
O0OOOO0O0O000O0O0 ['free']=OOO00OO0OOO0O0OO0 .free
|
||||
return O0OOOO0O0O000O0O0
|
||||
else :
|
||||
continue
|
||||
OOO00OO0OOO0O0OO0 =psutil .disk_usage (O0OOOO0O0O000O0O0 ['path'])
|
||||
O0OOOO0O0O000O0O0 ['used']=OOO00OO0OOO0O0OO0 .used
|
||||
O0OOOO0O0O000O0O0 ['free']=OOO00OO0OOO0O0OO0 .free
|
||||
OO00OOO0O00OOOO00 .append (O0OOOO0O0O000O0O0 )
|
||||
if get_path :
|
||||
return {'size':0 ,'used':0 ,'free':0 }
|
||||
if len (OO00OOO0O00OOOO00 )!=len (O00OO00OO000O0OO0 ):
|
||||
public .writeFile (OOOO000OO000O000O .__O0O000000OO000000 ,json .dumps (OO00OOO0O00OOOO00 ))
|
||||
return O00OO00OO000O0OO0
|
||||
def get_quota_mysql_list (OO000O0O00OOOOO0O ,args =None ,get_name =None ):
|
||||
""
|
||||
if not os .path .exists (OO000O0O00OOOOO0O .__O00OOOO00OO0OO0OO ):
|
||||
public .writeFile (OO000O0O00OOOOO0O .__O00OOOO00OO0OO0OO ,'[]')
|
||||
OO00OO0000O0O0OOO =json .loads (public .readFile (OO000O0O00OOOOO0O .__O00OOOO00OO0OO0OO ))
|
||||
O00O00OOO0OOO00OO =[]
|
||||
OOOO000000OO0O0O0 =public .M ('databases')
|
||||
for OOO0OO0O000O0O00O in OO00OO0000O0O0OOO :
|
||||
if get_name :
|
||||
if OOO0OO0O000O0O00O ['db_name']==get_name :
|
||||
OOO0OO0O000O0O00O ['used']=OOO0OO0O000O0O00O ['used']=int (public .get_database_size_by_name (OOO0OO0O000O0O00O ['db_name']))
|
||||
_O0OO00O000O0OOO00 =OOO0OO0O000O0O00O ['size']*1024 *1024
|
||||
if (OOO0OO0O000O0O00O ['used']>_O0OO00O000O0OOO00 and OOO0OO0O000O0O00O ['insert_accept'])or (OOO0OO0O000O0O00O ['used']<_O0OO00O000O0OOO00 and not OOO0OO0O000O0O00O ['insert_accept']):
|
||||
OO000O0O00OOOOO0O .mysql_quota_check ()
|
||||
return OOO0OO0O000O0O00O
|
||||
else :
|
||||
if OOOO000000OO0O0O0 .where ('name=?',OOO0OO0O000O0O00O ['db_name']).count ():
|
||||
if args :OOO0OO0O000O0O00O ['used']=int (public .get_database_size_by_name (OOO0OO0O000O0O00O ['db_name']))
|
||||
O00O00OOO0OOO00OO .append (OOO0OO0O000O0O00O )
|
||||
OOOO000000OO0O0O0 .close ()
|
||||
if get_name :
|
||||
return {'size':0 ,'used':0 }
|
||||
if len (O00O00OOO0OOO00OO )!=len (OO00OO0000O0O0OOO ):
|
||||
public .writeFile (OO000O0O00OOOOO0O .__O00OOOO00OO0OO0OO ,json .dumps (O00O00OOO0OOO00OO ))
|
||||
return O00O00OOO0OOO00OO
|
||||
def __OOO000O00000O0OO0 (OOOOOOOO0OOO000OO ,OOO0000OOO00O000O ,OO0OOO0000000OOO0 ,O0OOO0OO00O00O0OO ,OOOO00000OOOO0OO0 ):
|
||||
""
|
||||
O0OO0O00O000O00O0 =OOO0000OOO00O000O .execute ("REVOKE ALL PRIVILEGES ON `{}`.* FROM '{}'@'{}';".format (O0OOO0OO00O00O0OO ,OO0OOO0000000OOO0 ,OOOO00000OOOO0OO0 ))
|
||||
if O0OO0O00O000O00O0 :raise public .PanelError ('Failed to remove insert permission for database user:{}'.format (O0OO0O00O000O00O0 ))
|
||||
O0OO0O00O000O00O0 =OOO0000OOO00O000O .execute ("GRANT SELECT, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, LOCK TABLES, CREATE VIEW, EVENT, TRIGGER, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON `{}`.* TO '{}'@'{}';".format (O0OOO0OO00O00O0OO ,OO0OOO0000000OOO0 ,OOOO00000OOOO0OO0 ))
|
||||
if O0OO0O00O000O00O0 :raise public .PanelError ('Failed to remove insert permission for database user:{}'.format (O0OO0O00O000O00O0 ))
|
||||
OOO0000OOO00O000O .execute ("FLUSH PRIVILEGES;")
|
||||
return True
|
||||
def __O000O000O0OOOOOOO (OO00OOO00OO0OOO00 ,O000OOOO0OO0O00OO ,O0OOO0OOO0OO00O00 ,O00OOO0OO0OO0OOOO ,OOOOOOOO0OO00O000 ):
|
||||
""
|
||||
OOO0O000OOOOO0O00 =O000OOOO0OO0O00OO .execute ("REVOKE ALL PRIVILEGES ON `{}`.* FROM '{}'@'{}';".format (O00OOO0OO0OO0OOOO ,O0OOO0OOO0OO00O00 ,OOOOOOOO0OO00O000 ))
|
||||
if OOO0O000OOOOO0O00 :raise public .PanelError ('Failed to restore insert privileges for database user:{}'.format (OOO0O000OOOOO0O00 ))
|
||||
OOO0O000OOOOO0O00 =O000OOOO0OO0O00OO .execute ("GRANT ALL PRIVILEGES ON `{}`.* TO '{}'@'{}';".format (O00OOO0OO0OO0OOOO ,O0OOO0OOO0OO00O00 ,OOOOOOOO0OO00O000 ))
|
||||
if OOO0O000OOOOO0O00 :raise public .PanelError ('Failed to restore insert privileges for database user:{}'.format (OOO0O000OOOOO0O00 ))
|
||||
O000OOOO0OO0O00OO .execute ("FLUSH PRIVILEGES;")
|
||||
return True
|
||||
def mysql_quota_service (O00000OO00O0O0000 ):
|
||||
""
|
||||
while 1 :
|
||||
time .sleep (600 )
|
||||
O00000OO00O0O0000 .mysql_quota_check ()
|
||||
def __O0OO00O00O0OOO0OO (O0OO0O0000OOO0O0O ,OO0O0OOOOO0O00O0O ):
|
||||
try :
|
||||
if type (OO0O0OOOOO0O00O0O )!=list and type (OO0O0OOOOO0O00O0O )!=str :OO0O0OOOOO0O00O0O =list (OO0O0OOOOO0O00O0O )
|
||||
return OO0O0OOOOO0O00O0O
|
||||
except :return []
|
||||
def mysql_quota_check (OO0O0OOO00O0OO00O ):
|
||||
""
|
||||
if not OO0O0OOO00O0OO00O .__OO000OOO0OO0O00OO ():return public .returnMsg (False ,OO0O0OOO00O0OO00O .__O0O00000000OOO0O0 )
|
||||
O00000OOO00OO000O =OO0O0OOO00O0OO00O .get_quota_mysql_list ()
|
||||
for OO0O0O0O0OO00OOO0 in O00000OOO00OO000O :
|
||||
try :
|
||||
if OO0O0O0O0OO00OOO0 ['size']<1 :
|
||||
if not OO0O0O0O0OO00OOO0 ['insert_accept']:
|
||||
OO0O0OOO00O0OO00O .__O000O000O0OOOOOOO (O0OOOO000OOO0O0OO ,O0000O00OO0O00O0O ,OO0O0O0O0OO00OOO0 ['db_name'],O000O00O0000OOO0O [0 ])
|
||||
OO0O0O0O0OO00OOO0 ['insert_accept']=True
|
||||
public .WriteLog ('Quota','Database [{}] quota has been closed, restore insert privileges'.format (OO0O0O0O0OO00OOO0 ['db_name']))
|
||||
continue
|
||||
O000O000O00000O0O =public .get_database_size_by_name (OO0O0O0O0OO00OOO0 ['db_name'])/1024 /1024
|
||||
O0000O00OO0O00O0O =public .M ('databases').where ('name=?',(OO0O0O0O0OO00OOO0 ['db_name'],)).getField ('username')
|
||||
O0OOOO000OOO0O0OO =public .get_mysql_obj (OO0O0O0O0OO00OOO0 ['db_name'])
|
||||
O0O0OOO0O0O00OOOO =OO0O0OOO00O0OO00O .__O0OO00O00O0OOO0OO (O0OOOO000OOO0O0OO .query ("select Host from mysql.user where User='"+O0000O00OO0O00O0O +"'"))
|
||||
if O000O000O00000O0O <OO0O0O0O0OO00OOO0 ['size']:
|
||||
if not OO0O0O0O0OO00OOO0 ['insert_accept']:
|
||||
for O000O00O0000OOO0O in O0O0OOO0O0O00OOOO :
|
||||
OO0O0OOO00O0OO00O .__O000O000O0OOOOOOO (O0OOOO000OOO0O0OO ,O0000O00OO0O00O0O ,OO0O0O0O0OO00OOO0 ['db_name'],O000O00O0000OOO0O [0 ])
|
||||
OO0O0O0O0OO00OOO0 ['insert_accept']=True
|
||||
public .WriteLog ('Quota','The database [{}] is below the quota [{}MB], restore the insert permission'.format (OO0O0O0O0OO00OOO0 ['db_name'],OO0O0O0O0OO00OOO0 ['size']))
|
||||
if hasattr (O0OOOO000OOO0O0OO ,'close'):O0OOOO000OOO0O0OO .close ()
|
||||
continue
|
||||
if OO0O0O0O0OO00OOO0 ['insert_accept']:
|
||||
for O000O00O0000OOO0O in O0O0OOO0O0O00OOOO :
|
||||
OO0O0OOO00O0OO00O .__OOO000O00000O0OO0 (O0OOOO000OOO0O0OO ,O0000O00OO0O00O0O ,OO0O0O0O0OO00OOO0 ['db_name'],O000O00O0000OOO0O [0 ])
|
||||
OO0O0O0O0OO00OOO0 ['insert_accept']=False
|
||||
public .WriteLog ('Quota','Database [{}] removed insert permission due to exceeding quota [{}MB]'.format (OO0O0O0O0OO00OOO0 ['db_name'],OO0O0O0O0OO00OOO0 ['size']))
|
||||
if hasattr (O0OOOO000OOO0O0OO ,'close'):O0OOOO000OOO0O0OO .close ()
|
||||
except :
|
||||
public .print_log (public .get_error_info ())
|
||||
public .writeFile (OO0O0OOO00O0OO00O .__O00OOOO00OO0OO0OO ,json .dumps (O00000OOO00OO000O ))
|
||||
def __O0000OO00OO00O0O0 (OO0000O0OO00O0OOO ,O0O0O00OO0OOOOOOO ):
|
||||
""
|
||||
if not OO0000O0OO00O0OOO .__OO000OOO0OO0O00OO ():return public .returnMsg (False ,OO0000O0OO00O0OOO .__O0O00000000OOO0O0 )
|
||||
if not os .path .exists (OO0000O0OO00O0OOO .__O00OOOO00OO0OO0OO ):
|
||||
public .writeFile (OO0000O0OO00O0OOO .__O00OOOO00OO0OO0OO ,'[]')
|
||||
OOOO0000OOOO0OOOO =int (O0O0O00OO0OOOOOOO ['size'])
|
||||
OOO000O0OO00O00OO =O0O0O00OO0OOOOOOO .db_name .strip ()
|
||||
O0OO0OOOOO00O00OO =json .loads (public .readFile (OO0000O0OO00O0OOO .__O00OOOO00OO0OO0OO ))
|
||||
for OO000O0O0O0O000OO in O0OO0OOOOO00O00OO :
|
||||
if OO000O0O0O0O000OO ['db_name']==OOO000O0OO00O00OO :
|
||||
return public .returnMsg (False ,'Database quota already exists')
|
||||
O0OO0OOOOO00O00OO .append ({'db_name':OOO000O0OO00O00OO ,'size':OOOO0000OOOO0OOOO ,'insert_accept':True })
|
||||
public .writeFile (OO0000O0OO00O0OOO .__O00OOOO00OO0OO0OO ,json .dumps (O0OO0OOOOO00O00OO ))
|
||||
public .WriteLog ('Quota','The quota limit for creating database [{db_name}] is: {size}MB'.format (db_name =OOO000O0OO00O00OO ,size =OOOO0000OOOO0OOOO ))
|
||||
OO0000O0OO00O0OOO .mysql_quota_check ()
|
||||
return public .returnMsg (True ,'Added successfully')
|
||||
def __OO000OOO0OO0O00OO (OOOO00OOOO00O0O00 ):
|
||||
import panelPlugin
|
||||
O0OOOOOO0O0000O0O =public .to_dict_obj ({})
|
||||
O0OOOOOO0O0000O0O .focre =1
|
||||
O0O0O00O0OO00O000 =panelPlugin .panelPlugin ().get_soft_list (O0OOOOOO0O0000O0O )
|
||||
return int (O0O0O00O0OO00O000 ['pro'])>time .time ()
|
||||
def modify_mysql_quota (OO00OO0OOOO00O000 ,OOOO00O0OO000OOOO ):
|
||||
""
|
||||
if not OO00OO0OOOO00O000 .__OO000OOO0OO0O00OO ():return public .returnMsg (False ,OO00OO0OOOO00O000 .__O0O00000000OOO0O0 )
|
||||
if not os .path .exists (OO00OO0OOOO00O000 .__O00OOOO00OO0OO0OO ):
|
||||
public .writeFile (OO00OO0OOOO00O000 .__O00OOOO00OO0OO0OO ,'[]')
|
||||
if not re .match (r"^\d+$",OOOO00O0OO000OOOO .size ):return public .returnMsg (False ,'Quota size must be an integer!')
|
||||
OO0O0OOOO00000OOO =int (OOOO00O0OO000OOOO ['size'])
|
||||
OO0OO0OO000O0O00O =OOOO00O0OO000OOOO .db_name .strip ()
|
||||
O0OOOO0OOOO0O0000 =json .loads (public .readFile (OO00OO0OOOO00O000 .__O00OOOO00OO0OO0OO ))
|
||||
O0O00O0O000OOO0O0 =False
|
||||
for OO00O0000O0OOOOO0 in O0OOOO0OOOO0O0000 :
|
||||
if OO00O0000O0OOOOO0 ['db_name']==OO0OO0OO000O0O00O :
|
||||
OO00O0000O0OOOOO0 ['size']=OO0O0OOOO00000OOO
|
||||
O0O00O0O000OOO0O0 =True
|
||||
break
|
||||
if O0O00O0O000OOO0O0 :
|
||||
public .writeFile (OO00OO0OOOO00O000 .__O00OOOO00OO0OO0OO ,json .dumps (O0OOOO0OOOO0O0000 ))
|
||||
public .WriteLog ('Quota','Modify the quota limit of database [{db_name}] to: {size}MB'.format (db_name =OO0OO0OO000O0O00O ,size =OO0O0OOOO00000OOO ))
|
||||
OO00OO0OOOO00O000 .mysql_quota_check ()
|
||||
return public .returnMsg (True ,'Successfully modified')
|
||||
return OO00OO0OOOO00O000 .__O0000OO00OO00O0O0 (OOOO00O0OO000OOOO )
|
||||
def __O0OOOO00O00000OOO (O0OO0O0O00O0OO00O ,O0O0O0O0O000O0OOO ):
|
||||
""
|
||||
O0OOO0OO0O0000O00 =[]
|
||||
OO0000OO0OO00O0O0 =public .ExecShell ("{xfs_quota} -x -c report {mountpoint}|awk '{{print $1}}'|grep '#'".format (xfs_quota =O0OO0O0O00O0OO00O .xfs_quota ,mountpoint =O0O0O0O0O000O0OOO ))[0 ]
|
||||
if not OO0000OO0OO00O0O0 :return O0OOO0OO0O0000O00
|
||||
for O0OO0O00OO0O0OO0O in OO0000OO0OO00O0O0 .split ('\n'):
|
||||
if O0OO0O00OO0O0OO0O :O0OOO0OO0O0000O00 .append (int (O0OO0O00OO0O0OO0O .split ('#')[-1 ]))
|
||||
return O0OOO0OO0O0000O00
|
||||
def __OO00O000OOOOOOO00 (O0OOO0O00OOOO0OOO ,OO0000O0OOOOOOO0O ,OOO0000OO0O0000OO ):
|
||||
""
|
||||
O00O00OO0O000O000 =1001
|
||||
if not OO0000O0OOOOOOO0O :return O00O00OO0O000O000
|
||||
O00O00OO0O000O000 =OO0000O0OOOOOOO0O [-1 ]['id']+1
|
||||
O0OO00OO00O00O000 =sorted (O0OOO0O00OOOO0OOO .__O0OOOO00O00000OOO (OOO0000OO0O0000OO ))
|
||||
if O0OO00OO00O00O000 :
|
||||
if O0OO00OO00O00O000 [-1 ]>O00O00OO0O000O000 :
|
||||
O00O00OO0O000O000 =O0OO00OO00O00O000 [-1 ]+1
|
||||
return O00O00OO0O000O000
|
||||
def __OOOO0O000OOOO00O0 (OO0OO00O0O0000O0O ,O000O0OOOO0OOO00O ):
|
||||
""
|
||||
if not OO0OO00O0O0000O0O .__OO000OOO0OO0O00OO ():return public .returnMsg (False ,OO0OO00O0O0000O0O .__O0O00000000OOO0O0 )
|
||||
OOOO000000O00OO00 =O000O0OOOO0OOO00O .path .strip ()
|
||||
OO000OOO0000OO00O =int (O000O0OOOO0OOO00O .size )
|
||||
if not os .path .exists (OOOO000000O00OO00 ):return public .returnMsg (False ,'The specified directory does not exist')
|
||||
if os .path .isfile (OOOO000000O00OO00 ):return public .returnMsg (False ,'this is not a valid directory!')
|
||||
if os .path .islink (OOOO000000O00OO00 ):return public .returnMsg (False ,'The specified directory is a soft link!')
|
||||
OOOOO000OO0000OOO =OO0OO00O0O0000O0O .get_quota_path_list ()
|
||||
for O00O0OOOO0O00O000 in OOOOO000OO0000OOO :
|
||||
if O00O0OOOO0O00O000 ['path']==OOOO000000O00OO00 :return public .returnMsg (False ,'The specified directory has already set a quota!')
|
||||
OO000O0OO0000OO00 =OO0OO00O0O0000O0O .__O000O0O0000OOOOOO (OOOO000000O00OO00 )
|
||||
if OO000O0OO0000OO00 ==-3 :return public .returnMsg (False ,'The partition where the specified directory is located is not an XFS partition and does not support directory quotas!')
|
||||
if OO000O0OO0000OO00 ==-2 :return public .returnMsg (False ,'this is not a valid directory!')
|
||||
if OO000O0OO0000OO00 ==-1 :return public .returnMsg (False ,'The specified directory does not exist!')
|
||||
if OO000OOO0000OO00O >OO000O0OO0000OO00 :return public .returnMsg (False ,'Insufficient quota capacity available for the specified disk!')
|
||||
OOO0O0O0O0O000O0O =OO0OO00O0O0000O0O .__O000000O0O0000OOO (OOOO000000O00OO00 )
|
||||
if not OOO0O0O0O0O000O0O :return public .returnMsg (False ,'The specified directory is not in the xfs disk partition!')
|
||||
if isinstance (OOO0O0O0O0O000O0O ,tuple ):return public .returnMsg (False ,'The directory quota function is not enabled for this xfs partition, please increase the [prjquota] parameter when mounting the partition<p>/etc/fstab File configuration example:<pre>{mountpoint} {path} xfs defaults,prjquota 0 0</pre></p><p>Note: You need to remount the partition or reboot the server to take effect</p><br>The setup is completed and the error still occurs, please refer to<br><a class="btlink" target ="_blank" href="https://forum.aapanel.com/d/12700-how-to-enable-disk-quota-for-root-directory">How to enable disk quota for root directory</a>'.format (mountpoint =OOO0O0O0O0O000O0O [1 ],path =OOO0O0O0O0O000O0O [0 ]))
|
||||
O0000OO000OO00O0O =OO0OO00O0O0000O0O .__OO00O000OOOOOOO00 (OOOOO000OO0000OOO ,OOO0O0O0O0O000O0O )
|
||||
OO0O0O0O0OOOOO00O =public .ExecShell ("{xfs_quota} -x -c 'project -s -p {path} {quota_id}'".format (path =OOOO000000O00OO00 ,quota_id =O0000OO000OO00O0O ,xfs_quota =OO0OO00O0O0000O0O .xfs_quota ))
|
||||
if OO0O0O0O0OOOOO00O [1 ]:return public .returnMsg (False ,OO0O0O0O0OOOOO00O [1 ])
|
||||
OO0O0O0O0OOOOO00O =public .ExecShell ("{xfs_quota} -x -c 'limit -p bhard={size}m {quota_id}' {mountpoint}".format (quota_id =O0000OO000OO00O0O ,size =OO000OOO0000OO00O ,mountpoint =OOO0O0O0O0O000O0O ,xfs_quota =OO0OO00O0O0000O0O .xfs_quota ))
|
||||
if OO0O0O0O0OOOOO00O [1 ]:return public .returnMsg (False ,OO0O0O0O0OOOOO00O [1 ])
|
||||
OOOOO000OO0000OOO .append ({'path':O000O0OOOO0OOO00O .path ,'size':OO000OOO0000OO00O ,'id':O0000OO000OO00O0O })
|
||||
public .writeFile (OO0OO00O0O0000O0O .__O0O000000OO000000 ,json .dumps (OOOOO000OO0000OOO ))
|
||||
public .WriteLog ('Quota','The quota limit for creating directory [{path}] is: {size}MB'.format (path =OOOO000000O00OO00 ,size =OO000OOO0000OO00O ))
|
||||
return public .returnMsg (True ,'Added successfully')
|
||||
def modify_path_quota (O0O0OOOOO0OOO0OOO ,OO0O0000000OO0OO0 ):
|
||||
""
|
||||
if not O0O0OOOOO0OOO0OOO .__OO000OOO0OO0O00OO ():return public .returnMsg (False ,O0O0OOOOO0OOO0OOO .__O0O00000000OOO0O0 )
|
||||
O00O0O00OOO0O0O0O =OO0O0000000OO0OO0 .path .strip ()
|
||||
if not re .match (r"^\d+$",OO0O0000000OO0OO0 .size ):return public .returnMsg (False ,'Quota size must be an integer!')
|
||||
O0O00O0OOO0O0O0OO =int (OO0O0000000OO0OO0 .size )
|
||||
if not os .path .exists (O00O0O00OOO0O0O0O ):return public .returnMsg (False ,'The specified directory does not exist')
|
||||
if os .path .isfile (O00O0O00OOO0O0O0O ):return public .returnMsg (False ,'This is not a valid directory!')
|
||||
if os .path .islink (O00O0O00OOO0O0O0O ):return public .returnMsg (False ,'The specified directory is a soft link!')
|
||||
OO0O00O00OO0000OO =O0O0OOOOO0OOO0OOO .get_quota_path_list ()
|
||||
OOOO0OO0OOOOO0OOO =0
|
||||
for OOO00000OOOOO0OOO in OO0O00O00OO0000OO :
|
||||
if OOO00000OOOOO0OOO ['path']==O00O0O00OOO0O0O0O :
|
||||
OOOO0OO0OOOOO0OOO =OOO00000OOOOO0OOO ['id']
|
||||
break
|
||||
if not OOOO0OO0OOOOO0OOO :return O0O0OOOOO0OOO0OOO .__OOOO0O000OOOO00O0 (OO0O0000000OO0OO0 )
|
||||
O0O0O00OOOOOO00O0 =O0O0OOOOO0OOO0OOO .__O000O0O0000OOOOOO (O00O0O00OOO0O0O0O )
|
||||
if O0O0O00OOOOOO00O0 ==-3 :return public .returnMsg (False ,'The partition where the specified directory is located is not an XFS partition, and directory quotas are not supported!')
|
||||
if O0O0O00OOOOOO00O0 ==-2 :return public .returnMsg (False ,'This is not a valid directory!')
|
||||
if O0O0O00OOOOOO00O0 ==-1 :return public .returnMsg (False ,'The specified directory does not exist!')
|
||||
if O0O00O0OOO0O0O0OO >O0O0O00OOOOOO00O0 :return public .returnMsg (False ,'Insufficient quota capacity available for the specified disk!')
|
||||
OOO0OO0O0000O0OO0 =O0O0OOOOO0OOO0OOO .__O000000O0O0000OOO (O00O0O00OOO0O0O0O )
|
||||
if not OOO0OO0O0000O0OO0 :return public .returnMsg (False ,'The specified directory is not in the xfs disk partition!')
|
||||
if isinstance (OOO0OO0O0000O0OO0 ,tuple ):return public .returnMsg (False ,'The directory quota function is not enabled for this xfs partition, please increase the [prjquota] parameter when mounting the partition<p>/etc/fstab File configuration example:<pre>{mountpoint} {path} xfs defaults,prjquota 0 0</pre></p><p>Note: After the configuration is complete, you need to remount the partition or restart the server to take effect</p>'.format (mountpoint =OOO0OO0O0000O0OO0 [1 ],path =OOO0OO0O0000O0OO0 [0 ]))
|
||||
OO00O0OOO00OOOO0O =public .ExecShell ("{xfs_quota} -x -c 'project -s -p {path} {quota_id}'".format (path =O00O0O00OOO0O0O0O ,quota_id =OOOO0OO0OOOOO0OOO ,xfs_quota =O0O0OOOOO0OOO0OOO .xfs_quota ))
|
||||
if OO00O0OOO00OOOO0O [1 ]:return public .returnMsg (False ,OO00O0OOO00OOOO0O [1 ])
|
||||
OO00O0OOO00OOOO0O =public .ExecShell ("{xfs_quota} -x -c 'limit -p bhard={size}m {quota_id}' {mountpoint}".format (quota_id =OOOO0OO0OOOOO0OOO ,size =O0O00O0OOO0O0O0OO ,mountpoint =OOO0OO0O0000O0OO0 ,xfs_quota =O0O0OOOOO0OOO0OOO .xfs_quota ))
|
||||
if OO00O0OOO00OOOO0O [1 ]:return public .returnMsg (False ,OO00O0OOO00OOOO0O [1 ])
|
||||
for OOO00000OOOOO0OOO in OO0O00O00OO0000OO :
|
||||
if OOO00000OOOOO0OOO ['path']==O00O0O00OOO0O0O0O :
|
||||
OOO00000OOOOO0OOO ['size']=O0O00O0OOO0O0O0OO
|
||||
break
|
||||
public .writeFile (O0O0OOOOO0OOO0OOO .__O0O000000OO000000 ,json .dumps (OO0O00O00OO0000OO ))
|
||||
public .WriteLog ('Quota','Modify the quota limit of directory [{path}] to:{size}MB'.format (path =O00O0O00OOO0O0O0O ,size =O0O00O0OOO0O0O0OO ))
|
||||
return public .returnMsg (True ,'Successfully modified')
|
||||
Reference in New Issue
Block a user