美文网首页
Cargo 私有仓库部署

Cargo 私有仓库部署

作者: 逸之 | 来源:发表于2020-09-15 10:03 被阅读0次

    Step 1:服务端创建Git仓库

    私有仓库的crates目录使用Git进行版本管理:

    $ mkdir mycrates-io
    $ cd mycrates-io
    $ git init
    $ cd ..
    $ git clone --bare mycrates-io mycrates-io.git
    

    Step 2:服务端部署Alexandrie服务

    Alexandrie是Rust语言编写的私有仓库管理服务器,当前版本0.1.0。官方提供了份花里胡哨的安装脚本,事实上也就执行了以下几步。

    Step 2.1:构建Alexandrie

    $ cd alexandrie
    $ cargo build -p alexandrie
    

    编译器:rustc 1.46.0

    编到migrations_macros模块可能会报/usr/bin/ld: cannot find -lsqlite3,解决方法:

    $ sudo apt install sqlite3
    $ sudo apt install libsqlite3-dev
    

    Step 2.2:创建仓库目录

    在alexandrie目录中创建存放crates的文件夹:

    $ mkdir crate-storage
    

    Step 2.3:配置仓库目录

    在alexandrie目录中拉一份mycrates-io.git:

    $ git clone path/to/mycrates-io.git crate-index
    

    在crate-index中添加配置文件config.json:

    {
        "dl": "http://<Alexandrie_IP>:3000/api/v1/crates/{crate}/{version}/download",
        "api": "http://$(hostname):3000",
        "allowed-registries": ["https://github.com/rust-lang/crates.io-index"]
    }
    

    注意:官方脚本中这里的<Alexandrie_IP>字段用的是$(hostname),实践证明可能会导致error: [6] Couldn't resolve host name,查错查了好久。

    提交:

    $ git add config.json;
    $ git commit -m 'Added `config.json`';
    $ git push -u origin master;
    

    Step 2.4:运行Alexandrie

    为了让局域网中的其他机器访问到,需要将alexandrie.toml中配置的回环地址改成固定IP:

    [general]
    bind_address = "<Alexandrie_IP>:3000"
    

    在alexandrie目录中运行(依然会用到一些源文件):

    $ ./target/debug/alexandrie -c alexandrie.toml
    Sep 12 16:48:21.043 INFO running database migrations, version: 0.1.0
    Sep 12 16:48:21.048 INFO setting up request logger middleware, version: 0.1.0
    Sep 12 16:48:21.050 INFO setting up cookie middleware, version: 0.1.0
    Sep 12 16:48:21.052 INFO setting up authentication middleware, version: 0.1.0
    Sep 12 16:48:21.055 INFO mounting '/', version: 0.1.0
    Sep 12 16:48:21.059 INFO mounting '/me', version: 0.1.0
    Sep 12 16:48:21.061 INFO mounting '/search', version: 0.1.0
    Sep 12 16:48:21.064 INFO mounting '/most-downloaded', version: 0.1.0
    Sep 12 16:48:21.065 INFO mounting '/last-updated', version: 0.1.0
    Sep 12 16:48:21.067 INFO mounting '/crates/:crate', version: 0.1.0
    Sep 12 16:48:21.069 INFO mounting '/account/login', version: 0.1.0
    Sep 12 16:48:21.071 INFO mounting '/account/logout', version: 0.1.0
    Sep 12 16:48:21.073 INFO mounting '/account/register', version: 0.1.0
    Sep 12 16:48:21.075 INFO mounting '/account/manage', version: 0.1.0
    Sep 12 16:48:21.081 INFO mounting '/account/manage/password', version: 0.1.0
    Sep 12 16:48:21.083 INFO mounting '/account/manage/tokens', version: 0.1.0
    Sep 12 16:48:21.084 INFO mounting '/account/manage/tokens/:token-id/revoke', version: 0.1.0
    Sep 12 16:48:21.086 INFO mounting '/assets/*path', version: 0.1.0
    Sep 12 16:48:21.088 INFO mounting '/api/v1/account/register', version: 0.1.0
    Sep 12 16:48:21.089 INFO mounting '/api/v1/account/login', version: 0.1.0
    Sep 12 16:48:21.091 INFO mounting '/api/v1/account/tokens', version: 0.1.0
    Sep 12 16:48:21.093 INFO mounting '/api/v1/account/tokens/:name', version: 0.1.0
    Sep 12 16:48:21.094 INFO mounting '/api/v1/categories', version: 0.1.0
    Sep 12 16:48:21.101 INFO mounting '/api/v1/crates', version: 0.1.0
    Sep 12 16:48:21.102 INFO mounting '/api/v1/crates/new', version: 0.1.0
    Sep 12 16:48:21.104 INFO mounting '/api/v1/crates/suggest', version: 0.1.0
    Sep 12 16:48:21.107 INFO mounting '/api/v1/crates/:name', version: 0.1.0
    Sep 12 16:48:21.108 INFO mounting '/api/v1/crates/:name/owners', version: 0.1.0
    Sep 12 16:48:21.110 INFO mounting '/api/v1/crates/:name/:version/yank', version: 0.1.0
    Sep 12 16:48:21.112 INFO mounting '/api/v1/crates/:name/:version/unyank', version: 0.1.0
    Sep 12 16:48:21.114 INFO mounting '/api/v1/crates/:name/:version/download', version: 0.1.0
    Sep 12 16:48:21.119 INFO listening on '127.0.0.1:3000', version: 0.1.0
    Sep 12 16:48:21.122 INFO Server listening on http://127.0.0.1:3000, version: 0.1.0
    

    输出信息显示Alexandrie在3000端口监听请求,但防火墙可能会将其禁用,使用以下步骤依次完成查看端口状态、开启端口、重启防火墙、确认端口状态:

    $ sudo firewall-cmd --query-port=3000/tcp
    no
    $ sudo firewall-cmd --permanent --add-port=3000/tcp
    success
    $ sudo firewall-cmd --reload
    success
    $ sudo firewall-cmd --query-port=3000/tcp
    yes
    

    后面如需关闭端口:

    $ sudo firewall-cmd --permanent --remove-port=3000/tcp
    

    Step 3:客户端发布

    Alexandrie就绪后,可在任意客户端发布crate,但需要注册Alexandrie账户并使用cargo登陆。

    Step 3.1 注册账户

    使用浏览器访问http://<Alexandrie_IP>:3000进行注册。有趣的是,密码似乎只能是十六进制数,因为alexandrie/src/frontend/account/register.rs是这么处理的:

            //? Decode hex-encoded password hash.
            let decoded_password = match hex::decode(form.password.as_bytes()) {
                Ok(passwd) => passwd,
                Err(_) => {
                    let error_msg = String::from("password/salt decoding issue.");
                    req.set_flash_message(FlashMessage::from_json(&error_msg)?);
                    return Ok(utils::response::redirect("/account/register"));
                }
            };
    

    注册之后进入http://<Alexandrie_IP>:3000/account/manage页面,点击「Create token」获得token。

    Step 3.2 登陆

    $ cargo login <TOKEN>
    

    <TOKEN>就是上一步获得的token,cargo会自动将其保存至~/.cargo/credential

    Step 3.3 发布

    cargo publish --no-verify --manifest-path path/to/Cargo.toml --index=ssh://<USER>:<PASSWORD>@<Alexandrie_IP>/path/to/mycrates-io.git
    

    笔者使用rustc源码自带的vendor进行实验,发现cargo在打包前会检查依赖,如果找不到就无法打包。一番研究,cargo似乎没有禁止依赖检查的选项,最后祭出绝招——改源码(1.34.2):把src/tools/cargo/src/cargo/core/resolver/mod.rs resolve()函数中对activate_deps_loop()的调用注释掉。

    由于Cargo仓库被设计成永久保存,发布上去的crate只能yank,不能删除,无法重新发布同版本的crate,这意味着一旦传错,只能在服务端删库重来:

    $ rm alexandrie.db
    $ rm crate-storage/*
    $ cd crate-index
    $ git reset --hard <HEAD>
    $ git push -f origin master
    

    Step 4:客户端使用私有仓库

    默认情况下,cargo访问的crates仓库目录是https://github.com/rust-lang/crates.io-index,我们需要在~/.cargo/config中将其替换为自己的私有仓库:

    [source.crates-io]
    replace-with = 'mycrates-io'
    [source.mycrates-io]
    registry = "ssh://<USER>:<PASSWORD>@<Alexandrie_IP>/path/to/mycrates-io.git"
    

    注意:一个是把服务端密码放进去,二个是IP后面的:改成/

    参考资料


    2020年9月11日、14日、16日 无锡

    相关文章

      网友评论

          本文标题:Cargo 私有仓库部署

          本文链接:https://www.haomeiwen.com/subject/npfwektx.html