/** * @author 李乾坤 * 进行volume的一系列操作,如创建、开启停止volume,为volume添加或删除brick */ package com.platform.glusterfs; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.junit.Test; import com.platform.utils.Constant; public class SetVolume { public static Logger log = Logger.getLogger(SetVolume.class); /** * 创建volume 返回值:创建并挂载成功 1 1:可以创建 ;-1:brick的ip不在集群中或者未连接; -2 -3 * -4:类型与brick数目不匹配 ; -5 :volumeName 已经存在;-6:挂载点存在且不为空,不能作为挂载点; -7:未知错误 * * @param volumeName * @param count * @param type * @param bricks * @param mountPoint * @return * @see [类、类#方法、类#成员] */ public int createVolume(String volumeName, int count, String type, List bricks, String mountPoint) { log.info("Creat new volume"); // 判断创建volume的条件是否满足 int able = isAbleCreateVolume(volumeName, count, type, bricks, mountPoint); if (able == 1) { String command = null; // 将brics从List变量中提取出来并连接成可以在命令行中使用的格式 String commandarg = concat(bricks); /* * verify the type */ if (type.equals(Constant.distributed)) { command = "gluster volume create " + volumeName + " " + commandarg + "force"; } else if (type.equals(Constant.replica) || type.equals(Constant.stripe)) { command = "gluster volume create " + volumeName + " " + type + " " + count + " " + commandarg + "force"; } // 执行命令 List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); // 创建成功时返回信息格式:volume create: volumename success: if (reStrings == null || reStrings.size() == 0) { log.error("3106 " + command + " run return error"); return -7; } if (reStrings.get(0).contains("volume create: " + volumeName + ": " + "success:")) { log.info("create volume " + volumeName + " successed!"); // 创建成功则启动并进行挂载 if (startVolume(volumeName) == 0) { log.info("start volume " + volumeName + " successed!"); log.info("create "+mountPoint); new CopyData().createFolders(mountPoint); // 进行挂载 String command3 = "mount -t glusterfs " + Constant.hostIp + ":" + volumeName + " " + mountPoint; List reStrings3 = Constant.ganymedSSH.execCmdWaitAcquiescent(command3); if (reStrings3.size() == 0 || reStrings.get(0).contains("GlusterFS is already mounted")) { log.info("mount point successed!"); String addRecord = "echo \"" + volumeName + ":" + mountPoint + "\" >> " + Constant.MountRecord; Constant.ganymedSSH.execCmdNoWaitAcquiescent(addRecord); return 1; } } } else { log.error("3104 volume create failed with error" + reStrings.get(0)); // System.out.println(reStrings.get(0)); return -7; } return 1; } else { log.error("给出的参数不满足创建条件"); // System.out.println("给出的参数不满足创建条件"); return able; } } /** * 删除volume 1 表示成功 ;-1表示volume name不存在;-2表示停止volume 失败; * -3表示删除失败,-4表示/gfsAutoMount/mountPoint.record文件不存在 * @param volumeName * @return * @see [类、类#方法、类#成员] */ public int deleteVolume(String volumeName) { int status = 0; VolumeInfo volumeInfo = new VolumeInfo(); List volumeNames = volumeInfo.showAllVolumeName(); if (!volumeNames.contains(volumeName)) { log.error("3801 " + volumeName + " is not exists !"); return -1; } List mountPoints = volumeInfo.getVolumeMountPoint(volumeName); String cmd = "cat " + Constant.MountRecord; List mountRecord = Constant.ganymedSSH.execCmdWaitAcquiescent(cmd); if (stopVolume(volumeName) != 0) { return -2; } String command = "echo -e \"y\"| gluster volume delete " + volumeName; List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); if (reStrings == null || reStrings.size() == 0 || !(reStrings.get(0).contains("volume delete: " + volumeName + ": success"))) { log.error("3803 : delete volume " + volumeName + " failed !"); return -3; } log.info("delete " + volumeName + " successed!"); if (mountRecord.size() != 0 && mountPoints.get(0).contains(Constant.noSuchFile)) { log.error("3804 : " + Constant.MountRecord + " is not exits"); return -4; } for (String mountPoint : mountPoints) { command = "umount -l " + mountPoint; Constant.ganymedSSH.execCmdNoWaitAcquiescent(command); log.info("umount " + mountPoint + " successed!"); String oneRecord=volumeName+":"+mountPoint; if (mountRecord.contains(oneRecord)) { mountRecord.remove(oneRecord); } } String newRecords=""; for(String one:mountRecord){ newRecords+=one+"\n"; } command="echo -ne \""+newRecords+"\" > "+Constant.MountRecord; Constant.ganymedSSH.execCmdNoWaitAcquiescent(command); return 1; } /** * 为指定的volume添加brick,参数中需要指定类型、数量等 返回值:1成功 ;其他失败 * 过程中需要先检查volume是否存在,还需检查给出的brick数量与类型、count是否相符 * * @param volumeName * @param brickName * @param count * @param type * @return * @see [类、类#方法、类#成员] */ public int addBrickVolume(String volumeName, List brickName, int count, String type) { // 检查是否满足添加bricks的条件 int able = isAble(volumeName, count, type, brickName); if (able != 1) { return able; } String command = ""; log.info("add brick to the specified volume"); String brick = concat(brickName); if (type.equals(Constant.distributed)) command = "gluster volume add-brick " + volumeName + " " + brick + "force"; else if (type.equals(Constant.replica)) command = "gluster volume add-brick " + volumeName + " " + "replica " + count + " " + brick + "force"; else if (type.equals(Constant.stripe)) command = "gluster volume add-brick " + volumeName + " " + "stripe " + count + " " + brick + "force"; List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); // 添加成功的返回信息是:volume add-brick: success if (reStrings != null && reStrings.size() > 0 && reStrings.get(0).contains("volume add-brick: success")) { log.info("添加brick成功!"); return 1; } else { log.error("3205 add brick failed,please check the system"); // System.out.println("3202 add brick failed,please check the // system"); return -5; } } /** * 为指定的volume删除brick,参数中需要指定类型、数量等 返回值:1 成功 ;其他 失败 * 过程中需要先检查volume是否存在,还需检查给出的brick数量与类型、count是否相符 * * @param volumeName * @param brickName * @param count * @param type * @return * @see [类、类#方法、类#成员] */ public int deleteBrickVolume(String volumeName, List brickName, int count, String type) { int able = isAble(volumeName, count, type, brickName); if (able != 1) { return able; } String command = null; log.info("delete brick of the specified volume"); String brick = concat(brickName); if (type.equals(Constant.distributed)) { command = "echo -e \"y\" | gluster volume remove-brick " + volumeName + " " + brick + " force"; } else if (type.equals(Constant.replica)) { command = "echo -e \"y\" | gluster volume remove-brick " + volumeName + " repli " + count + " " + brick + " force"; } else if (type.equals(Constant.stripe)) { command = "echo -e \"y\" | gluster volume remove-brick " + volumeName + " stripe " + count + " " + brick + " force"; } if (command == null) { log.error("3305 remove brick failed,please check the system"); return -5; } log.info("即将执行删除命令"); List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); // System.out.println(reStrings); log.info("删除命令执行完毕"); // 删除成功的返回信息是“volume remove-brick: success” if (reStrings.get(0).contains("volume remove-brick: success")) { { log.info("删除brick成功"); return 1; } } else { log.error("3305 remove brick failed,please check the system"); return -5; } } /* * 停止指定volume 参数中需给出volume的名字 返回值: 0 成功 -1 失败 * 需要先检查volume是否存在,然后判断volume的状态是否已经是停止状态 */ public int stopVolume(String volumeName) { log.info("stop volume"); // 首先需要判断volume是否存在,调用其他函数返回所有volume的名字 boolean volumeExist = false; List volume = new VolumeInfo().showAllVolumeName(); for (String temp : volume) { if (temp.equals(volumeName)) { volumeExist = true; break; } } if (!volumeExist) { // volume不存在 log.error("3501 the volume doesnot exist"); System.out.println("3501 the volume doesnot exist"); return -1; } else { // volume存在,则需判断volume的状态是否已经为“stop” if (new VolumeInfo().getVolumeStatus(volumeName).equals("Stopped")) { log.error("3502 the volume is already stoped"); System.out.println("3502 the volume is already stoped"); return 0; } else { String command = "echo -e \"y\"| gluster volume stop " + volumeName; List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); // 标记操作结果:operation = 1 操作成功 // operation = 0 操作失败 int operation = 0; for (String temp2 : reStrings) { if (temp2.contains("volume stop: " + volumeName + ": " + "success")) { operation = 1; break; } System.out.println("operation: " + operation); } if (operation == 1) { return 0; } else { log.error("3503 stop " + volumeName + " failed"); System.out.println("3503 stop " + volumeName + " failed"); return -1; } } } } /* * 开启指定volume 参数中需给出volume的名字 返回值: 0 成功 -1 失败 * 需要先检查volume是否存在,然后判断volume的状态是否已经是开启状态 */ public int startVolume(String volumeName) { log.info("start volume"); boolean volumeExist = false; List volume = new VolumeInfo().showAllVolumeName(); for (String temp : volume) { if (temp.equals(volumeName)) { volumeExist = true; break; } } if (volumeExist) { if (!(new VolumeInfo().getVolumeStatus(volumeName).equals("Started"))) { String command = "gluster volume start " + volumeName; int operation = 0; // 执行命令 List reStrings = Constant.ganymedSSH.execCmdWaitAcquiescent(command); for (String temp2 : reStrings) { if (temp2.equals("volume start: " + volumeName + ": " + "success")) { operation = 1; } } if (operation == 1) { return 0; } else { log.error("3602 start volume failed"); System.out.println("3602 start volume failed"); return -1; } } else { log.error("volume已经开启"); System.out.println("volume已经开启"); return -1; } } else { log.error("3601 the volume does not exist"); // System.out.println("3601 the volume does not exist"); return -1; } } // 需要将存于List变量中的brick的位置组装成可以在glusterfs命令行中直接使用的格式 public String concat(List brickName) { StringBuffer result = new StringBuffer(); int len = brickName.size(); for (int i = 0; i < len; i++) { result.append(brickName.get(i)); result.append(" "); } return result.toString(); } /* * 只在创建volume时使用此函数 创建volume时对不同数据卷,brick的数量需要满足和count的关系 * 首先判断它们是否满足关系,在不满足的关系的情况下是肯定无法完成操作的 1:可以创建 ;-1:brick的ip不在集群中或者未连接; -2 -3 * -4 :类型与brick数目不匹配 ; -5 :volumeName 已经存在;-6:挂载点存在且不为空,不能作为挂载点; -7:未知错误 */ public int isAbleCreateVolume(String volumeName, int count, String type, List bricks, String mountPoint) { int status = 0; int length = bricks.size(); if (type.equals(Constant.distributed)) { if (count != 0) { log.error("3101 the kind of distributed requires the arg of count to be 0"); return -2; } } if (type.equals(Constant.stripe)) { if (length % count != 0) { log.error("3102 the number of bricks should be the same as or the times of the stripe count"); return -3; } } if (type.equals(Constant.replica)) { if ((length % count) != 0) { log.error( "3103 the number of bricks should be the same as the replicate count or the times of replicate count"); return -4; } } Map peer_status = new ClusterInfo().showClusterInfo(); peer_status.put(Constant.hostIp, Constant.peerincluster_connected); for (String brick : bricks) { brick = brick.split(":")[0]; if (!(peer_status.containsKey(brick) && peer_status.get(brick).equals(Constant.peerincluster_connected))) { log.error("3105 birck " + brick + " ip is not in cluster"); return -1; } } List volumeNames = new VolumeInfo().showAllVolumeName(); if (volumeNames == null) { log.error("3108 showAllVolumeName return error"); return -7; } if (volumeNames.contains(volumeName)) { log.error("3106 " + volumeName + " is already exists! "); return -5; } /* Map datas = new ShowData().showFolderData(mountPoint); if (datas != null && datas.size() > 0) { log.error("3107 " + mountPoint + " is not exists or not empty ! "); return -6; } */ return 1; } /** * 添加或删除volume的brick时,首先需要判断volume是否存在,然后需要判断volume类型、count及brick数目 * * @param volumeName * @param count * @param type * @param bricks * @return 1 满足条件,可以添加;-1 :volume name is not exists;-2,-3,-4 类型与brick数量不匹配; */ public int isAble(String volumeName, int count, String type, List bricks) { List volumeNames = new VolumeInfo().showAllVolumeName(); if (!volumeNames.contains(volumeName)) { log.error("3201:" + volumeName + " is not exists! "); return -1; } int length = bricks.size(); if (type.equals("distribute")) { if (count == 0) return 1; else { log.error("3202: the kind of distributed requires the arg of count to be 0"); // System.out.println(" the kind of distributed requires the // arg of count to be 0"); return -2; } } if (type.equals("stripe")) { if (length % count == 0) return 1; else { log.error("3203: the number of bricks should be the same as or the times of the stripe count"); // System.out.println(" the number of bricks should be the // same as or the times of the stripe count"); return -3; } } if (type.equals("replicate")) { if ((length % count) == 0) return 1; else { log.error( "3204: the number of bricks should be the same as the replicate count or the times of replicate count"); return -4; } } return 1; } @Test public void test_deleteVolume(){ System.out.println(deleteVolume("lili_test1")); } // @Test public void test_createVolume(){ List bricksToCreate = new ArrayList(); bricksToCreate.add("192.168.0.110:/lili_test1"); bricksToCreate.add("192.168.0.116:/lili_test1"); System.out.println(createVolume("lili_test1", 0, "distributed", bricksToCreate, "/home/lili_test1_point")); } public static void main(String[] args) { SetVolume setVolume = new SetVolume(); int operation = 0; // PropertyConfigurator.configure("log4j.properties"); // TODO Auto-generated method stub // 测试创建volume的代码 // List bricksToCreate = new ArrayList(); // bricksToCreate.add("192.168.0.110:/v2"); // bricksToCreate.add("192.168.0.116:/v2"); // operation = setVolume.createVolume("v2", 0, "distributed", bricksToCreate, "/home/v2_point"); // operation = setVolume.deleteVolume("v3"); // // // 以下是测试添加brick的代码 // // List bricksToAdd = new ArrayList(); // bricksToAdd.add("192.168.191.23:/v3"); // operation = setVolume.addBrickVolume("v3", bricksToAdd, 0, // "distribute"); // System.out.println(operation); // 以下代码是测试删除brick的代码 // List bricksToAdd= new ArrayList(); // bricksToAdd.add("192.168.191.23:/v3"); // operation = // setVolume.deleteBrickVolume("v3",bricksToAdd,0,"distribute"); // System.out.println(operation); // 以下是测试start volume的代码 // String volumeToStart = "testcreate" ; // int startOperation = startVolume(volumeToStart); // System.out.println(startOperation); // 以下是测试stop volume String volumeToStop = "v3"; // int startOperation = setVolume.stopVolume(volumeToStop); // 以下是测试创建volume并完成挂载的代码 // List bricksToCreate= new ArrayList(); // bricksToCreate.add("192.168.214.135:/home/create"); // bricksToCreate.add("192.168.214.138:/home/create"); // // int operation = // createVolume("createAndmount",0,"distribute",bricksToCreate,"/mnt/create"); // System.out.println(operation); } }