Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
92 changes: 92 additions & 0 deletions api-server/CSIManager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
## CSI Manager API

### 기능

* PVC 생성, PVC 삭제, PVC 조회, Gluster Subdir 조회

### URL

#### PVC 생성

HTTP

POST http://{CSIManager}:1113/create

- Parameter

|Name|Required|Type|Description|
|:---:|:---:|:---:|:---|
|`pvcName`|True|String|`PVC name`|
|`pvcType`|True|String|`NVMeOF / Gluster`|
|`dupliType`|True|String|`Replica [1,2,3] / Distribute`|
|`CSIManger`|True|Int|`Kubernetes Master IP`|


- Return

|Result|Type|Value|
|:---:|:---:|:---|
|`Success`|JSON|{<br>&nbsp;&nbsp;"pvName":[PV Name]<br>}|
|`Fail`|String|Error Message|

#### PVC 삭제

HTTP

POST http://{CSIManager}:1113/delete

- Parameter

|Name|Required|Type|Description|
|:---:|:---:|:---:|:---|
|`pvcName`|True|String|`PVC name`|
|`CSIManger`|True|Int|`Kubernetes Master IP`|


- Return

|Result|Type|Value|
|:---:|:---:|:---|
|`Success`|String|Success Message|
|`Fail`|String|Error Message|

#### PVC 조회

HTTP

POST http://{CSIManager}:1113/get

- Parameter

|Name|Required|Type|Description|
|:---:|:---:|:---:|:---|
|`CSIManger`|True|Int|`Kubernetes Master IP`|


- Return

|Result|Type|Value|
|:---:|:---:|:---|
|`Success`|JSON|[<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;"pvcName" : [PVC Name],<br>&nbsp;&nbsp;&nbsp;&nbsp;"pvcType" : [NVMeOF/Gluster],<br>&nbsp;&nbsp;&nbsp;&nbsp;"dupliType" : [Replica{1,2,3} / Distribute],<br>&nbsp;&nbsp;&nbsp;&nbsp;"subdir" : "subvol/ce/3d/"<br>&nbsp;&nbsp;},<br>] |
|`Fail`|String|Error Message|

#### subdir 조회

HTTP

POST http://{CSIManager}:1113/getSubdir

- Parameter

|Name|Required|Type|Description|
|:---:|:---:|:---:|:---|
|`ip`|True|String|`POD IP`|
|`CSIManger`|True|Int|`Kubernetes Master IP`|


- Return

|Result|Type|Value|
|:---:|:---:|:---|
|`Success`|JSON|{<br>&nbsp;&nbsp;"data" : [Subdir , VolumeName] <br>}|
|`Fail`|String|Error Message|
129 changes: 129 additions & 0 deletions api-server/CSIManager/csimanager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from flask import Flask, request
import os
import yaml
import subprocess

app = Flask(__name__)

_DIS = "kadalu.gluster-vol"
_REP1 = ""
_REP2 = ""
_REP3 = ""

def applyPVC(name):
cmd = "kubectl create -f yaml/%s"%name
err, msg = subprocess.getstatusoutput(cmd)

def createPVC(pvcName,pvcType,scName,limit):
pass
template = ""
yamlName = "%s_pvc.yaml"%(pvcName)
with open('template_pvc.yaml','r') as f:
template = yaml.load(f,Loader=yaml.FullLoader)

template["metadata"]["name"] = pvcName
template["spec"]["storageClassName"] = scName
template["spec"]["resources"]["requests"]["storage"] = limit

with open("yaml/%s"%yamlName,'w') as f:
yaml.dump(template,f,default_flow_style=False)

applyPVC(yamlName)

@app.route("/getSubdir",methods=["GET","POST"])
def getSubdir():
if request:
ip = str(request.form["ip"])

podCMD = '''kubectl get pod -o json | jq '.items[] | select(.status.podIP=="%s") | .metadata.name' '''%ip
err, podName = subprocess.getstatusoutput(podCMD)

pvcCMD = '''kubectl get pod/%s -o json | jq -r ".spec.volumes[0].persistentVolumeClaim.claimName" '''%podName
err, pvcName = subprocess.getstatusoutput(pvcCMD)

pvCMD = '''kubectl get pvc/%s -o json | jq -r ".spec.volumeName" '''%pvcName
err, pvName = subprocess.getstatusoutput(pvCMD)

subdirCMD = '''kubectl get pv/%s -o json | jq -r ".spec.csi.volumeAttributes.path" '''%pvName
err, subDir = subprocess.getstatusoutput(subdirCMD)

scCMD = '''kubectl get pvc/%s -o json | jq -r ".spec.storageClassName" '''%pvcName
err, scName = subprocess.getstatusoutput(scCMD)

glsCMD = '''kubectl get sc/%s -o json | jq -r ".parameters.gluster_volname" '''%scName
err, volName = subprocess.getstatusoutput(glsCMD)

subDir = subDir.replace("\n","")
volName = volName.replace("\n","")

return {"data" : [subDir,volName]}

@app.route("/create",methods=["GET","POST"])
def create():
if request:
pvcName = str(request.form["pvcName"])
pvcType = str(request.form["pvcType"])
dupliType = str(request.form["dupliType"])
limit = str(request.form["limit"])

scName = ""

if dupliType == "distribute":
scName = _DIS
elif dupliType == "replica1":
scName = _REP1
elif dupliType == "replica2":
scName = _REP2
elif dupliType == "replica3":
scName = _REP3

createPVC(pvcName,pvcType,scName,limit)

return pvcName

@app.route("/delete",methods=["GET","POST"])
def delete():
if request:
pvcName = str(request.form["pvcName"])

cmd = "kubectl delete pvc/%s && rm -f yaml/%s_pvc.yaml"%(pvcName,pvcName)
err, msg = subprocess.getstatusoutput(cmd)

return msg

@app.route("/get",methods=["GET","POST"])
def get():
if request:
result = []

cmd = "kubectl get pvc"
err, res = subprocess.getstatusoutput(cmd)
res = res.split("\n")[1:]

for r in res:
pvc = {}
r = r.split()

pvc["name"] = r[0]
if "kadalu" in r[5]:
pvc["pvcType"] = "Gluster"
if "vol1" in r[5]:
pvc["dupliType"] = "Replica 1"
elif "vol2" in r[5]:
pvc["dupliType"] = "Replica 2"
elif "vol3" in r[5]:
pvc["dupliType"] = "Replica 3"
else:
pvc["dupliType"] = "Distribute"

cmd = '''kubectl get pv/%s -o json | jq -r ".spec.csi.volumeAttributes.path" '''%r[2]
err, subdir = subprocess.getstatusoutput(cmd)
pvc["subdir"] = subdir
else:
pvc["pvcType"] = "NVMeOF"
result.append(pvc)

return {"result":result}

if __name__ == "__main__":
app.run(host="0.0.0.0",port=1113)
Binary file not shown.
Binary file added api-server/LB2PBA/API 정의서/LBA2PBA API.docx
Binary file not shown.
162 changes: 162 additions & 0 deletions api-server/LB2PBA/LBA2PBA_Manager/lba2pba_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import os
import subprocess
import json
import requests as re
from flask import Flask, request


app = Flask(__name__)

def getVolumeHost(volume):
pass
cmd = "gluster volume info %s | grep Brick"%(volume)
err, res = subprocess.getstatusoutput(cmd)

hosts = {}
if err != 0:
return 1, res
else:
res = res.split("\n")[2:]

for r in res:
host = r.split(":")[1][1:]
birck = r.split(":")[2]

hosts[host] = birck


return 0, hosts




def getGfid(firstFile):
pass
path = firstFile["path"]
host = firstFile["host"]

gfid = ""

cmd = "ssh %s 'getfattr -d -m. -e hex %s'"%(host,path)
err, res = subprocess.getstatusoutput(cmd)

if err == 0:
gfid = res.split("gfid=0x")[1].split("\n")[0]

return 0, gfid

return 1, res

def getShardList(path,volume):
pass
err, hosts = getVolumeHost(volume)
if err != 0:
return err, hosts

shardList = list()

firstFile = {}


for host in hosts.keys():
brick = hosts[host]
fullPath = brick + "/" + path

cmd = "ssh %s 'ls %s'"%(host,fullPath)
err, res = subprocess.getstatusoutput(cmd)

if err == 0:
firstFile["path"] = fullPath
firstFile["host"] = host

err, gfid = getGfid(firstFile)

if err == 0:
for host in hosts.keys():
brick = hosts[host]
shardPath = brick+"/.shard/"

cmd = "ssh %s 'ls %s'"%(host, shardPath)
err ,res = subprocess.getstatusoutput(cmd)

if err == 0:
shards = res.split("\n")

for shard in shards:
if gfid in shard.replace("-",""):
shardList.append({"path": shardPath+shard, "host": host})

shardList = sorted(shardList, key=(lambda x: x["path"]))
shardList.insert(0,firstFile)

return shardList

def file2PBA(host,fName):
pass
data = {"fName":fName}
url = "http://%s:9999/query/block/simple"%host

res = json.loads(re.post(url,data=data).json())["RES"]

result = []

for file_dict in res["LIST"]:

for chunk in file_dict["CHUNKS"]:
pba = {}

pba["OFFSET"] = chunk["OFFSET"]
pba["LENGTH"] = chunk["LENGTH"]
pba["HOST"] = host
pba["DISK"] = file_dict["DISK"]

result.append(pba)

print("file2PBA : ",result)

return result




@app.route("/getPBA",methods=['GET','POST'])
def getPBA():
pass

if request:
path = str(request.form['path'])
volume = str(request.form["volume"])

fPath,fName = os.path.split(path)


result = {"name":fName,"fpath":fPath}

shardList = getShardList(path,volume)

data = []

print(shardList)

for shard in shardList:
host = shard["host"]
path = shard["path"]

data.extend(file2PBA(host,path))

ran = 0
for i in range(len(data)):
start = ran
end = ran + data[i]["LENGTH"]

data[i]["RANGE"] = [ran, end]

ran = end

result["data"] = data

return json.dumps(result)

if __name__ == "__main__":
app.run(host="0.0.0.0",port=1111)

Loading