From 0766ea8fcf31990d07431521c7fc7db7e1acf762 Mon Sep 17 00:00:00 2001 From: Shireesh Anjal Date: Wed, 23 Mar 2011 19:24:44 +0530 Subject: Create Volume --- .../management/client/GlusterDataModelManager.java | 12 +- .../management/client/RunningTaskClient.java | 2 +- .../storage/management/client/VolumesClient.java | 12 +- .../storage/management/core/model/Cluster.java | 4 + .../management/core/model/ClusterListener.java | 2 + .../core/model/DefaultClusterListener.java | 4 + .../storage/management/core/utils/GlusterUtil.java | 64 ++++++++++ .../gui/dialogs/CreateVolumeDisksPage.java | 141 +++++++++++++++++++-- .../management/gui/dialogs/CreateVolumePage1.java | 76 ++++++++++- .../management/gui/dialogs/CreateVolumeWizard.java | 24 +++- .../management/gui/dialogs/SelectDisksDialog.java | 22 +++- .../server/resources/VolumesResource.java | 58 +-------- 12 files changed, 330 insertions(+), 91 deletions(-) diff --git a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java index 01ba6468..4d594f36 100644 --- a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java +++ b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterDataModelManager.java @@ -135,13 +135,23 @@ public class GlusterDataModelManager { } } - private Volume addVolume(List volumes, String name, Cluster cluster, VOLUME_TYPE volumeType, + public Volume addVolume(List volumes, String name, Cluster cluster, VOLUME_TYPE volumeType, TRANSPORT_TYPE transportType, VOLUME_STATUS status) { Volume volume = new Volume(name, cluster, volumeType, transportType, status); volumes.add(volume); return volume; } + + public void addVolume(Volume volume ) { + Cluster cluster = (Cluster)model.getChildren().get(0); + cluster.addVolume(volume); + + for(ClusterListener listener : listeners) { + listener.volumeCreated(volume); + } + } + private void initializeVolumes(Cluster cluster) { List volumes = new ArrayList(); diff --git a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/RunningTaskClient.java b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/RunningTaskClient.java index d2305272..9309cdc8 100644 --- a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/RunningTaskClient.java +++ b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/RunningTaskClient.java @@ -8,7 +8,7 @@ import com.gluster.storage.management.core.model.RunningTask; import com.gluster.storage.management.core.model.RunningTaskListResponse; public class RunningTaskClient extends AbstractClient { - private static final String RESOURCE_NAME = RESTConstants.PATH_PARAM_RUNNING_TASKS; + private static final String RESOURCE_NAME = RESTConstants.RESOURCE_PATH_RUNNING_TASKS; public RunningTaskClient(String securityToken) { super(securityToken); diff --git a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java index f1abb5c1..03e83a31 100644 --- a/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java +++ b/com.gluster.storage.management.client/src/com/gluster/storage/management/client/VolumesClient.java @@ -32,7 +32,6 @@ import com.gluster.storage.management.core.model.Volume; import com.sun.jersey.api.representation.Form; public class VolumesClient extends AbstractClient { - private static final String RESOURCE_NAME = "/cluster/volumes"; // TODO: move to common place public VolumesClient(String securityToken) { super(securityToken); @@ -40,13 +39,17 @@ public class VolumesClient extends AbstractClient { @Override public String getResourceName() { - return RESOURCE_NAME; + return RESTConstants.RESOURCE_PATH_VOLUMES; } @SuppressWarnings("unchecked") public Status createVolume(Volume volume) { - GenericResponse response = (GenericResponse) postObject(GenericResponse.class, volume); - return response.getStatus(); + GenericResponse createVolumeResponse = (GenericResponse) postObject(GenericResponse.class, volume); + + if (!createVolumeResponse.getStatus().isSuccess()) { + return (Status) createVolumeResponse.getStatus(); + } + return (Status) createVolumeResponse.getStatus(); } private Status performOperation(String volumeName, String operation) { @@ -64,6 +67,7 @@ public class VolumesClient extends AbstractClient { return performOperation(volumeName, RESTConstants.FORM_PARAM_VALUE_STOP); } + public static void main(String[] args) { UsersClient usersClient = new UsersClient(); if (usersClient.authenticate("gluster", "gluster")) { diff --git a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java index 79a2b80e..65d5ebea 100644 --- a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java +++ b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java @@ -75,6 +75,10 @@ public class Cluster extends Entity { this.volumes = volumes; children.add(new EntityGroup("Volumes", Volume.class, this, volumes)); } + + public void addVolume(Volume volume) { + this.volumes.add(volume); + } public Cluster(String name, Entity parent) { super(name, parent); diff --git a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java index 85cdd872..ce2752a4 100644 --- a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java +++ b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/ClusterListener.java @@ -38,4 +38,6 @@ public interface ClusterListener { public void volumeRemoved(Volume volume); public void volumeChanged(Volume volume, Event event); + + public void volumeCreated(Volume volume); } diff --git a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java index bf76de43..eb974fd9 100644 --- a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java +++ b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/DefaultClusterListener.java @@ -55,4 +55,8 @@ public class DefaultClusterListener implements ClusterListener { @Override public void discoveredServerRemoved(Server server) { } + + @Override + public void volumeCreated(Volume volume) { + } } diff --git a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java index 81208eff..7e2cfc31 100644 --- a/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java +++ b/com.gluster.storage.management.core/src/com/gluster/storage/management/core/utils/GlusterUtil.java @@ -24,8 +24,12 @@ import java.util.ArrayList; import java.util.List; import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; +import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; /** * @@ -131,6 +135,7 @@ public class GlusterUtil { return processUtil.executeCommand("gluster", "peer", "probe", serverName); } + public ProcessResult startVolume(String volumeName) { return processUtil.executeCommand("gluster", "volume", "start", volumeName); } @@ -139,6 +144,65 @@ public class GlusterUtil { return processUtil.executeCommand("gluster", "--mode=script", "volume", "stop", volumeName); } + public ProcessResult createVolume(Volume volume) { + int count=1; // replica or stripe count + String volumeType = null; + VOLUME_TYPE volType = volume.getVolumeType(); + if(volType == VOLUME_TYPE.DISTRIBUTED_MIRROR) { + volumeType = "replica"; + count = 2; + } else if(volType == VOLUME_TYPE.DISTRIBUTED_STRIPE) { + volumeType = "stripe"; + count = 4; + } + + String transportTypeStr = null; + TRANSPORT_TYPE transportType = volume.getTransportType(); + transportTypeStr = (transportType == TRANSPORT_TYPE.ETHERNET) ? "tcp" : "rdma"; + + List command = new ArrayList(); + command.add("gluster"); + command.add("volume"); + command.add("create"); + command.add(volume.getName()); + if(volumeType != null) { + command.add(volumeType); + command.add("" + count); + } + command.add("transport"); + command.add(transportTypeStr); + for(Disk disk : volume.getDisks()) { + command.add(getBrickNotation(volume, disk)); + } + return processUtil.executeCommand(command); + } + + public ProcessResult setOption(List command) { + return processUtil.executeCommand(command); + } + + public ProcessResult setVolumeAccessControl(Volume volume) { + List command = new ArrayList(); + command.add("gluster"); + command.add("volume"); + command.add("set"); + command.add(volume.getName()); + command.add("auth.allow"); + command.add(volume.getAccessControlList()); + return setOption(command); + } + + /** + * @param disk + * @return + */ + private String getBrickNotation(Volume vol, Disk disk) { + // TODO: Figure out an appropriate directory INSIDE the DISK having given NAME (e.g. sda, sdb, etc) + // String dirName = "/export/" + vol.getName() + "/" + disk.getName(); + String dirName = "/export/" + vol.getName() ; + return disk.getServerName() + ":" + dirName; + } + public static void main(String args[]) { List names = new GlusterUtil().getGlusterServerNames(); System.out.println(names); diff --git a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java index ce6df74c..80811226 100644 --- a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java +++ b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java @@ -18,6 +18,7 @@ *******************************************************************************/ package com.gluster.storage.management.gui.dialogs; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -25,11 +26,14 @@ import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import com.gluster.storage.management.core.model.Disk; @@ -54,13 +58,19 @@ public class CreateVolumeDisksPage extends Composite { private GUIHelper guiHelper = GUIHelper.getInstance(); private CustomTableDualListComposite dualTableViewer; private Text filterText; + // This list keeps track of the order of the disks as user changes the same by clicking on up/down arrow buttons + private List chosenDisks = new ArrayList(); private IRemovableContentProvider chosenDisksContentProvider; - public CreateVolumeDisksPage(final Composite parent, int style, List disks) { + private Button btnUp; + + private Button btnDown; + + public CreateVolumeDisksPage(final Composite parent, int style, List allDisks, List selectedDisks) { super(parent, style); - createPage(disks); + createPage(allDisks, selectedDisks); parent.layout(); } @@ -85,13 +95,22 @@ public class CreateVolumeDisksPage extends Composite { }; } - private void createPage(List disks) { + private int indexOf(List disks, Disk searchDisk) { + for(Disk disk : disks) { + if(disk.getQualifiedName().equals(searchDisk.getQualifiedName())) { + return disks.indexOf(disk); + } + } + return -1; + } + + private void createPage(List allDisks, List selectedDisks) { setupPageLayout(); filterText = guiHelper.createFilterText(this); new Label(this, SWT.NONE); - createDualTableViewer(disks); + createDualTableViewer(allDisks, selectedDisks); createFilter(filterText, false); // attach filter text to the dual table viewer for auto-filtering Composite buttonContainer = new Composite(this, SWT.NONE); @@ -100,15 +119,64 @@ public class CreateVolumeDisksPage extends Composite { buttonContainerData.minimumWidth = 40; buttonContainer.setLayoutData(buttonContainerData); - Button btnUp = new Button(buttonContainer, SWT.TOGGLE); + btnUp = new Button(buttonContainer, SWT.TOGGLE); GridData btnUpData = new GridData(SWT.LEFT, SWT.BOTTOM, true, false); btnUpData.minimumWidth = 30; btnUp.setLayoutData(btnUpData); btnUp.setImage(guiHelper.getImage(IImageKeys.ARROW_UP)); + btnUp.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + chosenDisks = getChosenDisks(); + List selectedDisks = getSelectedChosenDisks(); + + chosenDisksContentProvider.removeElements(chosenDisks); + for(Disk disk : selectedDisks) { + int index = chosenDisks.indexOf(disk); + Disk diskAbove = chosenDisks.get(index - 1); + chosenDisks.set(index - 1, disk); + chosenDisks.set(index, diskAbove); + } + chosenDisksContentProvider.addElements(chosenDisks); + dualTableViewer.refreshChosenViewer(); + updateButtons(); + } + }); - Button btnDown = new Button(buttonContainer, SWT.TOGGLE); + btnDown = new Button(buttonContainer, SWT.TOGGLE); btnDown.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); btnDown.setImage(guiHelper.getImage(IImageKeys.ARROW_DOWN)); + btnDown.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + chosenDisks = getChosenDisks(); + List selectedDisks = getSelectedChosenDisks(); + + chosenDisksContentProvider.removeElements(chosenDisks); + for(Disk disk : selectedDisks) { + int index = chosenDisks.indexOf(disk); + Disk diskBelow = chosenDisks.get(index + 1); + chosenDisks.set(index + 1, disk); + chosenDisks.set(index, diskBelow); + } + chosenDisksContentProvider.addElements(chosenDisks); + dualTableViewer.refreshChosenViewer(); + updateButtons(); + + } + }); + } + + private List getSelectedChosenDisks() { + TableItem[] selectedItems = dualTableViewer.getChosenTable().getSelection(); + List selectedDisks = new ArrayList(); + for (TableItem item : selectedItems) { + selectedDisks.add((Disk)item.getData()); + } + return selectedDisks; } private void createFilter(final Text filterText, boolean caseSensitive) { @@ -141,7 +209,7 @@ public class CreateVolumeDisksPage extends Composite { dualTableViewer.setChosenViewerFilter(filter); } - private void createDualTableViewer(List disks) { + private void createDualTableViewer(List allDisks, List selectedDisks) { TableColumnData[] columnData = createColumnData(); ITableLabelProvider diskLabelProvider = getDiskLabelProvider(); @@ -151,15 +219,57 @@ public class CreateVolumeDisksPage extends Composite { dualTableViewer.setAvailableTableLinesVisible(false); dualTableViewer.setAvailableTableHeaderVisible(true); - dualTableViewer.setAvailableContentProvider(new RemovableContentProvider()); + dualTableViewer.setAvailableContentProvider(new RemovableContentProvider(getAvailableDisks(allDisks, + selectedDisks))); dualTableViewer.setAvailableLabelProvider(diskLabelProvider); dualTableViewer.setChosenTableLinesVisible(true); dualTableViewer.setChosenTableHeaderVisible(true); - chosenDisksContentProvider = new RemovableContentProvider(disks); + chosenDisksContentProvider = new RemovableContentProvider(selectedDisks); dualTableViewer.setChosenContentProvider(chosenDisksContentProvider); dualTableViewer.setChosenLabelProvider(diskLabelProvider); + + dualTableViewer.getChosenTable().addSelectionListener(new SelectionAdapter() { + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(SelectionEvent e) { + updateButtons(); + } + }); + } + + private void updateButtons() { + btnUp.setEnabled(true); + btnDown.setEnabled(true); + List selectedChosenDisks = getSelectedChosenDisks(); + List chosenDisks = getChosenDisks(); + for(Disk disk : selectedChosenDisks) { + int index = chosenDisks.indexOf(disk); + if(index == 0) { + btnUp.setEnabled(false); + } + if(index == chosenDisks.size() - 1) { + btnDown.setEnabled(false); + } + } + } + + /** + * @param allDisks + * @param selectedDisks + * @return + */ + private List getAvailableDisks(List allDisks, List selectedDisks) { + List availableDisks = new ArrayList(); + for (Disk disk : allDisks) { + if (!selectedDisks.contains(disk)) { + availableDisks.add(disk); + } + } + return availableDisks; } private TableColumnData[] createColumnData() { @@ -182,11 +292,14 @@ public class CreateVolumeDisksPage extends Composite { setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); } - public List getSelectedDisks() { - // dualTableViewer.getChosenTable().getI - Disk[] disks = (Disk[])chosenDisksContentProvider.getElements(dualTableViewer); - if(disks != null) { - return Arrays.asList(disks); + public List getChosenDisks() { + Object[] disksArr = (Object[]) chosenDisksContentProvider.getElements(dualTableViewer); + if (disksArr != null) { + List disks = new ArrayList(); + for (Object disk : disksArr) { + disks.add((Disk) disk); + } + return disks; } return null; } diff --git a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java index e47adcaf..50f5e013 100644 --- a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java +++ b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java @@ -29,6 +29,8 @@ import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -40,6 +42,7 @@ import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; +import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Volume; import com.gluster.storage.management.core.model.Volume.NAS_PROTOCOL; @@ -52,8 +55,11 @@ public class CreateVolumePage1 extends WizardPage { private ComboViewer typeComboViewer; private Text txtAccessControl; private Volume volume = new Volume(); - private List disks; + private List allDisks; private Button btnNfs; + private Button btnStartVolume; + private Link linkCustomize; + private ValidationListener valListener = new ValidationListener(); /** * Create the wizard. @@ -62,13 +68,53 @@ public class CreateVolumePage1 extends WizardPage { super(PAGE_NAME); setTitle("Create Volume"); setDescription("Create a new Volume by choosing disks from the cluster servers and configuring the volume properties."); + + // by default, we create volume with all available disks + allDisks = GlusterDataModelManager.getInstance().getReadyDisksOfAllServers(); + volume.setDisks(allDisks); } + private class ValidationListener implements ModifyListener { + /* (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + @Override + public void modifyText(ModifyEvent e) { + String volumeName = txtName.getText().trim(); + String accessControl = txtAccessControl.getText().trim(); + String volumeNameToken = "^[a-zA-Z][a-zA-Z0-9\\-]*"; + + + setErrorMessage(null); + setPageComplete(true); + + if(volumeName.length() == 0) { + setPageComplete(false); + setErrorMessage("Please enter Volume Name"); + } + + if (!volumeName.matches(volumeNameToken)) { + setPageComplete(false); + setErrorMessage("Please enter valid Volume Name"); + } + + if(accessControl.length() == 0) { + setPageComplete(false); + setErrorMessage("Please enter Access Control"); + } + // TODO: acl validation + // String[] aclList = accessControl.split(","); + + } + } + /** * Create contents of the wizard. * @param parent */ public void createControl(Composite parent) { + + setPageComplete(false); Composite container = new Composite(parent, SWT.NULL); setControl(container); @@ -89,7 +135,8 @@ public class CreateVolumePage1 extends WizardPage { txtName = new Text(container, SWT.BORDER); GridData txtNameData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); txtNameData.widthHint = 300; - txtName.setLayoutData(txtNameData); + txtName.setLayoutData(txtNameData); + txtName.addModifyListener(valListener); Label lblType = new Label(container, SWT.NONE); lblType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); @@ -120,19 +167,21 @@ public class CreateVolumePage1 extends WizardPage { lblDisks.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblDisks.setText("Disks: "); - Link linkCustomize = new Link(container, SWT.UNDERLINE_LINK); - linkCustomize.setText("All Disks (customize)"); + linkCustomize = new Link(container, SWT.UNDERLINE_LINK); + linkCustomize.setText("All Disk(s) (customize)"); linkCustomize.addListener (SWT.Selection, new Listener () { public void handleEvent(Event event) { - SelectDisksDialog dialog = new SelectDisksDialog(getShell()); + SelectDisksDialog dialog = new SelectDisksDialog(getShell(), allDisks, volume.getDisks()); + dialog.create(); if(dialog.open() == Window.OK) { // user has customized disks. get them from the dialog box. volume.setDisks(dialog.getSelectedDisks()); + linkCustomize.setText("" + volume.getDisks().size() + " Disk(s) (customize)"); } } }); - + Label lblNasProtocol = new Label(container, SWT.RIGHT); lblNasProtocol.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblNasProtocol.setText("NAS Protocol: "); @@ -155,15 +204,24 @@ public class CreateVolumePage1 extends WizardPage { txtAccessControl.setText("*"); GridData accessControlData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); accessControlData.widthHint = 300; - txtAccessControl.setLayoutData(accessControlData); + txtAccessControl.setLayoutData(accessControlData); + txtAccessControl.addModifyListener(valListener); new Label(container, SWT.NONE); Label lblAccessControlInfo = new Label(container, SWT.TOP); lblAccessControlInfo.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); lblAccessControlInfo.setText("(Comma separated list of IP addresses)"); + + Label lblStartVolume = new Label(container, SWT.NONE); + lblStartVolume.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblStartVolume.setText("Start Volume: "); + + btnStartVolume = new Button(container, SWT.CHECK); + btnStartVolume.setSelection(true); } public Volume getVolume() { + volume.setName(txtName.getText()); IStructuredSelection selection = (IStructuredSelection)typeComboViewer.getSelection(); @@ -180,4 +238,8 @@ public class CreateVolumePage1 extends WizardPage { return volume; } + + public Boolean getStartVolumeRequest() { + return btnStartVolume.getSelection(); + } } diff --git a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java index 7095caad..dfa5a97c 100644 --- a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java +++ b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java @@ -18,6 +18,9 @@ *******************************************************************************/ package com.gluster.storage.management.gui.dialogs; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.wizard.Wizard; @@ -25,6 +28,7 @@ import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; public class CreateVolumeWizard extends Wizard { @@ -42,17 +46,25 @@ public class CreateVolumeWizard extends Wizard { public boolean performFinish() { CreateVolumePage1 page = (CreateVolumePage1) getPage(CreateVolumePage1.PAGE_NAME); Volume newVol = page.getVolume(); - GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); VolumesClient volumesClient = new VolumesClient(modelManager.getSecurityToken()); Status status = volumesClient.createVolume(newVol); + if (status.isSuccess()) { - new MessageDialog(getShell(), "Create Volume", null, "Volume created successfully!", - MessageDialog.INFORMATION, new String[] { "OK" }, 0); - // TODO: Update the model + newVol.setStatus(VOLUME_STATUS.OFFLINE); + + if (page.getStartVolumeRequest()) { + Status volumeStartStatus = volumesClient.startVolume(newVol.getName()); + if (volumeStartStatus.isSuccess()) { + newVol.setStatus(VOLUME_STATUS.ONLINE); + } + } + + modelManager.addVolume(newVol); + MessageDialog.openInformation(getShell(), "Create Volume", "Volume created successfully and configuration added!"); } else { - new MessageDialog(getShell(), "Create Volume", null, "Volume creation failed! [" + status.getCode() + "][" - + status.getMessage() + "]", MessageDialog.INFORMATION, new String[] { "OK" }, 0); + MessageDialog.openError(getShell(), "Create Volume", "Volume creation failed! [" + status.getCode() + "][" + + status.getMessage() + "]"); } return true; diff --git a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java index b6d0a227..10a36fb0 100644 --- a/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java +++ b/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java @@ -22,6 +22,8 @@ import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.framework.internal.core.Msg; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; @@ -32,19 +34,24 @@ import org.eclipse.swt.widgets.Shell; import com.gluster.storage.management.client.GlusterDataModelManager; import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Volume; public class SelectDisksDialog extends Dialog { private CreateVolumeDisksPage disksPage; + private List allDisks; + private List selectedDisks; /** * Create the dialog. * * @param parentShell */ - public SelectDisksDialog(Shell parentShell) { + public SelectDisksDialog(Shell parentShell, List allDisks, List selectedDisks) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); + this.allDisks = allDisks; + this.selectedDisks = selectedDisks; } /** @@ -61,8 +68,8 @@ public class SelectDisksDialog extends Dialog { container.setLayoutData(containerLayoutData); getShell().setText("Create Volume - Select Disks"); - disksPage = new CreateVolumeDisksPage(container, SWT.NONE, GlusterDataModelManager - .getInstance().getReadyDisksOfAllServers()); + + disksPage = new CreateVolumeDisksPage(container, SWT.NONE, allDisks, selectedDisks); return container; } @@ -93,11 +100,14 @@ public class SelectDisksDialog extends Dialog { @Override protected void okPressed() { - // TODO Validations - super.okPressed(); + if (this.getSelectedDisks().size() == 0 ) { + MessageDialog.openError(getShell(), "Select Disk(s)", "Please select atlease one disk"); + } else { + super.okPressed(); + } } public List getSelectedDisks() { - return disksPage.getSelectedDisks(); + return disksPage.getChosenDisks(); } } diff --git a/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java b/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java index c4c374d6..35571d01 100644 --- a/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java +++ b/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/VolumesResource.java @@ -27,8 +27,6 @@ import static com.gluster.storage.management.core.constants.RESTConstants.PATH_P import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_VOLUMES; import static com.gluster.storage.management.core.constants.RESTConstants.SUBRESOURCE_DEFAULT_OPTIONS; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import javax.ws.rs.Consumes; @@ -41,15 +39,11 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.GenericResponse; import com.gluster.storage.management.core.model.Status; import com.gluster.storage.management.core.model.Volume; -import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; -import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.utils.GlusterUtil; import com.gluster.storage.management.core.utils.ProcessResult; -import com.gluster.storage.management.core.utils.ProcessUtil; import com.gluster.storage.management.server.constants.VolumeOptionsDefaults; import com.sun.jersey.spi.resource.Singleton; @@ -62,55 +56,15 @@ public class VolumesResource { @Consumes(MediaType.TEXT_XML) @Produces(MediaType.TEXT_XML) public GenericResponse createVolume(Volume volume) { - - int count = 1; // replica or stripe count - String volumeType = null; - VOLUME_TYPE volType = volume.getVolumeType(); - if (volType == VOLUME_TYPE.DISTRIBUTED_MIRROR) { - volumeType = "replica"; - count = 2; - } else if (volType == VOLUME_TYPE.DISTRIBUTED_STRIPE) { - volumeType = "stripe"; - count = 4; + ProcessResult response = glusterUtil.createVolume(volume); + if (!response.isSuccess()) { + return new GenericResponse(Status.STATUS_FAILURE, "Volume creation failed: [" + + response.getOutput() + "]"); } - String transportTypeStr = null; - TRANSPORT_TYPE transportType = volume.getTransportType(); - transportTypeStr = (transportType == TRANSPORT_TYPE.ETHERNET) ? "tcp" : "rdma"; - - List command = new ArrayList(); - command.add("gluster"); - command.add("volume"); - command.add("create"); - command.add(volume.getName()); - if (volumeType != null) { - command.add(volumeType); - command.add("" + count); - } - command.add("transport"); - command.add(transportTypeStr); - - for (Disk disk : volume.getDisks()) { - command.add(getBrickNotation(volume, disk)); - } - - ProcessResult result = new ProcessUtil().executeCommand(command); - - if (!result.isSuccess()) { - return new GenericResponse(Status.STATUS_FAILURE, "Volume creation failed: [" + result.getOutput() - + "]"); - } - return new GenericResponse(Status.STATUS_SUCCESS, "Volume created successfully!"); - } + response = glusterUtil.setVolumeAccessControl(volume); - /** - * @param disk - * @return - */ - private String getBrickNotation(Volume vol, Disk disk) { - // TODO: Figure out an appropriate directory INSIDE the DISK having given NAME (e.g. sda, sdb, etc) - String dirName = "/export/" + vol.getName() + "/" + disk.getName(); - return disk.getServerName() + ":" + dirName; + return new GenericResponse(Status.STATUS_SUCCESS, response.getOutput()); } @PUT -- cgit