Commit 90c2d8af authored by Antoine de Torcy's avatar Antoine de Torcy
Browse files

Add Deep Archive test

parent 4bfd4a15
......@@ -48,3 +48,4 @@ END_POSTINSTALL
f 644 root root ${OS_IRODS_HOME_DIR}/plugins/resources/libs3.so ./libs3.so
f 644 root root ${OS_IRODS_HOME_DIR}/tests/pydevtest/test_irods_resource_plugin_s3.py ./packaging/test_irods_resource_plugin_s3.py
f 644 root root ${OS_IRODS_HOME_DIR}/tests/pydevtest/move2DA.r ./packaging/move2DA.r
# example:
# irule -F rules/move2DA.r "'s3resc;s3archive'" "'/tempZone/home/rods/testfile'" "'/my_bucket/home/rods/testfile'"
move_to_deep_archive {
msicompound_archive_object(*resc_hier, *logical_path, *physical_path);
}
INPUT *resc_hier=$1, *logical_path=$2, *physical_path=$3
OUTPUT ruleExecOut
......@@ -8,7 +8,9 @@ import datetime
import boto3
import random
import string
import json
import hashlib
import time
import sys
if sys.version_info >= (2,7):
import unittest
......@@ -19,6 +21,12 @@ import lib
from resource_suite import ResourceSuite
from test_chunkydevtest import ChunkyDevTest
import logging
logging.basicConfig(filename='/tmp/pydevtestlog.txt', level=logging.INFO)
@unittest.skip("AWS Only")
class Test_Compound_With_S3_Resource(ResourceSuite, ChunkyDevTest, unittest.TestCase):
def __init__(self, *args, **kwargs):
self.keypairfile='/projects/irods/vsphere-testing/externals/amazon_web_services-CI.keypair'
......@@ -387,6 +395,7 @@ class Test_Compound_With_S3_Resource(ResourceSuite, ChunkyDevTest, unittest.Test
os.unlink(filepath)
@unittest.skip("AWS Only")
class Test_Compound_With_S3_Resource_EU_Central_1(Test_Compound_With_S3_Resource):
'''
This also tests signature V4 with the x-amz-date header.
......@@ -400,6 +409,7 @@ class Test_Compound_With_S3_Resource_EU_Central_1(Test_Compound_With_S3_Resource
self.s3signature_version=4
super(Test_Compound_With_S3_Resource, self).__init__(*args, **kwargs)
@unittest.skip("AWS Only")
class Test_Compound_With_S3_Resource_STSDate_Header(Test_Compound_With_S3_Resource):
def __init__(self, *args, **kwargs):
self.keypairfile='/projects/irods/vsphere-testing/externals/amazon_web_services-CI.keypair'
......@@ -410,6 +420,7 @@ class Test_Compound_With_S3_Resource_STSDate_Header(Test_Compound_With_S3_Resour
self.s3signature_version=2
super(Test_Compound_With_S3_Resource, self).__init__(*args, **kwargs)
@unittest.skip("AWS Only")
class Test_Compound_With_S3_Resource_STSDate_Header_V4(Test_Compound_With_S3_Resource):
def __init__(self, *args, **kwargs):
self.keypairfile='/projects/irods/vsphere-testing/externals/amazon_web_services-CI.keypair'
......@@ -419,3 +430,365 @@ class Test_Compound_With_S3_Resource_STSDate_Header_V4(Test_Compound_With_S3_Res
self.s3endPoint='s3.amazonaws.com'
self.s3signature_version=4
super(Test_Compound_With_S3_Resource, self).__init__(*args, **kwargs)
class Test_Compound_With_S3_Resource_OSCS(ResourceSuite, ChunkyDevTest, unittest.TestCase):
def __init__(self, *args, **kwargs):
self.keypairfile='/etc/irods/oracle.keypair'
self.s3endPoint='us2.storage.oraclecloud.com'
super(Test_Compound_With_S3_Resource_OSCS, self).__init__(*args, **kwargs)
def setUp(self):
# skip ssl tests on ub12
distro_str = ''.join(platform.linux_distribution()[:2]).replace(' ','')
if self._testMethodName.startswith('test_ssl') and distro_str.lower().startswith('ubuntu12'):
self.skipTest("skipping ssl tests on ubuntu 12")
self.s3bucketname = 'my_bucket'
self.archivebucketname = 'test_archive' # deep archive
# set up resources
hostname = lib.get_hostname()
s3params=( 'S3_DEFAULT_HOSTNAME=' + self.s3endPoint +
';S3_AUTH_FILE=' + self.keypairfile +
';obj_bucket=' + self.s3bucketname +
';arch_bucket=' + self.archivebucketname +
';S3_RETRY_COUNT=15;S3_WAIT_TIME_SEC=1;S3_PROTO=HTTPS;S3_MPU_CHUNK=5120;S3_MPU_THREADS=4;S3_STSDATE=date'
)
s3params=os.environ.get('S3PARAMS', s3params);
with lib.make_session_for_existing_admin() as admin_session:
admin_session.assert_icommand("iadmin modresc demoResc name origResc", 'STDOUT_SINGLELINE', 'rename', stdin_string='yes\n')
admin_session.assert_icommand("iadmin mkresc demoResc compound", 'STDOUT_SINGLELINE', 'compound')
admin_session.assert_icommand("iadmin mkresc cacheResc 'unixfilesystem' "+hostname+":/var/lib/irods/cacheRescVault", 'STDOUT_SINGLELINE', 'cacheResc')
admin_session.assert_icommand('iadmin mkresc archiveResc s3 '+hostname+':/'+self.s3bucketname+'/irods/Vault "'+s3params+'"', 'STDOUT_SINGLELINE', 'archiveResc')
admin_session.assert_icommand("iadmin addchildtoresc demoResc cacheResc cache")
admin_session.assert_icommand("iadmin addchildtoresc demoResc archiveResc archive")
super(Test_Compound_With_S3_Resource_OSCS, self).setUp()
def tearDown(self):
super(Test_Compound_With_S3_Resource_OSCS, self).tearDown()
# tear down resources
with lib.make_session_for_existing_admin() as admin_session:
admin_session.assert_icommand("iadmin rmchildfromresc demoResc archiveResc")
admin_session.assert_icommand("iadmin rmchildfromresc demoResc cacheResc")
admin_session.assert_icommand("iadmin rmresc archiveResc")
admin_session.assert_icommand("iadmin rmresc cacheResc")
admin_session.assert_icommand("iadmin rmresc demoResc")
admin_session.assert_icommand("iadmin modresc origResc name demoResc", 'STDOUT_SINGLELINE', 'rename', stdin_string='yes\n')
shutil.rmtree(lib.get_irods_top_level_dir() + "/cacheRescVault", ignore_errors=True)
@staticmethod
def md5(path):
blocksize = 65536
hasher = hashlib.md5()
with open(path, 'rb') as f:
buf = f.read(blocksize)
while len(buf) > 0:
hasher.update(buf)
buf = f.read(blocksize)
return(hasher.hexdigest())
def test_deep_archive(self):
# make test file
filename = "DA_test_file.txt"
filepath = os.path.join('/tmp', filename)
with open(filepath,'w') as f:
f.write("TESTFILE -- ["+filepath+"]")
checksum = self.md5(filepath)
# upload test file to s3 resource
self.user0.assert_icommand("iput -f "+filepath)
# get object info for DA rule
resc_hier = self.user0.run_icommand('''iquest "%s" "select DATA_RESC_HIER where DATA_NAME ='{0}' and DATA_REPL_NUM ='1'"'''.format(filename))[1].strip()
file_path = self.user0.run_icommand('''iquest "%s" "select DATA_PATH where DATA_NAME ='{0}' and DATA_REPL_NUM ='1'"'''.format(filename))[1].strip()
obj_path = self.user0.run_icommand('''iquest "%s/%s" "select COLL_NAME, DATA_NAME where DATA_NAME ='{0}' and DATA_REPL_NUM ='1'"'''.format(filename))[1].strip()
# call rule to move object to deep archive
self.user0.assert_icommand('''irule -F move2DA.r "'{resc_hier}'" "'{obj_path}'" "'{file_path}'"'''.format(**locals()))
# trim replica on cache
self.user0.assert_icommand("itrim -n 0 -N 1 "+filename)
# remove local file
os.remove(filepath)
# fetch object from DA
while True:
iget_status, iget_out, iget_err = self.user0.run_icommand("iget -V {filename} {filepath}".format(**locals()))
if not iget_err:
break
logging.info('------')
logging.info('status')
logging.info(iget_status)
logging.info('------')
logging.info('out')
# we want only 'Level 0: { ... }', minus the 'Level 0: ' prefix
out_str = iget_out.splitlines()[0].split(': ', 1)[1]
res = json.loads(out_str)
logging.info("completed: {0}%".format(res['completedPercentage']))
logging.info('------')
logging.info('err')
logging.info(iget_err)
logging.info('========')
time.sleep(60)
# verify checksum of newly retrieved file
self.assertEqual(checksum, self.md5(filepath))
# cleanup
self.user0.assert_icommand("irm -f "+filename)
try:
os.remove(filepath)
except OSError:
pass
def test_irm_specific_replica(self):
self.admin.assert_icommand("ils -L "+self.testfile,'STDOUT_SINGLELINE',self.testfile) # should be listed
self.admin.assert_icommand("irepl -R "+self.testresc+" "+self.testfile) # creates replica
self.admin.assert_icommand("ils -L "+self.testfile,'STDOUT_SINGLELINE',self.testfile) # should be listed twice
self.admin.assert_icommand("irm -n 0 "+self.testfile) # remove original from cacheResc only
self.admin.assert_icommand("ils -L "+self.testfile,'STDOUT_SINGLELINE',["2 "+self.testresc,self.testfile]) # replica 2 should still be there
self.admin.assert_icommand_fail("ils -L "+self.testfile,'STDOUT_SINGLELINE',["0 "+self.admin.default_resource,self.testfile]) # replica 0 should be gone
trashpath = self.admin.session_collection_trash
self.admin.assert_icommand_fail("ils -L "+trashpath+"/"+self.testfile,'STDOUT_SINGLELINE',["0 "+self.admin.default_resource,self.testfile]) # replica should not be in trash
@unittest.skip("--wlock has possible race condition due to Compound/Replication PDMO")
def test_local_iput_collision_with_wlock(self):
pass
@unittest.skip("NOTSURE / FIXME ... -K not supported, perhaps")
def test_local_iput_checksum(self):
pass
@unittest.skip("EMPTY_RESC_PATH - no vault path for coordinating resources")
def test_ireg_as_rodsuser_in_vault(self):
pass
@unittest.skip("No Vault for S3 archive resource")
def test_iput_overwrite_others_file__ticket_2086(self):
pass
@unittest.skip("FIXME")
def test_iput_ibun_gzip_bzip2_from_devtest(self):
pass
@unittest.skip("FIXME")
def test_local_iput_interrupt_directory(self):
pass
def test_local_iput_with_force_and_destination_resource__ticket_1706(self):
# local setup
filename = "iputwithforceanddestination.txt"
filepath = lib.create_local_testfile(filename)
doublefile = "doublefile.txt"
os.system("cat %s %s > %s" % (filename, filename, doublefile))
doublesize = str(os.stat(doublefile).st_size)
# assertions
self.admin.assert_icommand("ils -L "+filename,'STDERR_SINGLELINE',"does not exist") # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate to test resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) #
self.admin.assert_icommand("iput -f -R %s %s %s" % (self.testresc, doublefile, filename) ) # overwrite test repl with different data
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," "+filename]) # default resource cache should have dirty copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," "+filename]) # default resource archive should have dirty copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," "+doublesize+" "," "+filename]) # default resource cache should not have doublesize file
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," "+doublesize+" "," "+filename]) # default resource archive should not have doublesize file
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "," "+doublesize+" ","& "+filename]) # targeted resource should have new double clean copy
# local cleanup
os.remove(filepath)
os.remove(doublefile)
###################
# irepl
###################
def test_irepl_update_replicas(self):
# local setup
filename = "updatereplicasfile.txt"
filepath = lib.create_local_testfile(filename)
hostname = lib.get_hostname()
doublefile = "doublefile.txt"
os.system("cat %s %s > %s" % (filename, filename, doublefile))
doublesize = str(os.stat(doublefile).st_size)
# assertions
self.admin.assert_icommand("iadmin mkresc thirdresc unixfilesystem %s:/tmp/thirdrescVault" % hostname, 'STDOUT_SINGLELINE', "Creating") # create third resource
self.admin.assert_icommand("iadmin mkresc fourthresc unixfilesystem %s:/tmp/fourthrescVault" % hostname, 'STDOUT_SINGLELINE', "Creating") # create fourth resource
self.admin.assert_icommand("ils -L "+filename,'STDERR_SINGLELINE',"does not exist") # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate to test resource
self.admin.assert_icommand("irepl -R thirdresc "+filename) # replicate to third resource
self.admin.assert_icommand("irepl -R fourthresc "+filename) # replicate to fourth resource
self.admin.assert_icommand("iput -f -R "+self.testresc+" "+doublefile+" "+filename) # repave overtop test resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 4 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand("irepl -U "+filename) # update last replica
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should have a dirty copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 4 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("irepl -aU "+filename) # update all replicas
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 4 "," & "+filename]) # should have a clean copy
self.admin.assert_icommand("irm -f "+filename) # cleanup file
self.admin.assert_icommand("iadmin rmresc thirdresc") # remove third resource
self.admin.assert_icommand("iadmin rmresc fourthresc") # remove third resource
# local cleanup
os.remove(filepath)
os.remove(doublefile)
def test_irepl_over_existing_second_replica__ticket_1705(self):
# local setup
filename = "secondreplicatest.txt"
filepath = lib.create_local_testfile(filename)
# assertions
self.admin.assert_icommand("ils -L "+filename,'STDERR_SINGLELINE',"does not exist") # should not be listed
self.admin.assert_icommand("iput -R "+self.testresc+" "+filename) # put file
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("irepl "+filename) # replicate to default resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("irepl "+filename) # replicate overtop default resource
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should not have a replica 3
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate overtop test resource
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should not have a replica 3
# local cleanup
os.remove(filepath)
def test_irepl_over_existing_third_replica__ticket_1705(self):
# local setup
filename = "thirdreplicatest.txt"
filepath = lib.create_local_testfile(filename)
hostname = lib.get_hostname()
# assertions
self.admin.assert_icommand("iadmin mkresc thirdresc unixfilesystem %s:/tmp/thirdrescVault" % hostname, 'STDOUT_SINGLELINE', "Creating") # create third resource
self.admin.assert_icommand("ils -L "+filename,'STDERR_SINGLELINE',"does not exist") # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate to test resource
self.admin.assert_icommand("irepl -R thirdresc "+filename) # replicate to third resource
self.admin.assert_icommand("irepl "+filename) # replicate overtop default resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate overtop test resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("irepl -R thirdresc "+filename) # replicate overtop third resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 4 "," & "+filename]) # should not have a replica 4
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 5 "," & "+filename]) # should not have a replica 5
self.admin.assert_icommand("irm -f "+filename) # cleanup file
self.admin.assert_icommand("iadmin rmresc thirdresc") # remove third resource
# local cleanup
os.remove(filepath)
def test_irepl_over_existing_bad_replica__ticket_1705(self):
# local setup
filename = "reploverwritebad.txt"
filepath = lib.create_local_testfile(filename)
doublefile = "doublefile.txt"
os.system("cat %s %s > %s" % (filename, filename, doublefile))
doublesize = str(os.stat(doublefile).st_size)
# assertions
self.admin.assert_icommand("ils -L "+filename,'STDERR_SINGLELINE',"does not exist") # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate to test resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',filename) # for debugging
self.admin.assert_icommand("iput -f %s %s" % (doublefile, filename) ) # overwrite default repl with different data
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," & "+filename]) # default resource cache should have clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 "," "+doublesize+" "," & "+filename]) # default resource cache should have new double clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," & "+filename]) # default resource archive should have clean copy
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 "," "+doublesize+" "," & "+filename]) # default resource archive should have new double clean copy
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "+self.testresc," "+doublesize+" "," "+filename]) # test resource should not have doublesize file
self.admin.assert_icommand("irepl -R "+self.testresc+" "+filename) # replicate back onto test resource
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 "+self.testresc," "+doublesize+" "," & "+filename]) # test resource should have new clean doublesize file
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 3 "," & "+filename]) # should not have a replica 3
# local cleanup
os.remove(filepath)
os.remove(doublefile)
def test_iput_with_purgec(self):
# local setup
filename = "purgecfile.txt"
filepath = os.path.abspath(filename)
f = open(filepath,'wb')
f.write("TESTFILE -- ["+filepath+"]")
f.close()
# assertions
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',filename) # should not be listed
self.admin.assert_icommand("iput --purgec "+filename) # put file
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 ",filename]) # should not be listed (trimmed)
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 ",filename]) # should be listed once - replica 1
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 ",filename]) # should be listed only once
# local cleanup
output = commands.getstatusoutput( 'rm '+filepath )
def test_iget_with_purgec(self):
# local setup
filename = "purgecgetfile.txt"
filepath = os.path.abspath(filename)
f = open(filepath,'wb')
f.write("TESTFILE -- ["+filepath+"]")
f.close()
# assertions
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',filename) # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("iget -f --purgec "+filename) # get file and purge 'cached' replica
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 ",filename]) # should not be listed (trimmed)
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 ",filename]) # should be listed once
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 ",filename]) # should not be listed
# local cleanup
output = commands.getstatusoutput( 'rm '+filepath )
def test_irepl_with_purgec(self):
# local setup
filename = "purgecreplfile.txt"
filepath = os.path.abspath(filename)
f = open(filepath,'wb')
f.write("TESTFILE -- ["+filepath+"]")
f.close()
# assertions
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',filename) # should not be listed
self.admin.assert_icommand("iput "+filename) # put file
self.admin.assert_icommand("irepl -R "+self.testresc+" --purgec "+filename) # replicate to test resource
self.admin.assert_icommand_fail("ils -L "+filename,'STDOUT_SINGLELINE',[" 0 ",filename]) # should not be listed (trimmed)
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 1 ",filename]) # should be listed twice - 2 of 3
self.admin.assert_icommand("ils -L "+filename,'STDOUT_SINGLELINE',[" 2 ",filename]) # should be listed twice - 1 of 3
# local cleanup
output = commands.getstatusoutput( 'rm '+filepath )
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment