diff options
author | Selvasundaram <selvam@gluster.com> | 2011-11-24 14:28:46 +0530 |
---|---|---|
committer | Selvasundaram <selvam@gluster.com> | 2011-11-24 14:28:46 +0530 |
commit | 8c7203104004e425579a4fcbc1b9b91bb82f8f2e (patch) | |
tree | 4cdbc20ee60ddffde626ae2b1ff9215e406fb635 /src | |
parent | 7476d5ee5b3f96ef8b637a4a016634cb1d098187 (diff) |
Disk Initialization enhanced with user selectable file system and mount point
Diffstat (limited to 'src')
8 files changed, 177 insertions, 26 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 3d27afb2..cb3519b1 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -31,6 +31,7 @@ import com.gluster.storage.management.core.constants.RESTConstants; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.ServerStats; import com.gluster.storage.management.core.response.GlusterServerListResponse; +import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.sun.jersey.api.representation.Form; import com.sun.jersey.core.util.MultivaluedMapImpl; @@ -76,9 +77,16 @@ public class GlusterServersClient extends AbstractClient { return postRequest(form); } - public URI initializeDisk(String serverName, String diskName, String fsType) { + public List<String> getFSType(String serverName) { + List<String> fsType = ((StringListResponse) fetchSubResource(serverName + "/" + RESTConstants.RESOURCE_FSTYPE, + StringListResponse.class)).getData(); + return fsType; + } + + public URI initializeDisk(String serverName, String diskName, String fsType, String mountPoint) { Form form = new Form(); form.add(RESTConstants.FORM_PARAM_FSTYPE, fsType); + form.add(RESTConstants.FORM_PARAM_MOUNTPOINT, fsType); return putRequestURI(serverName + "/" + RESTConstants.RESOURCE_DISKS + "/" + diskName, form); } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/InitializeDiskTypeSelection.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/InitializeDiskTypeSelection.java index 4b64ea96..b484d6d2 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/InitializeDiskTypeSelection.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/dialogs/InitializeDiskTypeSelection.java @@ -21,23 +21,30 @@ *******************************************************************************/ package com.gluster.storage.management.console.dialogs; -import java.util.ArrayList; import java.util.List; import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.Hyperlink; import com.gluster.storage.management.console.utils.GUIHelper; -import com.gluster.storage.management.core.constants.GlusterConstants; public class InitializeDiskTypeSelection extends Dialog { @@ -46,9 +53,16 @@ public class InitializeDiskTypeSelection extends Dialog { private Composite initializeDiskTypeComposite; private Composite composite; private String fsType; + private String mountPointText; + private Text mountPoint; + private String deviceName; + private List<String> possibleFsType; + private String defaultMountPoint = "/export/"; - public InitializeDiskTypeSelection(Shell parentShell) { + public InitializeDiskTypeSelection(Shell parentShell, String formatingDeviceName, List<String> possibleFsType) { super(parentShell); + this.possibleFsType = possibleFsType; + this.deviceName = formatingDeviceName; // TODO Auto-generated constructor stub } @@ -98,32 +112,84 @@ public class InitializeDiskTypeSelection extends Dialog { GridLayout layout = new GridLayout(3, false); initializeDiskTypeComposite.setLayout(layout); - createLabel(initializeDiskTypeComposite, "Format disk using "); + createLabel(initializeDiskTypeComposite, "File system "); createFormatTypeCombo(initializeDiskTypeComposite); - createLabel(initializeDiskTypeComposite, " file system"); + createLabel(initializeDiskTypeComposite, "Mount point "); + createMountPointText(initializeDiskTypeComposite); + createChangeLink(initializeDiskTypeComposite); } private void createLabel(Composite composite, String labelText) { Label formatTypeLabel = new Label(composite, SWT.NONE); formatTypeLabel.setText(labelText); - formatTypeLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + formatTypeLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false)); } private void createFormatTypeCombo(Composite composite) { - List<String> fsType = new ArrayList<String>(); - fsType.add(GlusterConstants.FSTYPE_DEFAULT); - fsType.add(GlusterConstants.FSTYPE_EXT_3); - fsType.add(GlusterConstants.FSTYPE_EXT_4); - fsType.add(GlusterConstants.FSTYPE_XFS); formatTypeCombo = new Combo(composite, SWT.READ_ONLY); - formatTypeCombo.setItems(fsType.toArray(new String[0])); + formatTypeCombo.setItems(possibleFsType.toArray(new String[0])); formatTypeCombo.select(0); + new Label(composite, SWT.NONE); } + private void createMountPointText(Composite container) { + mountPoint = new Text(container, SWT.BORDER); + GridData txtNameData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); + txtNameData.horizontalSpan = 1; + txtNameData.widthHint = 400; + mountPoint.setTextLimit(100); + mountPoint.setLayoutData(txtNameData); + mountPoint.setText(defaultMountPoint + deviceName); + mountPoint.setEnabled(false); + mountPoint.addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + validateMountPoint(mountPoint.getText().trim()); + } + }); + } + + private void createChangeLink(Composite container) { + final Hyperlink changeLink = new Hyperlink(container, SWT.UNDERLINE_SINGLE); + changeLink.setText("change"); + changeLink.setUnderlined(true); + changeLink.setForeground(new Color(Display.getDefault(), 0, 0, 255)); + + changeLink.addHyperlinkListener(new HyperlinkAdapter() { + + // private void finishEdit() { + // changeLink.setText("change"); + // mountPoint.setEnabled(false); + // } + + private void startEdit() { + // changeLink.setText("update"); + changeLink.setVisible(false); + mountPoint.setEnabled(true); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + if (mountPoint.isEnabled()) { + // we were already in edit mode. + // finishEdit(); + } else { + // Get in to edit mode + startEdit(); + } + } + }); + } + @Override protected void okPressed() { - fsType = formatTypeCombo.getText(); - super.okPressed(); + fsType = formatTypeCombo.getText().trim(); + mountPointText = mountPoint.getText().trim(); + if (validateForm()) { + super.okPressed(); + } else { + MessageDialog.openError(getShell(), "Error: Validation error!", "Empty or Invalid mountpoint."); + } } @Override @@ -131,6 +197,17 @@ public class InitializeDiskTypeSelection extends Dialog { super.cancelPressed(); } + private boolean validateMountPoint(String deviceMountPoint) { + if (deviceMountPoint.isEmpty()) { + return false; + } + return deviceMountPoint.matches("^/.+"); + } + + private boolean validateForm() { + return (!formatTypeCombo.getText().trim().isEmpty() && validateMountPoint( mountPoint.getText().trim())); + } + /** * Overriding to make sure that the dialog is centered in screen */ @@ -142,7 +219,10 @@ public class InitializeDiskTypeSelection extends Dialog { } public String getFSType() { - return fsType.trim(); + return fsType; } + public String getMountPoint() { + return mountPointText; + } } diff --git a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractDisksPage.java b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractDisksPage.java index 417e67ea..b131ccc2 100644 --- a/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractDisksPage.java +++ b/src/com.gluster.storage.management.console/src/com/gluster/storage/management/console/views/pages/AbstractDisksPage.java @@ -19,6 +19,7 @@ package com.gluster.storage.management.console.views.pages; import java.net.URI; +import java.util.ArrayList; import java.util.List; import org.eclipse.jface.dialogs.MessageDialog; @@ -45,6 +46,7 @@ import com.gluster.storage.management.console.Application; import com.gluster.storage.management.console.GlusterDataModelManager; import com.gluster.storage.management.console.IEntityListener; import com.gluster.storage.management.console.dialogs.InitializeDiskTypeSelection; +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Device; @@ -255,17 +257,26 @@ public abstract class AbstractDisksPage extends AbstractTableTreeViewerPage<Disk return; } - InitializeDiskTypeSelection formatDialog = new InitializeDiskTypeSelection(getShell()); + // To collect the available fsType + GlusterServersClient serversClient = new GlusterServersClient(); + List<String> possibleFsType = new ArrayList<String>(); + try { + possibleFsType = serversClient.getFSType(device.getServerName()); + } catch (GlusterRuntimeException eFsType) { + MessageDialog.openError(getShell(), "Error: File System Type", eFsType.getMessage()); + return; + } + + InitializeDiskTypeSelection formatDialog = new InitializeDiskTypeSelection(getShell(), device.getName(), possibleFsType); int userAction = formatDialog.open(); if (userAction == Window.CANCEL) { formatDialog.cancelPressed(); return; } - GlusterServersClient serversClient = new GlusterServersClient(); try { - URI uri = serversClient.initializeDisk(device.getServerName(), device.getName(), formatDialog.getFSType()); + URI uri = serversClient.initializeDisk(device.getServerName(), device.getName(), formatDialog.getFSType(), formatDialog.getMountPoint()); TasksClient taskClient = new TasksClient(); TaskInfo taskInfo = taskClient.getTaskInfo(uri); @@ -289,6 +300,7 @@ public abstract class AbstractDisksPage extends AbstractTableTreeViewerPage<Disk } guiHelper.showTaskView(); } catch (Exception e1) { + e1.printStackTrace(); MessageDialog.openError(getShell(), "Error: Initialize disk", e1.getMessage()); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java index cc32d109..99171c3e 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java @@ -44,6 +44,7 @@ public class RESTConstants { public static final String RESOURCE_KEYS = "keys"; public static final String RESOURCE_STATISTICS = "statistics"; public static final String RESOURCE_USERS = "users"; + public static final String RESOURCE_FSTYPE = "fstype"; public static final String TASK_START = "start"; public static final String TASK_PAUSE = "pause"; @@ -87,6 +88,7 @@ public class RESTConstants { public static final String FORM_PARAM_OLD_PASSWORD = "oldPassword"; public static final String FORM_PARAM_NEW_PASSWORD = "newPassword"; public static final String FORM_PARAM_FORCE = "force"; + public static final String FORM_PARAM_MOUNTPOINT = "mountPoint"; public static final String PATH_PARAM_FORMAT = "format"; public static final String PATH_PARAM_VOLUME_NAME = "volumeName"; diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/GlusterServersResource.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/GlusterServersResource.java index 8d3784e9..ccb11726 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/GlusterServersResource.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/resources/v1_0/GlusterServersResource.java @@ -20,6 +20,7 @@ package com.gluster.storage.management.gateway.resources.v1_0; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_FSTYPE; import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_SERVER_NAME; +import static com.gluster.storage.management.core.constants.RESTConstants.FORM_PARAM_MOUNTPOINT; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_CLUSTER_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME; import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME; @@ -30,6 +31,7 @@ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_ import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_PERIOD; import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TYPE; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS; +import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_FSTYPE; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_SERVERS; import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_STATISTICS; @@ -63,6 +65,7 @@ import com.gluster.storage.management.core.model.ServerStats; import com.gluster.storage.management.core.model.TaskStatus; import com.gluster.storage.management.core.response.GlusterServerListResponse; import com.gluster.storage.management.core.response.ServerNameListResponse; +import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.gateway.data.ClusterInfo; import com.gluster.storage.management.gateway.services.ClusterService; import com.gluster.storage.management.gateway.services.GlusterServerService; @@ -197,12 +200,19 @@ public class GlusterServersResource extends AbstractResource { return noContentResponse(); } + @GET + @Produces(MediaType.APPLICATION_XML) + @Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_FSTYPE) + public StringListResponse getFsType(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName) { + return glusterServerService.getFsType(clusterName, serverName); + } + @PUT @Produces(MediaType.APPLICATION_XML) @Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_DISKS + "/{" + PATH_PARAM_DISK_NAME + "}") public Response initializeDisk(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName, @PathParam(PATH_PARAM_SERVER_NAME) String serverName, @PathParam(PATH_PARAM_DISK_NAME) String diskName, - @FormParam(FORM_PARAM_FSTYPE) String fsType) { + @FormParam(FORM_PARAM_FSTYPE) String fsType, @FormParam(FORM_PARAM_MOUNTPOINT) String mountPoint) { if (clusterName == null || clusterName.isEmpty()) { return badRequestResponse("Cluster name must not be empty!"); @@ -221,7 +231,7 @@ public class GlusterServersResource extends AbstractResource { // return badRequestResponse("Parameter [" + FORM_PARAM_FSTYPE + "] is missing in request!"); } - InitializeDiskTask initializeTask = new InitializeDiskTask(clusterService, clusterName, serverName, diskName, fsType); + InitializeDiskTask initializeTask = new InitializeDiskTask(clusterService, clusterName, serverName, diskName, fsType, mountPoint); try { initializeTask.start(); // Check the initialize disk status diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterServerService.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterServerService.java index da1a8487..fcaec52e 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterServerService.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/services/GlusterServerService.java @@ -35,6 +35,7 @@ import com.gluster.storage.management.core.exceptions.GlusterValidationException import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Server.SERVER_STATUS; +import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.core.utils.GlusterCoreUtil; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.core.utils.StringUtil; @@ -142,6 +143,20 @@ public class GlusterServerService { return server; } } + + // Server not found. It's possible that the server name returned by glusterfs is actually IP address + // Hence fetch details of all servers and then compare the host names again. + String errMsg = fetchDetailsOfServers(Collections.synchronizedList(servers)); + if (!errMsg.isEmpty()) { + throw new GlusterRuntimeException("Couldn't fetch details for server(s): " + errMsg); + } + for (GlusterServer server : servers) { + if (server.getName().equalsIgnoreCase(serverName)) { + return server; + } + } + + // still not found! return null; } @@ -504,4 +519,12 @@ public class GlusterServerService { } } } + + public StringListResponse getFsType(String clusterName, String serverName) { + if (isValidServer(clusterName, serverName)) { + return serverUtil.getFsType(serverName); + } else { + throw new GlusterRuntimeException(serverName + " is not belongs to the cluster [" + clusterName + "]"); + } + } } diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/tasks/InitializeDiskTask.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/tasks/InitializeDiskTask.java index 4c437737..ffb9619d 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/tasks/InitializeDiskTask.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/tasks/InitializeDiskTask.java @@ -43,10 +43,11 @@ public class InitializeDiskTask extends Task { private String serverName; private String diskName; private String fsType; + private String mountPoint; private ServerUtil serverUtil; public InitializeDiskTask(ClusterService clusterService, String clusterName, String serverName, String diskName, - String fsType) { + String fsType, String deviceMountPoint) { // Reference contains "Server:disk" super(clusterService, clusterName, TASK_TYPE.DISK_FORMAT, serverName + ":" + diskName, "Initialize disk " + serverName + ":" + diskName, false, false, false); @@ -54,6 +55,7 @@ public class InitializeDiskTask extends Task { setServerName(serverName); setDiskName(diskName); setFsType(fsType); + setMountpoint(deviceMountPoint); taskInfo.setName(getId()); init(); } @@ -117,10 +119,8 @@ public class InitializeDiskTask extends Task { } private void startInitializeDisk(String serverName) { - String fsTypeCommand = (getFsType().equals(GlusterConstants.FSTYPE_DEFAULT)) ? "" : " -t " + getFsType(); - - String output = serverUtil.executeScriptOnServer(serverName, INITIALIZE_DISK_SCRIPT + fsTypeCommand + " " - + getDiskName()); + String output = serverUtil.executeScriptOnServer(serverName, INITIALIZE_DISK_SCRIPT + getFsType() + " " + + mountPoint + " " + getDiskName() ); TaskStatus taskStatus = new TaskStatus(new Status(Status.STATUS_CODE_RUNNING, output)); taskStatus.setPercentageSupported((getFsType().equals(GlusterConstants.FSTYPE_XFS)) ? false : true); getTaskInfo().setStatus(taskStatus); @@ -187,4 +187,12 @@ public class InitializeDiskTask extends Task { public String getFsType() { return fsType; } + + public void setMountpoint(String deviceMountPoint) { + this.mountPoint = deviceMountPoint; + } + + public String getMountpoint() { + return mountPoint; + } } diff --git a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/utils/ServerUtil.java b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/utils/ServerUtil.java index 0d09d616..b53d0042 100644 --- a/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/utils/ServerUtil.java +++ b/src/com.gluster.storage.management.gateway/src/com/gluster/storage/management/gateway/utils/ServerUtil.java @@ -44,6 +44,7 @@ import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Server.SERVER_STATUS; import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.response.StringListResponse; import com.gluster.storage.management.core.utils.ProcessResult; import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.gateway.services.GlusterInterfaceService; @@ -65,6 +66,7 @@ public class ServerUtil { private static final String SCRIPT_COMMAND = "python"; private static final String REMOTE_SCRIPT_GET_DISK_FOR_DIR = "get_disk_for_dir.py"; private static final String REMOTE_SCRIPT_GET_SERVER_DETAILS = "get_server_details.py"; + private static final String REMOTE_SCRIPT_GET_FILE_SYSTEM_TYPE = "get_filesystem_type.py"; private static final String REMOTE_SCRIPT_BASE_DIR = "/opt/glustermg"; private static final String REMOTE_SCRIPT_DIR_NAME = "backend"; @@ -360,4 +362,10 @@ public class ServerUtil { ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); return ctx.getBean(clazz); } + + public StringListResponse getFsType(String serverName) { + String output = executeScriptOnServer(serverName, REMOTE_SCRIPT_GET_FILE_SYSTEM_TYPE); + StringListResponse response = new StringListResponse(Arrays.asList(output.trim().split(CoreConstants.NEWLINE))); + return response; + } } |