文档
名称
opm - OpenResty 包管理器
目录
状态
实验性。
概述
对于库用户
# show usage
opm --help
# search package names and abstracts with the user pattern "lock".
opm search lock
# search package names and abstracts with multiple patterns "lru" and "cache".
opm search lru cache
# install a package named lua-resty-foo under the name of some_author
opm get some_author/lua-resty-foo
# get a list of lua-resty-foo packages under all authors.
opm get lua-resty-foo
# show the details of the installed package specified by name.
opm info lua-resty-foo
# show all the installed packages.
opm list
# upgrade package lua-resty-foo to the latest version.
opm upgrade lua-resty-foo
# update all the installed packages to their latest version.
opm update
# uninstall the newly installed package
opm remove lua-resty-foo
所有命令都可以使用 --cwd
选项在当前工作目录(位于 ./resty/modules/)中而不是系统范围的位置工作。
# install into ./resty_modules/ instead of the system-wide location:
opm --cwd get foo/lua-resty-bar
# check the locally installed packages under ./resty_modules/
opm --cwd list
# remove the locally installed packages under ./resty_modules/
opm --cwd remove lua-resty-bar
对于库作者
cd /path/to/lua-resty-foo/
opm build
# optional:
# cd lua-resty-foo-VERSION/ && opm server-build
# you may need to edit the ~/.opmrc file to set up your github
# personal access tokens. the first run of "opm upload" will create
# a boilerplate ~/.opmrc file for you.
opm upload
# cleaning up the leftovers of the opm build command.
opm clean dist
描述
opm
是官方的 OpenResty 包管理器,其理念类似于 Perl 的 CPAN 和 NodeJS 的 npm。
我们在本 GitHub 代码库中提供 opm
客户端命令行实用程序和中央包仓库的服务器端应用程序。
OpenResty 用户可以使用 opm
命令行实用程序下载发布在中央 opm
服务器(即 opm.openresty.org
)上的包。对于包作者和维护者,它还可以用来打包并将 OpenResty 包上传到服务器。你可以在 bin/
目录下找到 opm
的源代码。它目前被实现为一个独立的 Perl 脚本。
服务器端 Web 应用程序是基于 OpenResty 构建的,并使用 Lua 编写。你可以在 web/
目录下找到服务器代码。
与 cpan
、luarocks
、npm
或 pip
等许多其他包管理系统不同。我们的 opm
采用类似于 github
的包命名规范,即每个包名都应该由发布者 ID 限定,例如 agentzh/lua-resty-foo
,其中 agentzh
是发布者 ID,而 lua-resty-foo
是包名本身。此命名要求消除了占用良好包名的诱惑,并且还允许多个同名库在同一个中央服务器仓库中共存。用户可以决定安装哪个库(甚至在她的不同项目中安装同一个库的多个分支)。为简便起见,我们简单地将 GitHub 用户 ID 和组织 ID 映射到 opm
的发布者 ID。因此,我们使用 GitHub 个人访问令牌(或 OAuth 令牌)来验证我们的包发布者。这也完全消除了 opm
包作者的注册流程。
opm
内置支持 restydoc
工具,即通过 opm
安装的包的文档已由 restydoc
索引,可以使用 restydoc
工具直接在终端查看。
opm
目前只支持纯 Lua 库,但我们将很快添加对纯 C 或带有一些 C 组件的 Lua 库的支持。我们的愿景是在未来还通过 opm
添加对将第三方 NGINX C 模块重新分发为动态 NGINX 模块的支持。毕竟,OpenResty 世界由各种不同类型的“模块”组成。
我们还计划允许用户通过特殊用户 ID luarocks
通过 opm
安装 LuaRocks 包。这存在安装与 OpenResty 无关的 Lua 模块的风险,这会导致 NGINX 工作进程在网络 I/O 上严重阻塞,尽管如此,作为 opm
的开发者,我们始终喜欢选择,尤其是那些提供给用户的选择。
用法
opm [options] command package...
Options:
-h
--help Print this help.
--install-dir=PATH Install into the specified PATH directory instead of the system-wide
OpenResty installation tree containing this tool.
--cwd Install into the current working directory under ./resty_modules/
instead of the system-wide OpenResty installation tree containing
this tool.
Commands:
build Build from the current working directory a package tarball ready
for uploading to the server.
clean ARGUMENT... Do clean-up work. Currently the valid argument is "dist", which
cleans up the temporary files and directories created by the "build"
command.
info PACKAGE... Output the detailed information (or meta data) about the specified
packages. Short package names like "lua-resty-lock" are acceptable.
get PACKAGE... Fetch and install the specified packages. Fully qualified package
names like "openresty/lua-resty-lock" are required. One can also
specify a version constraint like "=0.05" and ">=0.01".
list List all the installed packages. Both the package names and versions
are displayed.
remove PACKAGE... Remove (or uninstall) the specified packages. Short package names
like "lua-resty-lock" are acceptable.
search QUERY... Search on the server for packages matching the user queries in their
names or abstracts. Multiple queries can be specified and they must
fulfilled at the same time.
server-build Build a final package tarball ready for distribution on the server.
This command is usually used by the server to verify the uploaded
package tarball.
update Update all the installed packages to their latest version from
the server.
upgrade PACKAGE... Upgrade the packages specified by names to the latest version from
the server. Short package names like "lua-resty-lock" are acceptable.
upload Upload the package tarball to the server. This command always invokes
the build command automatically right before uploading.
全局安装
要全局安装 opm 包,只需使用 sudo opm get foo/bar
命令。
本地安装
当使用 --cwd
选项将包安装到 ./resty_modules/
目录时,应将以下行放在你的 nginx.conf
中,位于 http {}
块内
lua_package_path "$prefix/resty_modules/lualib/?.lua;;";
lua_package_cpath "$prefix/resty_modules/lualib/?.so;;";
不要将 $prefix
自己更改为硬编码的绝对路径!OpenResty 会在启动时自动解析指令值中的特殊 $prefix
变量。$prefix
值将被解析为服务器前缀,该前缀稍后将通过 openresty
命令行的 -p
选项指定。
然后,你应该从当前工作目录启动 OpenResty 应用程序,如下所示
openresty -p $PWD/
假设你在当前目录下具有以下 OpenResty 应用程序目录布局
logs/
conf/
conf/nginx.conf
resty_modules/
或者,如果你只想将 resty
命令行实用程序与安装到 ./resty_modules
目录中的 opm 模块一起使用,那么你应该只使用 -I ./resty_modules/lualib
选项,如
resty -I ./resty_modules/lualib -e 'require "foo.bar".go()'
HTTP 代理支持
HTTP 代理通过 http_proxy
和 https_proxy
系统环境变量支持,如
http_proxy [protocol://]<host>[:port]
Sets the proxy server to use for HTTP.
https_proxy [protocol://]<host>[:port]
Sets the proxy server to use for HTTPS.
作者工作流程
包作者应该在 Lua 库源代码树的顶层放置一个名为 dist.ini
的元数据文件。此文件由 opm build
命令用于将你的库构建并打包成一个 tarball 文件,该文件稍后可以通过 opm upload
命令上传到中央包服务器。
OpenResty 的 lua-resty-core 库的一个示例 dist.ini
文件如下所示
# distribution config for opm packaging
name = lua-resty-core
abstract = New FFI-based Lua API for the ngx_lua module
author = Yichun "agentzh" Zhang (agentzh)
is_original = yes
license = 2bsd
lib_dir = lib
doc_dir = lib
repo_link = https://github.com/openresty/lua-resty-core
main_module = lib/resty/core/base.lua
requires = luajit, openresty/lua-resty-lrucache >= 0.04
如我们所见,dist.ini
文件使用流行的 INI 文件格式。此示例中的大多数字段应该是不言自明的。有关 dist.ini
中可用字段的详细文档,请查看 文件 dist.ini 部分。
opm build
命令还会读取并提取当前系统用户主目录(即文件路径 ~/.opmrc
)下配置文件 .opmrc
中的信息。如果文件不存在,opm build
将自动在该路径中生成一个样板文件。一个示例 ~/.opmrc
文件如下所示。
# your github account name (either your github user name or github organization that you owns)
github_account=agentzh
# you can generate a github personal access token from the web UI: https://github.com/settings/tokens
# IMPORTANT! you are required to assign the scopes "user:email" and "read:org" to your github token.
# you should NOT assign any other scopes to your token due to security considerations.
github_token=0123456789abcdef0123456789abcdef01234567
# the opm central servers for uploading openresty packages.
upload_server=https://opm.openresty.org.cn
download_server=https://opm.openresty.org.cn
基本上,opm build
命令只需要此文件中的 github_account
设置。其他字段由尝试将打包的 tarball 上传到远程包服务器的 opm upload
命令需要。你既可以使用自己的 GitHub 登录名(本例中为 agentzh
),也可以使用你拥有的 GitHub 组织名(即对该组织具有 admin
权限)。
在 opm build
成功在当前工作目录下生成一个 .tar.gz
文件后,作者可以使用 opm upload
命令将该文件上传到远程服务器。为了确保一致性,opm upload
会在尝试上传操作之前自动运行 opm build
本身。中央包服务器(在本例中为 opm.openresty.org
)在幕后调用 GitHub API 来验证作者的身份。因此,作者需要在她的 ~/.opmrc
文件中提供她的 GitHub 个人访问令牌。此访问令牌只需要分配 user:email
和 read:org
权限(或 GitHub 术语中的 scopes
)。
文件 dist.ini
dist.ini
文件指定了包的元数据,并由 opm build
命令用来生成一个压缩包,该压缩包可以上传到远程包服务器。该文件应该位于库或模块源代码树的顶层。
此文件使用 INI 文件格式。它在默认的顶层部分包含以下键(或属性)
name
指定包的名称(不包括版本号)。例如,
name = lua-resty-limit-traffic
名称只能包含字母、数字和连字符 (-
)。
此键是必需的。
abstract
当前包的摘要。
abstract = New FFI-based Lua API for the ngx_lua module
您可以在此字段值中使用 UTF-8 字符。但是,无效的 UTF-8 序列会导致 opm build
或 opm server-build
命令出错。
此键是必需的。
version
当前包的版本号。
如果指定了此键,则此处指定的版本号将自动与从“主模块”文件(有关更多详细信息,请参阅 main_module 键)中提取的版本号进行比较。
示例
version = 1.0.2
另请参阅 版本号处理 部分,了解有关包版本号的更多详细信息。
此键是可选的。
author
指定库的一个或多个作者。例如,
author = Yichun Zhang (agentzh)
多个作者的名称应以逗号分隔,并可选地使用空格环绕。
author = Yichun Zhang (agentzh), Dejiang Zhu
您可以在此字段值中使用 UTF-8 字符。但是,无效的 UTF-8 序列会导致 opm build
或 opm server-build
命令出错。
此键是必需的。
license
指定库的许可证。例如,
license = 3bsd
这将 3 条款 BSD 许可证分配给当前包。
需要使用通用代码许可证的特殊 ID。目前,支持以下 ID
2bsd
BSD 2 条款“简化”或“FreeBSD”许可证
3bsd
BSD 3 条款“新”或“修订”许可证
apache2
Apache 许可证 2.0
artistic
Artistic 许可证
artistic2
Artistic 许可证 2.0
ccby
Creative Commons Attribution 4.0 International Public License
ccbysa
Creative Commons Attribution-ShareAlike 4.0 International Public License
ccbynd
Creative Commons Attribution-NoDerivatives 4.0 International Public License
ccbync
Creative Commons Attribution-NonCommercial 4.0 International Public License
ccbyncsa
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
ccbyncnd
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License
cddl
Common Development and Distribution License
eclipse
Eclipse Public License
gpl
GNU 通用公共许可证 (GPL)
gpl2
GNU 通用公共许可证 (GPL) 版本 2
gpl3
GNU 通用公共许可证 (GPL) 版本 3
lgpl
GNU 库或“较小”通用公共许可证 (LGPL)
mit
MIT 许可证
mozilla2
Mozilla Public License 2.0
proprietary
专有
public
公有领域
如果您需要上面未列出的开源许可证,请告诉我们。
也可以同时指定多个许可证,例如
license = gpl2, artistic2
这指定了双重许可证:GPLv2 和 Artistic 2.0。
要将包上传到官方 opm 包服务器,您必须至少在此处指定一个开源许可证。
此键是必需的。
requires
指定此包的运行时依赖项。
多个依赖项以逗号分隔,并可选地使用空格环绕。例如
requires = foo/lua-resty-bar, baz/lua-resty-blah
运行 opm get
或 opm build
命令时,必须同时满足此键中指定的所有依赖项约束。
您也可以指定版本号要求,例如
requires = foo/lua-resty-bar >= 0.3.5
支持的版本比较运算符为 >=
、=
和 >
。它们的语义不言自明。
您也可以指定以下特殊依赖项名称
luajit
要求包用户 OpenResty 安装(以及包上传者)中的 LuaJIT 组件。当指定版本号约束时,还将检查 LuaJIT 的版本号。
nginx
要求包用户 OpenResty 安装(以及包上传者)中的 NGINX 组件。当指定版本号约束时,还将检查 NGINX 内核的版本号。
openresty
当指定了关联的版本号约束时,此依赖项才有意义。包用户(以及上传者)OpenResty 安装的版本号必须满足此处的版本约束。
ngx_http_lua
要求包用户 OpenResty 安装(以及包上传者)中的 ngx_http_lua_module 组件。当指定版本号约束时,还将检查已安装的 ngx_http_lua_module 的版本。
以下是一个这样的示例
requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.6
或者您可以在上面的示例中只指定一个 openresty
版本约束来覆盖所有内容
requires = openresty >= 1.11.2.1
此键是可选的。
repo_link
代码存储库的 URL(通常在 GitHub 上)。例如,
repo_link = https://github.com/openresty/lua-resty-core
如果存储库在 GitHub 上,则 opm build
确保您在 ~/.opmrc
文件中指定的 github_account
确实 与您的 GitHub 存储库 URL 中的帐户相匹配。否则,opm build
会报告错误。
此键是必需的。
is_original
取值为 yes
或 no
,用于指定此包是否为原创作品(即,不是其他人包的 fork)。
此键是必需的。
lib_dir
指定库文件的根目录(例如,.lua
文件)。
您不能使用绝对目录路径或包含 ..
的路径作为值。
默认为 lib
。
此键是可选的。
exclude_files
指定通过 opm bulid
打包时要排除的文件的模式。支持 Unix Shell 通配符,如 *
和 ?
。
多个模式应以逗号分隔,并可选地使用空格环绕。
exclude_files=foo*.lua, bar/baz/*/*.lua, lint_config.lua
main_module
此键指定当前包的“主模块”文件的路径。例如,opm build
命令会读取“主模块”文件以提取当前包的版本号。
opm build
使用简单的正则表达式来查找如下所示的 Lua 代码模式
_VERSION = '1.0.2'
version = "0.5"
version = 0.08
当未指定此键时,opm build
会尝试自动查找主模块文件(尽管这可能是错误的)。
您不能使用绝对文件路径或包含 ..
的路径作为值。
此键是可选的。
doc_dir
指定文档文件的根目录。默认为 lib
。
您不能使用绝对目录路径或包含 ..
的路径作为值。
opm build
始终尝试收集 Markdown(.md
或 .markdown
)或 POD(.pod
)格式的文档文件。
无论此 doc_dir
键的值如何,opm build
始终尝试收集当前工作目录(应该是当前包的根目录)中的以下文件
README.md
、README.markdown
或README.pod
COPYING
COPYRIGHT
Changes.md
、Changes.markdown
或Changes.pod
您可以在这些文档文件中使用 UTF-8 字符。必须避免其他多字节字符编码。
此键是可选的。
文件 .opmrc
当前系统用户主目录下的 .opmrc
文件配置了当前系统用户的各种重要设置。只有库作者应该关心此文件,因为 opm get
、opm search
或 opm list
等命令根本不需要此文件。
与 file dist-ini 文件类似,此文件也采用 INI 文件格式。当此文件不存在时,第一次运行 opm build
或 opm upload
命令会自动为您生成一个样板文件,供您稍后自行填写。
此文件识别以下键值:
github_account
指定您的 GitHub 账户名称,可以是您的 GitHub 用户登录名,也可以是您拥有的 GitHub 组织名称。
例如,本文档作者的 GitHub 登录名为 agentzh
,同时他还拥有 GitHub 组织 openresty
。因此,他可以选择将自己的包上传到 agentzh
或 openresty
下,使用相同的 GitHub 访问令牌(通过 github_token 键定义)进行配置。
此键值是必需的。
github_token
指定用于上传包的 GitHub 个人访问令牌。
您可以从 GitHub 网页界面 生成 GitHub 个人访问令牌。
在 GitHub 网站上生成令牌时,为令牌分配正确的权限(或 GitHub 术语中的“范围”)至关重要。opm
工具链要求令牌必须包含 user:email
范围。您还可以选择同时分配 read:org
范围,如果您想将 OpenResty 包上传到您拥有的组织名称下,则需要此范围。
GitHub 个人访问令牌类似于密码,因此在处理时要格外小心。切勿与他人共享令牌,否则任何人都可以以您的名义将包上传到 OPM 包服务器。
出于安全考虑,包服务器也会拒绝过于宽松的 GitHub 个人访问令牌(即,拥有比所需范围更多的范围)。包服务器会将其令牌的排序哈希值缓存到自己的数据库中,这样服务器就不必在后续上传时查询 GitHub。由于令牌是哈希化的,因此包服务器只能验证令牌是否正确,但无法从数据库中恢复原始令牌。
此键值是必需的。
upload_server
指定用于上传包的 OPM 服务器。默认值为 https://opm.openresty.org.cn
。强烈建议使用 https
(默认值)来保证通信隐私。
官方的 OPM 包服务器是 https://opm.openresty.org.cn
。但是,您可以将此键值指向您自己的服务器或任何第三方服务器(风险自担)。
此键值可以与 download_server 的值不同。
download_server
指定用于下载包的 OPM 服务器。默认值为 https://opm.openresty.org.cn
。强烈建议使用 https
(默认值)来保证通信隐私。
官方的 OPM 包服务器是 https://opm.openresty.org.cn
。但是,您可以将此键值指向您自己的服务器或任何第三方服务器(风险自担)。
此键值可以与 upload_server 的值不同。
版本号处理
OPM 要求所有包版本号仅包含数字、点、字母和下划线。只有数字部分是必需的。
OPM 将所有版本号视为一个或多个整数,这些整数由点 (.
) 或任何其他非数字字符分隔。版本号比较通过按其出现的顺序比较每个整数部分来执行。例如,以下版本号比较成立
12 > 10
1.0.3 > 1.0.2
1.1.0 > 1.0.9
0.10.0 > 0.9.2
当您的版本号看起来像十进制数时,可能会出现一些意外情况,例如
0.1 < 0.02
这是因为 0.1
被解析为整数对 {0, 1}
,而 0.02
被解析为 {0, 2}
,因此后者大于前者。为了避免此类陷阱,始终指定相同长度的十进制部分,即将 0.1
写作 0.10
,这与 0.02
的长度相同。
OPM 还不支持特殊版本,例如“候选版本”(RC)或“开发版本”。但我们可能会在将来添加此类支持。为了保持向前兼容性,包作者应避免使用 _2
或 rc1
等后缀的版本号。
安装
适用于 opm
自 1.11.2.2
版本起,OpenResty 版本 默认包含并安装了 opm
。因此,通常您不需要自己安装 opm
。
值得注意的是,如果您使用的是官方 OpenResty 预构建的 Linux 包,则应安装 openresty-opm 包,因为 openresty 二进制包本身不包含 opm
。
如果您真的想将代码仓库中的 opm
更新到最新版本,只需将仓库中的 bin/opm
文件复制到 <openresty-prefix>/bin/
目录,其中 <openresty-prefix>
是您构建 OpenResty 时 ./configure
的 --prefix
选项的值(默认为 /usr/local/openresty/
)。
# <openresty-prefix> defaults to `/usr/local/openresty/`
# unless you override it when building OpenResty yourself.
sudo cp bin/opm <openresty-prefix>/bin/
如果您使用的是较旧版本的 OpenResty,该版本默认情况下不包含 opm
,则还应创建以下目录:
cd <openresty-prefix>
sudo mkdir -p site/lualib site/manifest site/pod
请注意,至少需要 OpenResty 1.11.2.1 才能使 opm
正确工作。
要运行 opm
工具,您只需要 perl
、tar
和 curl
。确保您的 perl 版本不低于 5.10.1
,并且您的 curl 支持 SNI
。
安全注意事项
opm
客户端工具始终使用 HTTPS 与包服务器 opm.openresty.org 通信,默认情况下,用于上传和下载包,以及其他用于元数据的 Web 服务查询。虽然用户可以通过手动编辑其自己的 ~/.opmrc
文件中的 download_server
和/或 upload_server
键值,将其切换到 HTTP 协议。opm
客户端工具还会始终验证远程 OPM 包服务器的 SSL 证书(目前通过 curl
)。
类似地,OPM 包服务器始终使用 TLS 与 GitHub 和 Mailgun 提供的远程服务通信。这些远程站点的 SSL 证书也始终在服务器端进行验证。用户无法关闭此功能。
OPM 包服务器使用 PostgreSQL 的 pgcrypto
扩展来加密数据库中作者的 GitHub 个人访问令牌(我们将令牌缓存到自己的数据库中,以加快后续上传速度,并在 GitHub API 出现故障时提高网站可靠性)。即使是服务器管理员也无法从数据库中恢复原始访问令牌。服务器还会确保作者的个人令牌不过于宽松,并拒绝此类令牌。
opm
工具链和服务器还会始终在下载和上传的包文件上执行 MD5 校验和验证,以确保数据在网络传输过程中的完整性。
鸣谢
opm
工具的设计受到了各种现有包管理系统的启发,包括但不限于 Perl 的 cpan
和 Dist::Zilla、RedHat 的 yum
、NodeJS 的 npm
以及 Mac OS X 的 homebrew
。
待办事项
- 添加
opm reinstall
命令来重新安装已安装的模块(相同版本)。 - 添加
opm doctor
命令来检查当前 opm 包安装树是否存在任何不一致之处。 - 添加
opm files <package>
命令来列出指定包中的所有文件。 - 添加
opm whatprovides <package>
命令来找出指定文件所属的包。 - 为
opm build
添加插件机制(类似于 Perl 的 Dist::Zilla 打包框架)。 - 将 opm.openresty.org 打造成一个类似于 search.cpan.org 的完整网站。
- 添加对具有独立 C 库的 Lua C 模块和 LuaJIT FFI 模块的支持。
- 添加对第三方 NGINX C 模块的支持(可以编译为 NGINX 动态模块)。
- 添加对 LuaRocks 的(有限)支持,通过特殊命名空间
luarocks
,例如
opm get luarocks/foo
作者
章亦春 (agentzh) [email protected],OpenResty 公司
版权和许可
该模块使用 BSD 许可证授权。
版权所有 (C) 2016-2020,由章亦春(agentzh)[email protected],OpenResty Inc. 所有。
保留所有权利。
允许以源代码和二进制形式重新分发和使用,无论是否修改,只要满足以下条件:
源代码的再分发必须保留上述版权声明、此条件列表和以下免责声明。
二进制形式的再分发必须在附带的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件由版权所有者和贡献者“按原样”提供,任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保均被排除。在任何情况下,版权所有者或贡献者均不对因使用本软件而造成的任何直接、间接、附带、特殊、示例性或后果性损害(包括但不限于替代商品或服务的采购;使用损失、数据或利润损失;或业务中断)负责,无论损害原因如何,以及无论责任理论如何,无论是在合同、严格责任或侵权行为(包括疏忽或其他原因)的情况下,即使被告知可能发生此类损害。