我的 Ruby 3.3 AWS Lambda 函数最近在过去几周的某个时候停止工作。如果添加的文件大小超过 10-40KB,该函数似乎无法再写入 tmp 目录。 lambda 函数将临时存储设置为 512MB,因此这似乎不是问题。
为了演示这个问题,我创建了一个新的 Ruby lambda 函数,它可以简单地使用 open-uri 打开文件。 2KB 和 7KB 的文件工作正常,但任何大文件 (160KB) 都会失败并出现错误。
我猜测最近的 AWS 更改现在要求我们专门设置 tmp 目录,但我尝试添加 TMPDIR 环境变量并使用 ENV['TMPDIR']= '/tmp' 直接在代码中设置它,没有这有效。
工作示例:
require "json"
require "open-uri"
def lambda_handler(event:, context:)
URI.open("https://freetestdata.com/wp-content/uploads/2023/11/7.7-KB.txt") # 7KB - works
URI.open("https://freetestdata.com/wp-content/uploads/2023/11/160-KB.txt") # 160KB - error
{ statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end
错误信息:
system temporary path is world-writable: /tmp
/tmp is world-writable: /tmp
. is not writable: /var/task
Error raised from handler method
{
"errorMessage": "could not find a temporary directory",
"errorType": "Function<ArgumentError>",
"stackTrace": [
"/var/lang/lib/ruby/3.3.0/tmpdir.rb:43:in `tmpdir'",
"/var/lang/lib/ruby/3.3.0/tmpdir.rb:119:in `tmpdir'",
"/var/lang/lib/ruby/3.3.0/tmpdir.rb:142:in `create'",
"/var/lang/lib/ruby/3.3.0/tempfile.rb:157:in `initialize'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:414:in `new'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:414:in `<<'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:350:in `block (3 levels) in open_http'",
"/var/lang/lib/ruby/3.3.0/net/protocol.rb:535:in `call_block'",
"/var/lang/lib/ruby/3.3.0/net/protocol.rb:526:in `<<'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:702:in `block (2 levels) in inflate_adapter'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:700:in `inflate'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:700:in `block in inflate_adapter'",
"/var/lang/lib/ruby/3.3.0/net/protocol.rb:535:in `call_block'",
"/var/lang/lib/ruby/3.3.0/net/protocol.rb:526:in `<<'",
"/var/lang/lib/ruby/3.3.0/net/protocol.rb:162:in `read'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:723:in `read'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:631:in `read_chunked'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:595:in `block in read_body_0'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:570:in `inflater'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:593:in `read_body_0'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:363:in `read_body'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:349:in `block (2 levels) in open_http'",
"/var/lang/lib/ruby/3.3.0/net/http.rb:2353:in `block in transport_request'",
"/var/lang/lib/ruby/3.3.0/net/http/response.rb:320:in `reading_body'",
"/var/lang/lib/ruby/3.3.0/net/http.rb:2352:in `transport_request'",
"/var/lang/lib/ruby/3.3.0/net/http.rb:2306:in `request'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:340:in `block in open_http'",
"/var/lang/lib/ruby/3.3.0/net/http.rb:1570:in `start'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:334:in `open_http'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:770:in `buffer_open'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:220:in `block in open_loop'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:218:in `catch'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:218:in `open_loop'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:158:in `open_uri'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:750:in `open'",
"/var/lang/lib/ruby/3.3.0/open-uri.rb:29:in `open'",
"/var/task/lambda_function.rb:5:in `lambda_handler'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric/lambda_handler.rb:28:in `call_handler'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric.rb:88:in `run_user_code'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric.rb:66:in `start_runtime_loop'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric.rb:49:in `run'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric.rb:221:in `bootstrap_handler'",
"/var/runtime/gems/aws_lambda_ric-3.0.0/lib/aws_lambda_ric.rb:203:in `start'",
"/var/runtime/index.rb:4:in `<main>'"
]
目前,此问题仅存在于最新的运行时
Ruby 3.3
,如果您尝试使用Ruby 3.2
运行时,它将可以正常工作。
问题似乎与权限有关。默认情况下,Ruby 尝试写入系统的临时目录。如果无法访问或安全,Ruby 将尝试写入当前工作目录。
因此,如果我们查看错误,它会显示
system temporary path is world-writable: /tmp
,这意味着 Ruby 认为当前文件夹权限不够好,不足以称之为安全。然后它尝试写入当前工作目录,我们知道在 lambda 的情况下它是只读的,它会抛出这个 . is not writable: /var/task
。