Skip to content

Commit 9f32d6a

Browse files
committed
S3Download works and is tested
uses new external python script for downloading
1 parent 6e421a7 commit 9f32d6a

File tree

1 file changed

+35
-98
lines changed

1 file changed

+35
-98
lines changed

shock-server/node/util.go

Lines changed: 35 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ import (
2727

2828
"github.com/MG-RAST/Shock/shock-server/conf"
2929
"github.com/MG-RAST/Shock/shock-server/logger"
30-
31-
"github.com/aws/aws-sdk-go/aws"
32-
"github.com/aws/aws-sdk-go/aws/credentials"
33-
"github.com/aws/aws-sdk-go/aws/session"
34-
"github.com/aws/aws-sdk-go/service/s3"
35-
"github.com/aws/aws-sdk-go/service/s3/s3manager"
3630
)
3731

3832
type mappy map[string]bool
@@ -174,6 +168,7 @@ LocationLoop:
174168
}
175169

176170
if md5sum != nodeMd5 {
171+
logger.Errorf("(FMOpen) md5sum=%s AND nodeMd5= %s", md5sum, nodeMd5)
177172
logger.Errorf("(FMOpen) %s download returned: %s", locationConfig.Type, err.Error())
178173
continue LocationLoop
179174
}
@@ -219,150 +214,92 @@ LocationLoop:
219214
// ************************ ************************ ************************ ************************ ************************ ************************ ************************ ************************
220215
// ************************ ************************ ************************ ************************ ************************ ************************ ************************ ************************
221216

222-
// S3Download download a file and its indices from an S3 source using an external python script
217+
// S3Download download a file and its indices from an S3 source using an external boto3 python script
223218
func S3Download(uuid string, nodeInstance *Node, location *conf.LocationConfig) (err error, md5sum string) {
224219
functionName := "S3Download"
225220

226221
itemkey := fmt.Sprintf("%s.data", uuid)
227222
indexfile := fmt.Sprintf("%s.idx.zip", uuid) // the zipped contents of the idx directory in S3
228223

224+
//fmt.Printf("(%s) downloading node: %s \n", functionName, uuid)
225+
229226
tmpfile, err := ioutil.TempFile(conf.PATH_CACHE, "")
230227
if err != nil {
231-
log.Fatalf("(S3Download) cannot create temporary file: %s [Err: %s]", uuid, err.Error())
228+
log.Fatalf("(%s) cannot create temporary file: %s [Err: %s]", functionName, uuid, err.Error())
232229
return
233230
}
234231
tmpfile.Close()
235-
tmpFileName := tmpfile.Name()
236-
237-
// initialize params for the exec slice
238-
//a := fmt.Sprintf("--accesskey=%s", location.AuthKey)
239-
//s := fmt.Sprintf("--secretkey=%s", location.SecretKey)
240-
b := fmt.Sprintf("--bucket=%s", location.Bucket)
241-
i := fmt.Sprintf("--object=%s", itemkey)
242-
m := fmt.Sprintf("--md5=%s", md5sum)
243-
r := fmt.Sprintf("--region=%s", location.Region)
244-
t := fmt.Sprintf("--tmpfile=%s", tmpfile.Name())
245-
u := fmt.Sprintf("--s3endpoint=%s", location.URL)
246-
247-
// find our executable
248-
externalCmd := "/usr/local/bin/boto-s3-download.py"
249-
path, err := exec.LookPath(externalCmd)
250-
if err != nil {
251-
logger.Debug(1, "(S3Download) didn't find %s executable\n", externalCmd)
252-
return
253-
}
254232

255-
cmd := exec.Command(path, b, i, t, m, u, r)
233+
baseArgString := fmt.Sprintf("boto-s3-download.py --bucket=%s --region=%s --tmpfile=%s --s3endpoint=%s",
234+
location.Bucket, location.Region, tmpfile.Name(), location.URL)
235+
argString := fmt.Sprintf("%s --object=%s",
236+
baseArgString, itemkey)
237+
args := strings.Fields(argString)
238+
cmd := exec.Command(args[0], args[1:]...)
256239

257240
// passing parameters to external program via ENV variables, see https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html
241+
// this is more secure than cmd-line
258242
envAuth := fmt.Sprintf("AWS_ACCESS_KEY_ID = %s", location.AuthKey)
259243
envSecret := fmt.Sprintf("AWS_SECRET_ACCESS_KEY = %s", location.SecretKey)
260-
261244
newEnv := append(os.Environ(), envAuth, envSecret)
262245
cmd.Env = newEnv
263246

264-
err = cmd.Run()
247+
// run and capture the output
248+
out, err := cmd.Output()
265249
if err != nil {
266-
logger.Debug(1, "(%s) cmd.Run(%s) failed with %s\n", functionName, externalCmd, err)
250+
logger.Debug(1, "(%s) cmd.Run(%s) failed with %s\n", functionName, cmd, err)
251+
//fmt.Printf("(%s) cmd.Run(%s) failed with %s\n", functionName, cmd, err.Error())
267252
return
268253
}
269254

270-
//logger.Errorf("creating S3 session failed with Endpoint: %s, Region: %s, Bucket: %s, Authkey: %s, SessionKey: %s (err: %s)",
271-
// location.URL, location.Region, location.Bucket, location.AuthKey, location.SecretKey, err.Error())
272-
273-
//fmt.Printf("node: %s MD5 of requested file: %s\n", itemkey, md5sum)
255+
//md5sum = fmt.Sprintf("%s", string(out))
274256

257+
md5sum = string(out)
258+
md5sum = strings.TrimRight(md5sum, "\r\n")
275259
//fmt.Printf("node: %s DONE \n", itemkey)
276260

277261
// move the bits into place
278-
err = handleDataFile(tmpFileName, uuid, functionName)
262+
err = handleDataFile(tmpfile.Name(), uuid, functionName)
279263
if err != nil {
280-
logger.Debug(3, "(S3Download) error moving directory structure and symkink into place for : %s [Err: %s]", uuid, err.Error())
264+
logger.Debug(3, "(%s) error moving directory structure and symkink into place for : %s [Err: %s]", functionName, uuid, err.Error())
281265
return
282266
}
283267

284268
// ##############################################################################
285269
// ##############################################################################
286270
// ##############################################################################
287271
//index bits now
288-
289272
tmpfile, err = ioutil.TempFile(conf.PATH_CACHE, "")
290273
if err != nil {
291-
log.Fatalf("(S3Download) cannot create temporary file: %s [Err: %s]", uuid, err.Error())
274+
log.Fatalf("(%s) cannot create temporary file: %s [Err: %s]", functionName, uuid, err.Error())
292275
return
293276
}
294-
defer tmpfile.Close()
295-
defer os.Remove(tmpfile.Name())
296-
297-
Bucket := location.Bucket
298-
logger.Debug(1, "(S3Download) attempting download, UUID: %s, nodeID: %s, Bucket:%s", uuid, nodeInstance.Id, Bucket)
299-
300-
//logger.Infof("(S3Download) attempting download, UUID: %s, nodeID: %s, Bucket:%s", uuid, nodeInstance.Id, Bucket)
301-
302-
// 2) Create an AWS session
303-
s3Config := &aws.Config{
304-
Credentials: credentials.NewStaticCredentials(location.AuthKey, location.SecretKey, ""),
305-
Endpoint: aws.String(location.URL),
306-
Region: aws.String(location.Region),
307-
308-
//DisableSSL: aws.Bool(true),
309-
S3ForcePathStyle: aws.Bool(true),
310-
}
311-
//logger.Infof("(S3Download) creating S3 session failed with Endpoint: %s, Region: %s, Bucket: %s, Authkey: %s, SessionKey: %s ",
312-
// location.URL, location.Region, location.Bucket, location.AuthKey, location.SecretKey)
313-
314-
sess, err := session.NewSession(s3Config) //we might have to move this to ensure we only have one client per runtime
315-
316-
if err != nil {
317-
logger.Errorf("(S3Download) creating S3 session failed with Endpoint: %s, Region: %s, Bucket: %s, Authkey: %s, SessionKey: %s (err: %s)",
318-
location.URL, location.Region, location.Bucket, location.AuthKey, location.SecretKey, err.Error())
319-
return
320-
}
321-
322-
//logger.Infof("(S3Download) Session established")
323-
324-
// 3) Create a new AWS S3 downloader
325-
downloader := s3manager.NewDownloader(sess)
277+
tmpfile.Close()
326278

327-
_, err = downloader.Download(tmpfile,
328-
&s3.GetObjectInput{
329-
Bucket: aws.String(Bucket),
330-
Key: aws.String(itemkey),
331-
})
279+
argString = fmt.Sprintf("%s --object=%s", baseArgString, indexfile)
280+
args = strings.Fields(argString)
281+
cmd = exec.Command(args[0], args[1:]...)
332282

333-
//logger.Infof("(S3Download) downloaded %d Bytes for %s into %s", numBytes, itemkey, tmpfile.Name())
283+
// passing parameters to external program via ENV variables, see https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html
284+
// this is more secure than cmd-line
285+
cmd.Env = newEnv
334286

287+
// run and capture the output
288+
out, err = cmd.Output()
335289
if err != nil {
336-
log.Fatalf("(S3Download) Unable to download item %q for %s, %s", itemkey, uuid, err.Error())
337-
// logger.Infof("(S3Download) Unable to download item %q for %s, %s", itemkey, uuid, err.Error())
338-
290+
logger.Debug(1, "(%s) cmd.Run(%s) failed with %s\n", functionName, cmd, err)
291+
fmt.Printf("(%s) cmd.Run(%s) failed with %s\n", functionName, cmd, err.Error())
292+
err = nil
339293
return
340294
}
341295

342-
_, err = downloader.Download(tmpfile,
343-
&s3.GetObjectInput{
344-
Bucket: aws.String(Bucket),
345-
Key: aws.String(indexfile),
346-
})
347-
348-
if err != nil {
349-
// check if S3 tells us there is no file
350-
if strings.HasPrefix(err.Error(), "NoSuchKey") {
351-
// we did not find an index
352-
// logger.Infof("no index for %s", uuid)
353-
err = nil
354-
return
355-
}
356-
log.Fatalf("(S3Download) Unable to download item %q for %s, %s", indexfile, uuid, err.Error())
357-
return
358-
}
359296
//logger.Infof("Downloaded: %s (%d Bytes) \n", file.Name(), numBytes)
360297
err = handleIdxZipFile(tmpfile, uuid, "S3Download")
361298
if err != nil {
362299
logger.Debug(3, "(S3Download) error moving index directory structure and symkink into place for : %s [Err: %s]", uuid, err.Error())
363300
return
364301
}
365-
tmpfile.Close()
302+
366303
return
367304
}
368305

0 commit comments

Comments
 (0)