Hyper-V Cmdlet 활용 알고리즘 고안하기
일단 생성파일을 실행시키도록 하는 기능은 해결되었으니, 이제 알고리즘을 구현할 시간이 왔다.
앞 글에서 언급했다시피, Hyper-V는 Power-shell Cmdlet을 지원한다.
서버에서 생성파일을 실행시킬때 필요한 정보들을 인자로 넘겨줄 수 없기때문에, DB의 정보를 불러와서 생성하는 알고리즘을 고안할 필요가 있었다.
요점은 생성파일이 만들어야할 서버정보를 인지하는데 식별할수있는 컬럼을 추가하는 아이디어이다.
알고리즘 :
1. 유저가 서버를 생성요청을 한다.
2,서버 생성에 필요한 정보를 입력하면, Vm정보가 저장된다.
이때 저장되는 컬럼중 trans의 값을 True로 저장한다.
참고로, service_num은 미리 옵션별 스펙을 어드민이 관리하는 DB안에 미리 세팅해뒀기때문에 서비스 번호만 통일해주면 나중에 유지, 보수가 편리하도록 구상했다.
위처럼 service_num에 해당하는 필수적인 정보를 미리 입력해두고, 나중에 서비스사업자의 변동요구가 생기면 수정하기만 하면 된다.
3. Vm정보를 저장한 후, powershell 실행파일내에서 trans가 True인 Vm의 정보를 검색한다.
4.저장된 정보대로 Vm을 생성하고, 완료되면 trans의 값을 False로 변경하여 저장한다.
이 알고리즘의 핵심은 DB를 교두보로 활용하여, 서버와 실행파일간의 상호작용을 가능케 하는것이다.
서버 코드(app.py), 서버 생성스크립트(create_vm.ps1)
코드를 함께 보며 디테일을 확인해보자.
app.py:
@app.route('/create', methods=['GET','POST'])
def create():
user_id = session.get('login',None)
if user_id == None:
return redirect(url_for("login"))
if request.method == 'GET':
return render_template('create.html',user_info = user.find_one({"user_id":user_id}), price = admin.find_one({"lable":"price"}))
else:
#로그인에 문제가 없으면 아래코드로 정보 받아오기
result = user.find_one( {'user_id' : user_id})
service_num = request.form['service_num']
nums = number_changer(service_num)
price = admin.find_one({"lable":"price"})
auto = request.form['auto']
autos = boolean_changer(auto)
host_id = request.form['host_id']
host_pw = request.form['host_pw']
host_pw2 = request.form['host_pw2']
end_time = datetime.today() + relativedelta(months= +1)
start_time = datetime.today()
pw_hash = hashlib.sha256(host_pw.encode('utf-8')).hexdigest() #패스워드 해쉬화
if host_pw != host_pw2: #패스워드가 맞지 않으면 다시 입력하게 한다
flash("호스트 비밀번호가 다릅니다.")
return render_template('create.html',user_info = user.find_one({"user_id":user_id}), price = admin.find_one({"lable":"price"}))
if result["point"] >= price[nums] : #잔여포인트가 생성에 충분하면
Vm.insert_one({
'user_id':user_id,
'host_pw': pw_hash,
'host_id': host_id,
'auto' : autos,
'service_num' : nums,
'start_time' : start_time,
'end_time': end_time,
'trans':True,#생성 활성화 코드
'running':True})
subprocess.call([".\create.bat"])#생성스크립트 실행
sleep(3)#서버를 생성할 시간을 벌어준다
after_point = result["point"] - price[nums]#포인트 차감
user.update_one({"user_id":user_id},{"$set":{"point":after_point}})#차감 포인트 반영
Vm.update_one({"trans":True},{"$set":{"trans":False}})#생성 컬럼 비활성화
flash("서버가 성공적으로 생성되었습니다.")
return redirect(url_for("main"))
else:
flash("포인트가 부족합니다.")
return redirect(url_for('create'))
create_Vm.ps1:
#powershell에서 mongoDB를 제어할 수 있도록 하는 CSharpDriver를 연결한다.
$mongoDbDriverPath = "c:\Program Files (x86)\MongoDB\CSharpDriver 1.7\"
Add-Type -Path "$($mongoDbDriverPath)\MongoDB.Bson.dll"
Add-Type -Path "$($mongoDbDriverPath)\MongoDB.Driver.dll"
$databaseName = "test"
$collectionName = "Vm"
#DB에 커넥트 한다.
$client = New-Object -TypeName MongoDB.Driver.MongoClient -ArgumentList "mongodb://localhost:27017"
$server = $client.GetServer()
#VM데이터에 접근한다.
$database = $server.GetDatabase($databaseName)
$collection = $database.GetCollection($collectionName)
#검색 쿼리 설정
$query = @{'trans'=$true}#trans가 true인 콜렉션 검색
$col = $collection.FindOne([MongoDB.Driver.QueryDocument]$query)
#필요한 정보 추출
$service_num = $col["service_num"].value
$VMName = $col["host_id"].value
#이번엔 admin데이터에 접근
$databaseName = "admin"
$collectionName = "admin"
$database = $server.GetDatabase($databaseName)
$collection = $database.GetCollection($collectionName)
#서비스 넘버에 맞는 스펙을 가져온다
$query = @{'lable' = $service_num}
$col = $collection.FindOne([MongoDB.Driver.QueryDocument]$query)
$MemoryStartupBytes = $col["MemoryStartupBytes"].value
$NewVHDSizeBytes = $col["NewVHDSizeBytes"].value
$ProcessCore = $col["ProcessCore"].value
$traffic = $col["traffic"].value * 1000000
#이하는 생성 cmdlet
$image = "C:\Users\Public\Documents\Hyper-V\iso\Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.iso"
$VM = @{
Name = $VMName
MemoryStartupBytes = $MemoryStartupBytes
Generation = 2
NewVHDPath = "D:\$VMName.vhdx"
NewVHDSizeBytes = $NewVHDSizeBytes #storage
BootDevice = "VHD"
Path = "C:\ProgramData\Microsoft\Windows\Hyper-V\"
SwitchName = "Default Switch"
}
New-VM @VM
Set-VMNetworkAdapterVlan -VMName $VMName -Access -VlanId 2
Set-VM -VMName $VMName -ProcessorCount $ProcessCore
Set-VMNetworkAdapter -Vmname $VMName -MaximumBandwidth $traffic
Set-VMProcessor $VMName -Count $ProcessCore
Set-VMDvdDrive -Vmname $VMName -path $image
exit
코드로 구현한 모습이다. 파워쉘에서 MongoDB를 컨트롤 하기위해 Csharph driver를 사용했다.
'프로젝트 > hyper-V 웹서비스' 카테고리의 다른 글
[hyper-V 웹 서비스]7.결제 API 구현하기[RESTFUL API!] (0) | 2022.03.17 |
---|---|
[hyper-V 웹 서비스]6.결제 API 이해하기 (0) | 2022.03.17 |
[hyper-V 웹서비스]4.Hyper-v 자동생성 기능 구현(매우중요) -1 (0) | 2022.03.11 |
[hyper-V 웹서비스]3. flask로 MongoDB에서 가져온 정보 html에 넘겨주기 (0) | 2022.03.11 |
[hyper-V 웹서비스]2. flask로 로그인 기능 구현 (0) | 2022.03.11 |