Skip to content

Commit

Permalink
Merge pull request #106 from EMCECS/develop
Browse files Browse the repository at this point in the history
Pull Develop into Master
  • Loading branch information
APeter0807 committed Mar 10, 2016
2 parents 72305b4 + 8e08a59 commit cb0935d
Show file tree
Hide file tree
Showing 15 changed files with 931 additions and 27 deletions.
4 changes: 2 additions & 2 deletions Documentation/ECS-MultiNode-Instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ An ECS cluster deployment requires a minimum of four (4) data nodes to provide t

- **Operative system:** CentOS 7
- **CPU/Cores:** 4 Cores
- **Memory:** Minimum of 50 GB RAM (64 GB recommended)
- **Memory:** Minimum of 16 GB RAM
- **Disks:** An unpartitioned/Raw disk with at least 100 GB of Storage per disk per host. Multiple disks can be attached on each ECS Node to increase capacity and performance. Each disk need to be un-partitioned before running the installation scripts.


Expand All @@ -43,7 +43,7 @@ We have performed testing against the following platforms:

OS Name | Version | Docker Version |
|-------|---------|----------------|
|CentOS | 7.1 | 1.4.1 |
|CentOS | 7.1 | (os bundled) |


## Installation Steps
Expand Down
4 changes: 3 additions & 1 deletion Documentation/ECS-Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ Executing REST API command:
{"secret_key_1":"UORQB9Xxx8OKmjplSgKHRIPeeWcR2bbiagC5/xT+","key_timestamp_1":"2015-06-21 07:31:48.515","key_expiry_timestamp_1":"","secret_key_2":"","key_timestamp_2":"","key_expiry_timestamp_2":"","link":{"rel":"self","href":"/object/secret-keys"}}`



### Checking Step 2 Object provisioning progress

If you want to see if system is making progress:
Expand All @@ -42,10 +41,13 @@ If you want to see if system is making progress:

To install ECS Community Edition under these conditions, please view the readme file under **/emc-ssl-cert** for further instructions in installing the necessary CA certificate.


### List of Open ports required on each ECS data node

Ensure the following ports are open for communication. Add these ports to the guide saying if a single node is used:

`fwd_settings.sh` in the main directory will invoke the `firewalld` service and permanently open necessary ports. In the case of a failure in this setup referencing `iptables`, please ensure that your docker network bridge is running and installed using `yum install bridge-utils`.


|Port Name-Usage=Port Number|
|---------------------------|
Expand Down
42 changes: 39 additions & 3 deletions ecs-multi-node/step1_ecs_multinode_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,8 @@ def docker_pull_func(docker_image_name):

docker = "docker"
docker_arg = "pull"
docker_file = docker_image_name
logger.info("Executing a Docker Pull for image {}".format(docker_file))
subprocess.call([docker, docker_arg, docker_file])
logger.info("Executing a Docker Pull for image {}".format(docker_image_name))
subprocess.call([docker, docker_arg, docker_image_name])

except Exception as ex:
logger.exception(ex)
Expand Down Expand Up @@ -261,6 +260,18 @@ def prepare_data_disk_func(disks):
logger.info("Mount attached /dev{} to /ecs/{} volume.".format(device_name, uuid_name))
subprocess.call(["mount", device_name, "/ecs/{}".format(uuid_name), "-o", "noatime,seclabel,attr2,inode64,noquota"])

# add entry to fstab if not pre-existing
fstab = "/etc/fstab"
p = subprocess.Popen(["grep", device_name, fstab], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode == 0:
logger.info("Data disk already entered in fs table")
elif p.returncode == 1:
with open("/etc/fstab", 'a') as file:
file.write("{} {} xfs rw,noatime,seclabel,attr2,inode64, noquota 0 0".format(device_name, uuid_name) )
else:
logger.info("Error in checking filesystem table: {}".format(err))

except Exception as ex:
logger.exception(ex)
logger.fatal("Aborting program! Please review log.")
Expand Down Expand Up @@ -288,6 +299,17 @@ def clean_data_disk_func(disks):
logger.info("Remove /ecs/{} Directory in attached Volume".format(uuid_name))
subprocess.call(["rm", "-rf", "/ecs/{}".format(uuid_name)])

logger.info("Remove {} from fs table".format(disk_path))
fstab = "/etc/fstab"
f = open(fstab, "r+")
rl = f.readlines()
f.seek(0)
for ln in rl:
if not disk_path in ln:
f.write(ln)
f.truncate()
f.close()

# sudo rm -rf /data/*
logger.info("Remove /data/* Directory in attached Volume")
subprocess.call(["rm", "-rf", "/data/*"])
Expand Down Expand Up @@ -512,6 +534,19 @@ def modify_container_conf_func():
os.system(
"docker exec -t ecsmultinode cp /host/ssm.object.properties /opt/storageos/conf/ssm.object.properties")

logger.info("Adding python setuptools to container")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode wget https://bootstrap.pypa.io/ez_setup.py")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode python ez_setup.py")

logger.info("Adding python requests library to container")
os.system(
"docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode curl -OL https://github.com/kennethreitz/requests/tarball/master")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode tar zxvf master -C /tmp") os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t -i ecsstandalone bash -c \"cd /tmp/kennethreitz-requests-* && python setup.py install\"")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode wget https://bootstrap.pypa.io/ez_setup.py")
logger.info("Cleaning up python packages")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode rm master")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsmultinode rm setuptools-20.0.zip")

# Flush vNest to clear data and restart.
logger.info("Flush VNeST data")
os.system("docker exec -t ecsmultinode rm -rf /data/vnest/vnest-main/*")
Expand Down Expand Up @@ -598,6 +633,7 @@ def main():
# Check if only wants to run the Container Configuration section
if args.cleanup:
logger.info("Starting CleanUp: Removing Previous Docker containers and images. Deletes the created Directories.")
subprocess.call(["service","docker","start"])
docker_cleanup_old_images()
clean_data_disk_func(args.disks)
sys.exit(4)
Expand Down
45 changes: 42 additions & 3 deletions ecs-single-node/step1_ecs_singlenode_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,8 @@ def docker_pull_func(docker_image_name):

docker = "docker"
docker_arg = "pull"
docker_file = docker_image_name
logger.info("Executing a Docker Pull for image {}".format(docker_file))
command_line = [docker, docker_arg, docker_file]
logger.info("Executing a Docker Pull for image {}".format(docker_image_name))
command_line = [docker, docker_arg, docker_image_name]
command_line[1:1] = DockerCommandLineFlags
subprocess.call(command_line)

Expand Down Expand Up @@ -273,6 +272,18 @@ def prepare_data_disk_func(disks):
logger.info("Mount attached /dev{} to /ecs/{} volume.".format(device_name, uuid_name))
subprocess.call(["mount", device_name, "/ecs/{}".format(uuid_name), "-o", "noatime,seclabel,attr2,inode64,noquota"])

# add entry to fstab if not pre-existing
fstab = "/etc/fstab"
p = subprocess.Popen(["grep", device_name, fstab], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode == 0:
logger.info("Data disk already entered in fs table")
elif p.returncode == 1:
with open("/etc/fstab", 'a') as file:
file.write("{} {} xfs rw,noatime,seclabel,attr2,inode64, noquota 0 0".format(device_name, uuid_name) )
else:
logger.info("Error in checking filesystem table: {}".format(err))

except Exception as ex:
logger.exception(ex)
logger.fatal("Aborting program! Please review log.")
Expand Down Expand Up @@ -322,6 +333,7 @@ def directory_files_conf_func():

# cp seeds /host/files
logger.info("Copying seeds file to /host/files.")

subprocess.call(["cp", "seeds", "/host/files"])

# chown -R 444 /host
Expand Down Expand Up @@ -482,6 +494,20 @@ def modify_container_conf_func():
os.system(
"docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone cp /host/ssm.object.properties /opt/storageos/conf/ssm.object.properties")

logger.info("Adding python setuptools to container")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone wget https://bootstrap.pypa.io/ez_setup.py")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone python ez_setup.py")

logger.info("Adding python requests library to container")
os.system(
"docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone curl -OL https://github.com/kennethreitz/requests/tarball/master")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone tar zxvf master -C /tmp")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t -i ecsstandalone bash -c \"cd /tmp/kennethreitz-requests-* && python setup.py install\"")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone wget https://bootstrap.pypa.io/ez_setup.py")
logger.info("Cleaning up python packages")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone rm master")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone rm setuptools-20.0.zip")

logger.info("Flush VNeST data")
os.system("docker "+' '.join(DockerCommandLineFlags)+" exec -t ecsstandalone rm -rf /data/vnest/vnest-main/*")

Expand Down Expand Up @@ -571,6 +597,18 @@ def cleanup_installation(disks):
logger.info("Destroying partition table for {}".format(disk_path))
subprocess.call(["dd", "if=/dev/zero", "of={}".format(disk_path), "bs=512", "count=1", "conv=notrunc"])

logger.info("Remove {} from fs table".format(disk_path))
fstab = "/etc/fstab"
f = open(fstab, "r+")
rl = f.readlines()
f.seek(0)
for ln in rl:
if not disk_path in ln:
f.write(ln)
f.truncate()
f.close()


# sudo rm -rf /data/*
logger.info("Remove /data Directory")
subprocess.call(["rm", "-rf", "/data"])
Expand Down Expand Up @@ -654,6 +692,7 @@ def main():
# Check if only wants to run the Container Configuration section
if args.cleanup:
logger.info("Starting CleanUp: Removing Previous Docker containers and images. Deletes the created Directories.")
subprocess.call(["service","docker","start"])
docker_cleanup_old_images()
cleanup_installation(args.disks)
sys.exit(7)
Expand Down
43 changes: 25 additions & 18 deletions ecs-single-node/step2_object_provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,16 +242,17 @@ def getUserSecretKey(ECSNode, username):

def main(argv):
try:
opts, argv = getopt.getopt(argv, '', ["ECSNodes=","Namespace=","ObjectVArray=","ObjectVPool=","UserName=","DataStoreName=","VDCName=","MethodName="])
opts, argv = getopt.getopt(argv, '', ["ECSNodes=","Namespace=","ObjectVArray=","ObjectVPool=","UserName=","DataStoreName=","VDCName=","MethodName=","SkipVdcProvision"])
except getopt.GetoptError, e:
print e
print 'ObjectProvisioning.py --ECSNodes=<Coma separated list of datanodes> --Namespace=<namespace> --ObjectVArray=<Object vArray Name> --ObjectVPool=<Object VPool name> --UserName=<user name to be created> --DataStoreName=<Name of the datastore to be created> --VDCName=<Name of the VDC> --MethodName=<Operation to be performed>\n --MethodName is required only when you need to run a particular step in Object Provisioning.If this option is not provided all the Object Provisioning steps will be run.\n Supported options for --MethodName are:\n UploadLicense \n CreateObjectVarray \n GetVarrayID \n CreateDataStore \n InsertVDC \n CreateObjectVpool \n CreateNamespace \n CreateUserAndSecretKey \n'
print 'ObjectProvisioning.py --ECSNodes=<Coma separated list of datanodes> --Namespace=<namespace> --ObjectVArray=<Object vArray Name> --ObjectVPool=<Object VPool name> --UserName=<user name to be created> --DataStoreName=<Name of the datastore to be created> --VDCName=<Name of the VDC> --MethodName=<Operation to be performed> [--SkipVdcProvision]\n --MethodName is required only when you need to run a particular step in Object Provisioning.If this option is not provided all the Object Provisioning steps will be run.\n Supported options for --MethodName are:\n UploadLicense \n CreateObjectVarray \n GetVarrayID \n CreateDataStore \n InsertVDC \n CreateObjectVpool \n CreateNamespace \n CreateUserAndSecretKey \n Use --SkipVdcProvision for non-primary VDCs \n'
sys.exit(2)
ECSNodes=""
MethodName=""
SkipVdcProvision=False
for opt, arg in opts:
if opt == '-h':
print 'ObjectProvisioning.py --ECSNodes=<Coma separated list of datanodes> --Namespace=<namespace> --ObjectVArray=<Object vArray Name> --ObjectVPool=<Object VPool name> --UserName=<user name to be created> --DataStoreName=<Name of the datastore to be created> --VDCName=<Name of the VDC> --MethodName=<Operation to be performed>\n --MethodName is required only when you need to run a particular step in Object Provisioning.If this option is not provided all the Object Provisioning steps will be run.\n Supported options for --MethodName are:\n UploadLicense \n CreateObjectVarray \n GetVarrayID \n CreateDataStore \n InsertVDC \n CreateObjectVpool \n CreateNamespace \n CreateUserAndSecretKey \n'
print 'ObjectProvisioning.py --ECSNodes=<Coma separated list of datanodes> --Namespace=<namespace> --ObjectVArray=<Object vArray Name> --ObjectVPool=<Object VPool name> --UserName=<user name to be created> --DataStoreName=<Name of the datastore to be created> --VDCName=<Name of the VDC> --MethodName=<Operation to be performed> [--SkipVdcProvision]\n --MethodName is required only when you need to run a particular step in Object Provisioning.If this option is not provided all the Object Provisioning steps will be run.\n Supported options for --MethodName are:\n UploadLicense \n CreateObjectVarray \n GetVarrayID \n CreateDataStore \n InsertVDC \n CreateObjectVpool \n CreateNamespace \n CreateUserAndSecretKey \n Use --SkipVdcProvision for non-primary VDCs \n'
sys.exit()
elif opt in ("-ECSNodes", "--ECSNodes"):
ECSNodes = arg
Expand All @@ -271,17 +272,20 @@ def main(argv):
VDCName = arg
elif opt in ("-MethodName", "--MethodName"):
MethodName = arg
elif opt in ("-SkipVdcProvision", "--SkipVdcProvision"):
SkipVdcProvision = True

global AuthToken
AuthToken=getAuthToken(ECSNode, "root", "ChangeMe")

print("ECSNodes: %s" %ECSNode)
print("Namespace: %s" %Namespace)
print("ObjectVArray: %s" %ObjectVArray)
print("ObjectVPool: %s" %ObjectVPool)
print("UserName: %s" %UserName)
print("DataStoreName: %s" %DataStoreName)
print("VDCName: %s" %VDCName)
if not SkipVdcProvision:
print("ObjectVPool: %s" %ObjectVPool)
print("UserName: %s" %UserName)
print("DataStoreName: %s" %DataStoreName)
print("VDCName: %s" %VDCName)
print("MethodName: %s" %MethodName)


Expand Down Expand Up @@ -338,17 +342,20 @@ def main(argv):
CreateDataStoreOnCommodityNodesWithRetry(node, DataStoreName, ObjectVArrayID)

RetryDTStatus(ECSNode)
InsertVDCWithRetry(ECSNode, VDCName)
print("VDCID: %s" %getVDCID(ECSNode, VDCName))
CreateObjectVpoolWithRetry(ECSNode, ObjectVPool, VDCName)
print("Data service vPool ID:%s" %getVpoolID(ECSNode))
ObjectVPoolID = getVpoolID(ECSNode)
CreateNamespaceWithRetry(ECSNode, Namespace, ObjectVPoolID)
print("Namespace: %s" %getNamespaces(ECSNode))
addUserWithRetry(ECSNode, UserName, Namespace)
addUserSecretKey(ECSNode, UserName)
getUserSecretKey(ECSNode, UserName)
sys.exit()

if not SkipVdcProvision:
InsertVDCWithRetry(ECSNode, VDCName)
print("VDCID: %s" %getVDCID(ECSNode, VDCName))
CreateObjectVpoolWithRetry(ECSNode, ObjectVPool, VDCName)
print("Data service vPool ID:%s" %getVpoolID(ECSNode))
ObjectVPoolID = getVpoolID(ECSNode)
CreateNamespaceWithRetry(ECSNode, Namespace, ObjectVPoolID)
print("Namespace: %s" %getNamespaces(ECSNode))
addUserWithRetry(ECSNode, UserName, Namespace)
addUserSecretKey(ECSNode, UserName)
getUserSecretKey(ECSNode, UserName)

sys.exit()


if __name__ == "__main__":
Expand Down
13 changes: 13 additions & 0 deletions ecs-single-node/systemd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
For systems running systemd, you can start and stop the ECS container with the system using this script. To install, run:

```
sudo cp docker.ecsstandalone.service /etc/systemd/system/
sudo systemctl enable docker.ecsstandalone.service
```

Then your docker container will restart with the system. Also be sure that docker itself is set to restart with the system:

```
sudo systemctl enable docker.service
```

13 changes: 13 additions & 0 deletions ecs-single-node/systemd/docker.ecsstandalone.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=ECS Standalone Container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a ecsstandalone
ExecStop=/usr/bin/docker stop -t 60 ecsstandalone

[Install]
WantedBy=standalone-user.target

6 changes: 6 additions & 0 deletions patches/2.2.0.0/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Two fixes to the default 2.2.0.0 image.
FROM emccorp/ecs-software-2.2:2.2.0.0

ADD storageos-blobclient.jar /opt/storageos/lib/
ADD storageserver-partition-config.sh /opt/storageos/bin/

Binary file added patches/2.2.0.0/storageos-blobclient.jar
Binary file not shown.

0 comments on commit cb0935d

Please sign in to comment.