业务场景
公司是做体育测试相关的产品,有大量的现场业务视频要传回公司留存,但是由于现场网络,像素等原因,无法通过公网传输,只能拍摄完成后存入移动硬盘带回公司上传服务器,并上传阿里OSS云存储。
文章目录
- 前言
- 一、项目流程
- 二、实现步骤
- 1.配置环境
- 2.编写物理机脚本
- 3.编写Python发送脚本
- 4.编写虚拟机脚本
- 5.测试并验证结果
- 6.创建自动执行拷贝
- 总结
前言
我们公司的环境是物理服务器上搭建的KVM,创建的Centos7虚拟机。(公司比较穷得会过日子)
本项目需要安装一些插件,请自行安装。插件有:Ansible、Python3.7、Expect。
一、项目流程
因为虚拟机不能直接识别物理机的USB设备,所以我们要把U盘从物理机挂载到虚拟机上,我们还要创建相应的设备文件给虚拟机,让他可以识别USB设备。从而实现后面一系列的自动操作,大体流程如下:
USB设备插入物理服务器 → 检测有设备接入挂载到虚拟机 → 拷贝数据到虚拟机 → 从虚拟机上传到阿里云OSS
二、实现步骤
1.配置环境
创建飞书机器人(请看我之前的飞书相关文章)
地址:每天禅道超时任务、超时未开始任务发送飞书提醒_默^默的博客-CSDN博客
安装cp 命令显示拷贝进度条
地址:cp命令显示进度条_为Linux的cp和mv命令添加进度条_yi美小能手的博客-CSDN博客
服务器挂载阿里云OSS存储到服务器(我是挂载到虚拟机)
Ansible 跟虚拟机之间进行认证
命令:ssh-keygen //生成秘钥 一直回车就行
将秘钥拷贝到被管理服务器上
命令:ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 user@被管理的服务器IP
编辑配置文件:vim /etc/ansible/hosts
验证通信是否完成
编写yml文件:vim tviewer.yml
---
- hosts: server
remote_user: root
tasks:
- name: Project
shell: /bin/bash /root/script/mount.sh # 虚拟机中脚本存放路径自行修改
register: result
- debug: var=result
2.编写物理机脚本
注意所有脚本及文件在同一目录下,本次实验是固有环境,其他环境使用需要改动。
本次实验脚本路径:/root/script
首先创一个初始状态文件
echo "当前设备状态: 1" > ./status.txt
编写监控USB端口脚本
vim jk_usb.sh
代码如下(示例):
#!/bin/bash
# Monitor USB device
# 检测当前是否有USB设备接入
# 获取USB端口 idVendor,idProduct
while :
do
idven=`awk -F '[,=]' '/New USB device found, idVendor/{print $3}' /var/log/messages | tail -1`
idpro=`awk -F '[,=]' '/New USB device found, idVendor/{print $5}' /var/log/messages | tail -1`
if [ -z $idven ];then
echo "未检测到USB接口有U盘接入!"
else
echo "\"$idven$idpro\" USB接口有U盘接入!"
break
fi
sleep 20
done
编写传送USB设备文件脚本
vim monitor_usb.sh
代码如下(示例):
#!/bin/bash
# Monitor USB device
# 创建虚拟机需要的USB设备文件
if [ ! -f /opt/usb.xml ];then
touch /opt/usb.xml
echo -e "<hostdev mode='subsystem' type='usb' managed='yes'>\n\
<source>\n\
<vendor id='0x$idven'/>\n\
<product id='0x$idpro'/>\n\
</source>\n</hostdev>" >/opt/usb.xml
else
echo "文件已存在!" >/dev/null
fi
# 获取USB端口 idVendor,idProduct
while :
do
sh /root/script/jk_usb.sh
idven=`awk -F '[,=]' '/New USB device found, idVendor/{print $3}' /var/log/messages | tail -1`
idpro=`awk -F '[,=]' '/New USB device found, idVendor/{print $5}' /var/log/messages | tail -1`
oldid=`awk -F '[=/x'\'']' '/vendor/{print $4}' /opt/usb.xml`
oldip=`awk -F '[=/x'\'']' '/product/{print $4}' /opt/usb.xml`
# 检查当前设备使用状态
cat status.txt | grep "0"
if [ $? -eq 0 ];then
echo "当前 \"$oldid$oldip\" 设备正在使用中。。。"
else
echo "更换设备请稍后。。。"
# 替换上一次idVendor,idProduct
cp -r /opt/usb.xml /opt/bak_usb.xml
sed -i '3 s/'0x$oldid'/'\0x$idven'/g' /opt/usb.xml
sed -i '4 s/'0x$oldip'/'\0x$idpro'/g' /opt/usb.xml
# 清空系统日志消息
cat /dev/null >/var/log/messages
# 删除上次发送的yml文件
virsh detach-device dianxin_video /opt/usb.xml >/dev/null
# 发送到虚拟机设备文件
virsh attach-device dianxin_video /opt/usb.xml
#远程登录虚拟机执行脚本
ansible-playbook /root/script/tviewer.yml
fi
sleep 20
3.编写Python发送脚本
本地日志提示python脚本
vim feishugerenlocal_cpg.py
代码如下(示例):
#!/usr/bin/python3
# encoding: utf-8
import json
import requests
import sys
messages = sys.argv[1]
content = "视频拷贝到本地日志: \n %s" % messages
def gettenant_access_token():
# 获取应用token
tokenurl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
headers = {"Content-Type": "application/json"}
data = {
"app_id": "cli_a1960ffb******", # 飞书应用的ID
"app_secret": "121cF*****" # 飞书应用的Secret
}
request = requests.post(url=tokenurl, headers=headers, json=data)
response = json.loads(request.content)['tenant_access_token']
return response
def getuserid(tenant_access_token):
# 获取User_ID
mobiles = "18888666664" #个人飞书登录的手机号
userurl = "https://open.feishu.cn/open-apis/user/v1/batch_get_id?mobiles=%s" % mobiles
headers = {"Authorization": "Bearer %s" % tenant_access_token}
request = requests.get(url=userurl, headers=headers)
response = json.loads(request.content)['data']['mobile_users'][mobiles][0]['user_id']
print(json.loads(request.content))
return response
def sendmes(user_id, tenant_access_token):
sendurl = "https://open.feishu.cn/open-apis/message/v4/send/"
headers = {"Authorization": "Bearer %s" % tenant_access_token, "Content-Type": "application/json"}
# 给个人发送消息
data = {"user_id": user_id,
"msg_type": "text",
"content": {
"text": "<at user_id=\"%s\">test</at>\n \n %s" % (user_id, content)
}
}
requests.post(url=sendurl, headers=headers, json=data)
tenant_access_token = gettenant_access_token()
user_id = getuserid(tenant_access_token)
sendmes(user_id, tenant_access_token)
拷贝到OSS存储的日志脚本
vim feishugerenoss_cpg.py
代码如下(示例):
#!/usr/bin/python3
# encoding: utf-8
import json
import requests
import sys
messages = sys.argv[1]
content = "视频拷贝到OSS日志: \n %s" % messages
def gettenant_access_token():
# 获取应用token
tokenurl = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
headers = {"Content-Type": "application/json"}
data = {
"app_id": "cli_a1960ffb******", # 飞书应用的ID
"app_secret": "111CF*****" # 飞书应用的Secret
}
request = requests.post(url=tokenurl, headers=headers, json=data)
response = json.loads(request.content)['tenant_access_token']
return response
def getuserid(tenant_access_token):
# 获取User_ID
mobiles = "18888666664" #个人飞书登录的手机号
userurl = "https://open.feishu.cn/open-apis/user/v1/batch_get_id?mobiles=%s" % mobiles
headers = {"Authorization": "Bearer %s" % tenant_access_token}
request = requests.get(url=userurl, headers=headers)
response = json.loads(request.content)['data']['mobile_users'][mobiles][0]['user_id']
print(json.loads(request.content))
return response
def sendmes(user_id, tenant_access_token):
sendurl = "https://open.feishu.cn/open-apis/message/v4/send/"
headers = {"Authorization": "Bearer %s" % tenant_access_token, "Content-Type": "application/json"}
# 给个人发送消息
data = {"user_id": user_id,
"msg_type": "text",
"content": {
"text": "<at user_id=\"%s\">test</at>\n \n %s" % (user_id, content)
}
}
requests.post(url=sendurl, headers=headers, json=data)
tenant_access_token = gettenant_access_token()
user_id = getuserid(tenant_access_token)
sendmes(user_id, tenant_access_token)
4.编写虚拟机脚本
vim mount.sh
代码如下(示例):
#!/bin/bash
# Mount the USB flash drive and copy it to the specified directory
# Send flying books when finished
HOST="192.168.168.11" #物理机IP
USER="root"
PASSWARD="Yct3****"
FILE="/root/script/status.txt" #状态文件路径放在物理机脚本同级目录
TOFILE="/root/script/" #物理机脚本目录
#获取挂载盘
diskid=`lsblk | awk '{print $1,$4}' | grep -v ^[A-Z] | grep -E 'G|T' | tail -1 | awk -F '[─ ]' '{print $2}'`
mdir="/dianxin_video"
#先取消一下挂载(不管之前有没有挂载)
umount /video
#挂载U盘
mount /dev/$diskid $mdir
if [ $? = 0 ];then
echo "挂载成功!" > /root/sh.log
else
echo "请检查挂载!" > /root/sh.log
exit 1
fi
#创建状态文件传回物理机
echo "当前设备状态: 0" > /root/script/status.txt
expect -c "
spawn scp $FILE $USER@$HOST:$TOFILE
expect {
\"*assword\" {set timeout 300; send \"$PASSWARD\r\"; exp_continue;}
\"yes/no\" {send \"yes\r\";}
}
expect eof"
#查询U盘SN,创建拷贝目录 (通过SN码区别不同的U盘)
DISKID=`echo $diskid | awk -F "" '
{
for (i=1;i<=NF;i++)
{
if ($i ~ /[[:lower:]]/)
{
str=$i
str1=(str1 str)
}
}
print str1
}'`
USBSN=`lsblk -n --nodeps -o name,serial /dev/$DISKID | awk '{print $2}' `
DIR=`date +%Y%m%d`
if [ ! -d /root/video/$USBSN/$DIR ];then
mkdir -p /root/video/$USBSN/$DIR
else
echo "目录已存在!" > /root/sh.log
fi
#拷贝U盘中的文件到本地(指定U盘要拷贝的数据路径,这里是所有数据)
nohup cpg -rg /video/* /root/video/$USBSN/$DIR/ > /root/cp.log 2>&1 &
sleep 1
#发送copy到本地日志
str1=`cat /root/cp.log | tail -1`
string="copy到本地时发生错误请检查!"
grep -E "error|warning|failed" /root/cp.log
#检查到错误信息停止执行发送消息
if [ $? -eq 0 ];then
python3 /root/script/feishugerenlocal_cpg.py "$string"
exit 1
else
python3 /root/script/feishugerenlocal_cpg.py "${str1:5}"
fi
echo "${str1:5}"
#创建oss目录
if [ ! -d /ossfs/视频/$USBSN ];then
mkdir /ossfs/视频/$USBSN
else
echo "目录已存在!" > /root/sh.log
fi
#拷贝本地的文件到阿里OSS存储
nohup cpg -rg /root/video/$USBSN/$DIR /ossfs/视频/$USBSN > /root/cp.log 2>&1 &
sleep 1
#发送copy到OSS日志
str2=`cat /root/cp.log | tail -1`
string2="copy到阿里OSS存储时发生错误请检查!"
grep -E "error|warning|failed" /root/cp.log
#检查到错误信息停止执行发送消息
if [ $? -eq 0 ];then
python3 /root/script/feishugerenoss_cpg.py "$string2"
exit 1
else
python3 /root/script/feishugerenoss_cpg.py "${str2:5}"
fi
#完成后返回状态文件传回物理机作为下次查询
echo "当前设备状态: 1" > /root/script/status.txt
expect -c "
spawn scp $FILE $USER@$HOST:$TOFILE
expect {
\"*assword\" {set timeout 300; send \"$PASSWARD\r\"; exp_continue;}
\"yes/no\" {send \"yes\r\";}
}
EPpect eof"
5.测试并验证结果
在物理机上执行
sh monitor_usb.sh
拷贝到虚拟机验证结果
拷贝到阿里云OSS验证结果
发送消息至飞书验证结果
6.创建自动执行拷贝
启动命令在物理机执行
nohup sh monitor_usb.sh > cp.log 2>&1 &