我有一个带有Windows .exe依赖的Python脚本,它依赖于(闭源)Windows DLL.Python脚本通过调用Wine在Ubuntu中运行得很好.
是否可以(并且实际)在AWS Lambda上运行它?
准备代码包会涉及什么?
TL; 博士;
是否可以?是的
实用吗?我尝试的方法不是。更好的方法可能是尝试将 wine 放入不同的 lambda 层或自定义执行环境中。
它对你有用吗?这取决于,部署包大小和磁盘空间是限制因素。
我编译了一个自定义 wine,对 lambda 的依赖最小,压缩它,然后把它放到 S3 上。
然后,在运行时的 lambda 中,我下载了存档,将其解压缩到/tmp并使用自定义的空 wine 前缀运行它。
我的测试 Windows 可执行文件是 64 位curl.exe。
从https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html,我第一次尝试amzn-ami-hvm-2018.03.0.20181129-x86_64-gp2,但它有一个较旧的编译环境并且不会配置。
使用ec2amzn2-ami-hvm-2.0.20190313-x86_64-gp2上的AMI t3.2xlarge,我能够进行配置和编译。这些是我使用的命令,参考aws-compile和building-wine:
> sudo yum groupinstall "Development Tools"
> mkdir -p ~/wine-dirs/wine-source
> git clone git://source.winehq.org/git/wine.git ~/wine-dirs/wine-source
> cd ~/wine-dirs/wine-source
> ./configure --enable-win64 --without-x --without-freetype --prefix /opt/wine
> make -j8
> sudo mkdir -p /opt/wine
> sudo chown ec2-user.ec2-user /opt/wine/
> make install
> cd /opt/
> tar zcvf ~/wine-64.tar.gz wine/
Run Code Online (Sandbox Code Playgroud)
这只是一个 64 位版本。它还几乎没有其他可选的葡萄酒依赖项。
我在编译时从 wine 构建中删除了很多可选的依赖项,但它仍然太大。/tmp被限制为500MB。
我删除了包子目录中的文件,包括看起来像可选库的文件,直到我把它压缩到大约 300MB 未压缩。
我确认curl.exe在从构建中删除文件后,wine 仍会运行。
我tar.bz2用默认的 bz2 选项创建了一个wine 和 curl,它最终大约 80MB。压缩和提取的文件总共需要大约 390MB。
这样就有足够的空间来下载存档并将其解压缩到/tmplambda 内部。
> du -h .
290M ./wine/lib64/wine
292M ./wine/lib64
276K ./wine/share/wine
8.0K ./wine/share/applications
288K ./wine/share
5.0M ./wine/curl-7.66.0-win64-mingw/bin
5.0M ./wine/curl-7.66.0-win64-mingw
12M ./wine/bin
308M ./wine
390M .
> ls
wine wine.tar.bz2
Run Code Online (Sandbox Code Playgroud)
wine.tar.bz2到S3创建一个 S3 存储桶并将wine.tar.bz2文件上传到其中。
使用 python 3.7 运行时创建 AWS Lambda。虽然这使用了与上面构建的 wine 不同的底层 AMI,但它仍然有效。
在 lambda 执行角色中,授予对 S3 存储桶的访问权限。
内存:1024MB。我选择这个是因为 lambda CPU功率与内存成比例。
暂停: 1 min
我需要遵循这个问题和答案中的建议来更改 lambda 中的 wine 前缀。我也按照它的建议关闭了显示器。
例如:
handler():
... download from S3 to /tmp, cd to /tmp
subprocess.call(["tar", "-jxvf", "./wine.tar.bz2"])
os.environ['DISPLAY'] = ''
os.environ['WINEARCH'] = 'win64'
os.environ['WINEPREFIX'] = '/tmp/wineprefix'
subprocess.call(["./wine/bin/wine64", "./wine/curl-7.66.0-win64-mingw/bin/curl.exe", "http://www.stackoverflow.com"])
Run Code Online (Sandbox Code Playgroud)
成功!
| 归档时间: |
|
| 查看次数: |
1922 次 |
| 最近记录: |