如何在 Makefile 中启动未知(但有限)数量的 lambda 函数,每个函数都有一个递增的端口号?
How do I start an unknown (but limited) number of lambda functions, each with an incremental port number, in a Makefile?
实际上,我想要这个 Makefile 配方的反面:
.PHONY: stop-lambdas # Stop the lambdas.
stop-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-stopper
@echo ''
lambda-stopper: $(patsubst %,-stop-%,$(LAMBDAS))
$(patsubst %,-stop-%,$(LAMBDAS)):
@$(MAKE) --no-print-directory validate-lambda lambda="$(patsubst -stop-%,%,$@)"
@echo "Start the lambda function in lambdas/$(patsubst -stop-%,%,$@)."
@docker stop "lambda_$(patsubst -stop-%,%,$@)">/dev/null
@echo ''
到目前为止我有:
.PHONY: start-lambdas # Get the lambdas up and running to allow you to make calls to them.
start-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-starter
@echo ''
lambda-starter: $(patsubst %,-start-%,$(LAMBDAS))
$(patsubst %,-start-%,$(LAMBDAS)):
@$(MAKE) --no-print-directory validate-lambda lambda="$(patsubst -start-%,%,$@)"
@echo "Start the lambda function in lambdas/$(patsubst -start-%,%,$@)."
@docker run --detach --name "lambda_$(patsubst -start-%,%,$@)" --publish XXXXXXX:8080 --rm "${CONTAINER_GROUP}/lambda_$(patsubst -start-%,%,$@):${LAST_CONTAINER_TAG_BRANCH}_${LAST_CONTAINER_TAG_VERSION}" > /dev/null
@echo ''
我无法解决的一点是如何定义 XXXXXXX
。
对此我有 2 个想法。
简单(我希望)为每个 lambda 函数增加一个从 49900 开始的 var(目前大约有 10 个,还可以向该项目添加更多,但不足以耗尽端口号).
定义端口号列表(手动定义 - 每个 lambda 函数 1 个),然后以编程方式确定每个 lambda_$(patsubst -start-%,%,$@)
使用哪个 var
我可以在以下的 Makefile 中硬编码设置:
QUEUE_PORT_NUMBER=49901
QUEUE_ADMIN_PORT_NUMBER=49902
QUEUE_API_PORT_NUMBER=49903
...
在玩:
LAMBDA_PORT_NUMBER_VAR_NAME=$(patsubst -start-%,%,$@)_PORT_NUMBER; echo $${LAMBDA_PORT_NUMBER_VAR_NAME^^};
输出:
QUEUE_PORT_NUMBER
QUEUE_ADMIN_PORT_NUMBER
QUEUE_API_PORT_NUMBER
...
所以我可以通过编程方式定义具有端口号的变量。
我无法解决的是如何使用变量名称获取变量,然后从中获取值到我的食谱中。
一些额外的想法:
- 端口号与 运行 运行 无关。我将显示分配的端口。我希望它们在多个
make start-lambdas
. 之间保持一致
- 这仅供本地开发人员在本地执行 lambda 并允许他们 运行 测试...所有本地。
- 当我们依次对每个 lambda 进行 运行 单元测试时,已经使用了
docker
附加和分离。目前每次都使用端口 49990。我们向 运行ning(但已分离)lambda 发出大量 curl 请求,验证结果,然后终止 lambda,然后继续下一个。所以这一切都有效。
我们只想同时启动和 运行ning 所有 lambda。
不确定我是否了解所有细节。假设您要为每个 -start-lambda
定义一个从 49901 开始的数字,并且您希望每次调用 make
时此数字都相同。我们可以使用 join
GNU make 函数从您的 -start-lambda
列表和计算的数字列表中 assemble 一个 -start-lambda-number
标记列表。我们将令牌列表存储在 make 变量 TOKEN
.
中
在下文中,我们还将使用 make 变量 (STARTER
) 和配方中的 shell 变量 (lambda
) 分解当前 Makefile 的几个语句。对于后者,有两个重要方面需要记住:
make 在将配方传递给 shell 之前对其进行扩展。因此,当使用 shell 变量的值时,我们必须写 $$lambda
(或 $$number
)而不是 $lambda
。在 make 扩展后它将变成 $lambda
,我们要传递给 shell,而不仅仅是 ambda
.
配方的每一行由不同的shell执行。为了在多个配方行中使用 shell 变量,我们必须将它们与 ;
(或 &&
,如您所愿)连接在一起,以便它们成为一行,由一个单独执行shell。但为了更好的可读性,我们可以使用行继续(尾随 \
)。
给定 -start-lambda
目标的编号在配方中提取并存储在第二个 shell 变量 (number
) 和 $(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))
中,即找到具有函数 filter
的相应标记并使用 patsubst
.
提取数字
LAMBDAS := a b c d
STARTER := $(patsubst %,-start-%,$(LAMBDAS))
NUMBER := $(shell seq 49901 `expr 49900 + $(words $(STARTER))`)
TOKEN := $(join $(addsuffix -,$(STARTER)),$(NUMBER))
.PHONY: start-lambdas # Get the lambdas up and running to allow you to make calls to them.
start-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-starter
@echo ''
lambda-starter: $(STARTER)
$(STARTER):
@lambda="$(patsubst -start-%,%,$@)"; \
number="$(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))"; \
$(MAKE) --no-print-directory validate-lambda lambda="$$lambda"; \
echo "Start the lambda function in lambdas/$$lambda."; \
docker run --detach --name "lambda_$$lambda" --publish "$$number:8080" --rm "${CONTAINER_GROUP}/lambda_$$lambda:${LAST_CONTAINER_TAG_BRANCH}_${LAST_CONTAINER_TAG_VERSION}" > /dev/null
@echo ''
请记住,$$
和续行(尾部 ; \
)对于保证 shell 变量 lambda
和 [=29 的正确扩展是必不可少的=],以及它们在食谱所有行中的可用性。
注意:这仅在 $(filter $@-%,$(TOKEN)))
returns 只有一个令牌时有效。如果你有两个名为 foo
和 foo-bar
的 lambda,则相应的标记将是,例如,-start-foo-49901
和 -start-foo-bar-49907
并且对于目标 -start-foo
两者都将匹配 $@-%
。因此,如果您有这样的 lambda 名称,请更改 -start-lambda
部分和数字之间的分隔符。例如,如果您的 lambda 名称中没有 |
个字符,请使用 |
而不是 -
。
带有简化虚拟示例的演示:
$ cat Makefile
LAMBDA := a b c d
STARTER := $(patsubst %,-start-%,$(LAMBDA))
NUMBER := $(shell seq 49901 `expr 49900 + $(words $(STARTER))`)
TOKEN := $(join $(addsuffix -,$(STARTER)),$(NUMBER))
.PHONY: lambdas-starter $(STARTER)
lambda-starter: $(STARTER)
$(STARTER):
@lambda="$(patsubst -start-%,%,$@)"; \
number="$(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))"; \
echo "Start the lambda function in lambdas/$$lambda with $$number."
$ make
Start the lambda function in lambdas/a with 49901.
Start the lambda function in lambdas/b with 49902.
Start the lambda function in lambdas/c with 49903.
Start the lambda function in lambdas/d with 49904.
Renaud Pacalet 回答 - 非常感谢。
我采纳了他的回答并根据我的需要对其进行了进一步调整。
下面是一个改编版本,用于显示已记录的 Makefile 目标列表,以及报告 lambda 列表和将用于测试的端口号。
LAMBDAS := $(notdir $(wildcard ./src/lambdas/*))
PORT_NUMBERS := $(shell seq 49901 `expr 49900 + $(words $(LAMBDAS))`)
LAMBDA_TOKENS := $(join $(addsuffix -,$(LAMBDAS)),$(PORT_NUMBERS))
START_LAMBDAS := $(patsubst %,-start-%,$(LAMBDA_TOKENS))
LIST_LAMBDAS := $(patsubst %,-list-%,$(LAMBDA_TOKENS))
.PHONY: list # Generate list of targets
.PHONY: $(LIST_LAMBDAS)
list:
@grep '^.PHONY: .* #' $(MAKEFILE_LIST) | sort | sed 's/^.*\.PHONY: \(.*\) # \(.*\)/ /' | expand -t16
@echo ''
@echo 'The list of lambda functions known to this Makefile are:'
@echo ''
@$(MAKE) --no-print-directory list-lambdas
@echo ''
list-lambdas:$(LIST_LAMBDAS)
$(LIST_LAMBDAS):
@token=$(filter $(patsubst -list-%,%,$@),$(LAMBDA_TOKENS)); \
parts=($${token//-/ }); \
echo " src/lambdas/$${parts[0]} Will use port number $${parts[1]} for testing."| expand -t26
这输出:
$ make list
build Build the containers
list Generate list of targets
test Test the containers
check-container Check the version of Node in the AWS NodeJS container
clean Remove images, logs, NodeJS cache, node_modules, and built distributions
npm-ci Run `npm ci` for the lambda functions using the AWS NodeJS container
npm-update Run `npm update` for the lambda functions using the AWS NodeJS container
shell Get a bash shell prompt using the AWS NodeJS container, with the current directory mounted in /srv/queue
The list of lambda functions known to this Makefile are:
src/lambdas/api Will use port number 49901 for testing.
src/lambdas/queue Will use port number 49902 for testing.
src/lambdas/queue_admin Will use port number 49903 for testing.
src/lambdas/rendering Will use port number 49904 for testing.
src/lambdas/reporting Will use port number 49905 for testing.
src/lambdas/schedules Will use port number 49906 for testing.
所以我现在有一对 lambda 和端口号,然后用它来构建 Makefile 的目标。懂Makefile的当然可以理解!
实际上,我想要这个 Makefile 配方的反面:
.PHONY: stop-lambdas # Stop the lambdas.
stop-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-stopper
@echo ''
lambda-stopper: $(patsubst %,-stop-%,$(LAMBDAS))
$(patsubst %,-stop-%,$(LAMBDAS)):
@$(MAKE) --no-print-directory validate-lambda lambda="$(patsubst -stop-%,%,$@)"
@echo "Start the lambda function in lambdas/$(patsubst -stop-%,%,$@)."
@docker stop "lambda_$(patsubst -stop-%,%,$@)">/dev/null
@echo ''
到目前为止我有:
.PHONY: start-lambdas # Get the lambdas up and running to allow you to make calls to them.
start-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-starter
@echo ''
lambda-starter: $(patsubst %,-start-%,$(LAMBDAS))
$(patsubst %,-start-%,$(LAMBDAS)):
@$(MAKE) --no-print-directory validate-lambda lambda="$(patsubst -start-%,%,$@)"
@echo "Start the lambda function in lambdas/$(patsubst -start-%,%,$@)."
@docker run --detach --name "lambda_$(patsubst -start-%,%,$@)" --publish XXXXXXX:8080 --rm "${CONTAINER_GROUP}/lambda_$(patsubst -start-%,%,$@):${LAST_CONTAINER_TAG_BRANCH}_${LAST_CONTAINER_TAG_VERSION}" > /dev/null
@echo ''
我无法解决的一点是如何定义 XXXXXXX
。
对此我有 2 个想法。
简单(我希望)为每个 lambda 函数增加一个从 49900 开始的 var(目前大约有 10 个,还可以向该项目添加更多,但不足以耗尽端口号).
定义端口号列表(手动定义 - 每个 lambda 函数 1 个),然后以编程方式确定每个
使用哪个 varlambda_$(patsubst -start-%,%,$@)
我可以在以下的 Makefile 中硬编码设置:
QUEUE_PORT_NUMBER=49901
QUEUE_ADMIN_PORT_NUMBER=49902
QUEUE_API_PORT_NUMBER=49903
...
在玩:
LAMBDA_PORT_NUMBER_VAR_NAME=$(patsubst -start-%,%,$@)_PORT_NUMBER; echo $${LAMBDA_PORT_NUMBER_VAR_NAME^^};
输出:
QUEUE_PORT_NUMBER
QUEUE_ADMIN_PORT_NUMBER
QUEUE_API_PORT_NUMBER
...
所以我可以通过编程方式定义具有端口号的变量。 我无法解决的是如何使用变量名称获取变量,然后从中获取值到我的食谱中。
一些额外的想法:
- 端口号与 运行 运行 无关。我将显示分配的端口。我希望它们在多个
make start-lambdas
. 之间保持一致
- 这仅供本地开发人员在本地执行 lambda 并允许他们 运行 测试...所有本地。
- 当我们依次对每个 lambda 进行 运行 单元测试时,已经使用了
docker
附加和分离。目前每次都使用端口 49990。我们向 运行ning(但已分离)lambda 发出大量 curl 请求,验证结果,然后终止 lambda,然后继续下一个。所以这一切都有效。
我们只想同时启动和 运行ning 所有 lambda。
不确定我是否了解所有细节。假设您要为每个 -start-lambda
定义一个从 49901 开始的数字,并且您希望每次调用 make
时此数字都相同。我们可以使用 join
GNU make 函数从您的 -start-lambda
列表和计算的数字列表中 assemble 一个 -start-lambda-number
标记列表。我们将令牌列表存储在 make 变量 TOKEN
.
在下文中,我们还将使用 make 变量 (STARTER
) 和配方中的 shell 变量 (lambda
) 分解当前 Makefile 的几个语句。对于后者,有两个重要方面需要记住:
make 在将配方传递给 shell 之前对其进行扩展。因此,当使用 shell 变量的值时,我们必须写
$$lambda
(或$$number
)而不是$lambda
。在 make 扩展后它将变成$lambda
,我们要传递给 shell,而不仅仅是ambda
.配方的每一行由不同的shell执行。为了在多个配方行中使用 shell 变量,我们必须将它们与
;
(或&&
,如您所愿)连接在一起,以便它们成为一行,由一个单独执行shell。但为了更好的可读性,我们可以使用行继续(尾随\
)。
给定 -start-lambda
目标的编号在配方中提取并存储在第二个 shell 变量 (number
) 和 $(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))
中,即找到具有函数 filter
的相应标记并使用 patsubst
.
LAMBDAS := a b c d
STARTER := $(patsubst %,-start-%,$(LAMBDAS))
NUMBER := $(shell seq 49901 `expr 49900 + $(words $(STARTER))`)
TOKEN := $(join $(addsuffix -,$(STARTER)),$(NUMBER))
.PHONY: start-lambdas # Get the lambdas up and running to allow you to make calls to them.
start-lambdas:
@$(MAKE) --no-print-directory --makefile LastBuildMakefile report-build
@echo ''
@$(MAKE) --no-print-directory lambda-starter
@echo ''
lambda-starter: $(STARTER)
$(STARTER):
@lambda="$(patsubst -start-%,%,$@)"; \
number="$(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))"; \
$(MAKE) --no-print-directory validate-lambda lambda="$$lambda"; \
echo "Start the lambda function in lambdas/$$lambda."; \
docker run --detach --name "lambda_$$lambda" --publish "$$number:8080" --rm "${CONTAINER_GROUP}/lambda_$$lambda:${LAST_CONTAINER_TAG_BRANCH}_${LAST_CONTAINER_TAG_VERSION}" > /dev/null
@echo ''
请记住,$$
和续行(尾部 ; \
)对于保证 shell 变量 lambda
和 [=29 的正确扩展是必不可少的=],以及它们在食谱所有行中的可用性。
注意:这仅在 $(filter $@-%,$(TOKEN)))
returns 只有一个令牌时有效。如果你有两个名为 foo
和 foo-bar
的 lambda,则相应的标记将是,例如,-start-foo-49901
和 -start-foo-bar-49907
并且对于目标 -start-foo
两者都将匹配 $@-%
。因此,如果您有这样的 lambda 名称,请更改 -start-lambda
部分和数字之间的分隔符。例如,如果您的 lambda 名称中没有 |
个字符,请使用 |
而不是 -
。
带有简化虚拟示例的演示:
$ cat Makefile
LAMBDA := a b c d
STARTER := $(patsubst %,-start-%,$(LAMBDA))
NUMBER := $(shell seq 49901 `expr 49900 + $(words $(STARTER))`)
TOKEN := $(join $(addsuffix -,$(STARTER)),$(NUMBER))
.PHONY: lambdas-starter $(STARTER)
lambda-starter: $(STARTER)
$(STARTER):
@lambda="$(patsubst -start-%,%,$@)"; \
number="$(patsubst $@-%,%,$(filter $@-%,$(TOKEN)))"; \
echo "Start the lambda function in lambdas/$$lambda with $$number."
$ make
Start the lambda function in lambdas/a with 49901.
Start the lambda function in lambdas/b with 49902.
Start the lambda function in lambdas/c with 49903.
Start the lambda function in lambdas/d with 49904.
Renaud Pacalet 回答 - 非常感谢。
我采纳了他的回答并根据我的需要对其进行了进一步调整。
下面是一个改编版本,用于显示已记录的 Makefile 目标列表,以及报告 lambda 列表和将用于测试的端口号。
LAMBDAS := $(notdir $(wildcard ./src/lambdas/*))
PORT_NUMBERS := $(shell seq 49901 `expr 49900 + $(words $(LAMBDAS))`)
LAMBDA_TOKENS := $(join $(addsuffix -,$(LAMBDAS)),$(PORT_NUMBERS))
START_LAMBDAS := $(patsubst %,-start-%,$(LAMBDA_TOKENS))
LIST_LAMBDAS := $(patsubst %,-list-%,$(LAMBDA_TOKENS))
.PHONY: list # Generate list of targets
.PHONY: $(LIST_LAMBDAS)
list:
@grep '^.PHONY: .* #' $(MAKEFILE_LIST) | sort | sed 's/^.*\.PHONY: \(.*\) # \(.*\)/ /' | expand -t16
@echo ''
@echo 'The list of lambda functions known to this Makefile are:'
@echo ''
@$(MAKE) --no-print-directory list-lambdas
@echo ''
list-lambdas:$(LIST_LAMBDAS)
$(LIST_LAMBDAS):
@token=$(filter $(patsubst -list-%,%,$@),$(LAMBDA_TOKENS)); \
parts=($${token//-/ }); \
echo " src/lambdas/$${parts[0]} Will use port number $${parts[1]} for testing."| expand -t26
这输出:
$ make list
build Build the containers
list Generate list of targets
test Test the containers
check-container Check the version of Node in the AWS NodeJS container
clean Remove images, logs, NodeJS cache, node_modules, and built distributions
npm-ci Run `npm ci` for the lambda functions using the AWS NodeJS container
npm-update Run `npm update` for the lambda functions using the AWS NodeJS container
shell Get a bash shell prompt using the AWS NodeJS container, with the current directory mounted in /srv/queue
The list of lambda functions known to this Makefile are:
src/lambdas/api Will use port number 49901 for testing.
src/lambdas/queue Will use port number 49902 for testing.
src/lambdas/queue_admin Will use port number 49903 for testing.
src/lambdas/rendering Will use port number 49904 for testing.
src/lambdas/reporting Will use port number 49905 for testing.
src/lambdas/schedules Will use port number 49906 for testing.
所以我现在有一对 lambda 和端口号,然后用它来构建 Makefile 的目标。懂Makefile的当然可以理解!