6

Tôi cố gắng để chạy công cụ này trong một hàm lambda: https://github.com/nicolas-f/7DTD-leafletKhông thể chạy nhị phân từ bên trong python AWS lambda chức năng

Công cụ này phụ thuộc vào loại gối mà phụ thuộc vào thư viện hình ảnh không có sẵn trong các thùng chứa lambda AWS. Để thử và làm tròn cái này, tôi đã chạy pyinstaller để tạo một binary mà tôi hy vọng có thể thực thi. Tệp này có tên là map_reader và nằm ở cấp cao nhất của gói zip lambda.

Dưới đây là đoạn code tôi đang sử dụng để thử và chạy công cụ:

command = 'chmod 755 map_reader' 
args = shlex.split(command) 
print subprocess.Popen(args) 

command = './map_reader -g "{}" -t "{}"'.format('/tmp/mapFiles', '/tmp/tiles') 
args = shlex.split(command) 
print subprocess.Popen(args) 

Và đây là lỗi, mà xảy ra ngày thứ hai subprocess.Popen gọi:

<subprocess.Popen object at 0x7f08fa100d10> 
[Errno 13] Permission denied: OSError 

Làm thế nào tôi có thể chạy điều này một cách chính xác?

+0

Tôi đoán môi trường bạn đang chạy không cho phép bạn đặt các tệp cục bộ để có thể thực thi được. "Quyền bị từ chối" có thể có nghĩa là chính xác những gì nó nói. – Blckknght

Trả lời

3

Bạn có thể đã bị lừa nhầm vào vấn đề thực sự là gì.

Tôi không nghĩ rằng Popen đầu tiên đã chạy thành công. Tôi nghĩ rằng nó chỉ đổ một tin nhắn trong lỗi tiêu chuẩn và bạn không nhìn thấy nó. Đây có thể nói rằng

chmod: map_reader: No such file or directory 

Tôi đề nghị bạn có thể thử một trong những 2:

  1. Giải nén map_reader từ gói vào/tmp. Sau đó, tham khảo nó với /tmp/map_reader.
  2. Do đó theo khuyến cáo của Tim Wagner, Tổng Giám đốc của AWS Lambda người đã nói như sau trong bài viết Running Arbitrary Executables in AWS Lambda:

Bao gồm thực thi của riêng bạn là dễ dàng; chỉ đóng gói chúng trong tệp ZIP bạn tải lên và sau đó tham chiếu chúng (bao gồm đường dẫn tương đối trong tệp ZIP bạn đã tạo) khi bạn gọi chúng từ Node.js hoặc từ các quy trình khác mà bạn đã bắt đầu trước đây. Đảm bảo rằng bạn bao gồm vào lúc bắt đầu của mã chức năng của bạn:

process.env[‘PATH’] = process.env[‘PATH’] + ‘:’ + process.env[‘LAMBDA_TASK_ROOT’] 

Đoạn mã trên là dành cho Node JS nhưng đối với Python, nó giống như sau

import os os.environ['PATH']

Đó nên thực hiện lệnh command = './map_reader <arguments>.

Nếu họ vẫn không làm việc, bạn cũng có thể xem xét việc chạy chmod 755 map_readertrước tạo gói và tải lên (như đề xuất in this other question).

+0

Đánh dấu là chính xác mặc dù đó không phải là giải pháp đầy đủ cho tôi. Tôi sẽ đăng một câu trả lời khác với vấn đề khác. Điều quan trọng ở đây là chuyển nhị phân sang/tmp để tôi có thể hành động theo nó. – stevepkr84

+0

Tôi quên đề cập đến việc đảm bảo bạn đã biên soạn cho Amazon Linux. Tôi cho rằng bạn đã quan tâm đến điều đó. Tôi rất vui vì bạn đã tìm ra. –

+0

không thêm LAMBDA_TASK_ROOT vào đường dẫn của bạn không hoạt động cho bạn? –

2

Có hai vấn đề ở đây. Đầu tiên, theo câu trả lời của Jeshan, tôi phải chuyển nhị phân sang/tmp trước khi tôi có thể truy cập nó đúng cách.

Vấn đề khác là tôi đã chạy pyinstaller trên ubuntu, tạo một tệp. Tôi đã thấy ở một số ý kiến ​​khác về việc chắc chắn biên dịch trên cùng một kiến ​​trúc giống như thùng chứa lambda chạy. Vì vậy, tôi chạy pyinstaller trên ec2 dựa trên Amazon Linux AMI. Đầu ra là nhiều tệp .os, khi được chuyển đến tmp, hoạt động như mong đợi.

1
copyfile('/var/task/yourbinary', '/tmp/yourbinary') 
os.chmod('/tmp/yourbinary', 0555) 

Di chuyển nhị phân để /tmp và làm cho nó thực thi làm việc cho tôi

3

Tôi biết tôi là một chút trễ này, nhưng nếu bạn muốn có một cách chung chung hơn để làm điều này (ví dụ nếu bạn có rất nhiều mã nhị phân và có thể không sử dụng chúng tất cả), cách này tôi làm điều đó, miễn là bạn đặt tất cả các mã nhị phân của bạn trong một thư mục bin bên cạnh tập tin py của bạn, và tất cả các thư viện trong một thư mục lib:

import shutil 
import time 
import os 
import subprocess 

LAMBDA_TASK_ROOT = os.environ.get('LAMBDA_TASK_ROOT', os.path.dirname(os.path.abspath(__file__))) 
CURR_BIN_DIR = os.path.join(LAMBDA_TASK_ROOT, 'bin') 
LIB_DIR = os.path.join(LAMBDA_TASK_ROOT, 'lib') 
### In order to get permissions right, we have to copy them to /tmp 
BIN_DIR = '/tmp/bin' 

# This is necessary as we don't have permissions in /var/tasks/bin where the lambda function is running 
def _init_bin(executable_name): 
    start = time.clock() 
    if not os.path.exists(BIN_DIR): 
     print("Creating bin folder") 
     os.makedirs(BIN_DIR) 
    print("Copying binaries for "+executable_name+" in /tmp/bin") 
    currfile = os.path.join(CURR_BIN_DIR, executable_name) 
    newfile = os.path.join(BIN_DIR, executable_name) 
    shutil.copy2(currfile, newfile) 
    print("Giving new binaries permissions for lambda") 
    os.chmod(newfile, 0775) 
    elapsed = (time.clock() - start) 
    print(executable_name+" ready in "+str(elapsed)+'s.') 

# then if you're going to call a binary in a cmd, for instance pdftotext : 

_init_bin('pdftotext') 
cmdline = [os.path.join(BIN_DIR, 'pdftotext'), '-nopgbrk', '/tmp/test.pdf'] 
subprocess.check_call(cmdline, shell=False, stderr=subprocess.STDOUT) 
Các vấn đề liên quan