luarocks icon indicating copy to clipboard operation
luarocks copied to clipboard

LuaRocks 3.12.2 fails to install pinned package version (same package version works without pinning)

Open thomasleplus opened this issue 5 months ago • 5 comments

  • Platform: Alpine Linux (Docker image openresty/openresty:alpine-fat).

  • LuaRocks version:

$ luarocks --version
/usr/local/openresty/luajit/bin/luarocks 3.12.2
LuaRocks main command-line interface
  • Description: When installing any package with the --pin option, I get an error saying:
Error: Failed installing dependency: https://luarocks.org/lua_pack-2.0.0-0.src.rock - Could not satisfy dependency lua 5.1-1: Rock lua 5.1-1 is already provided by VM or via 'rocks_provided' in the config file.

If instead I try to install the exact same package version (the latest one) without the --pin option, the install is then successful.

  • Configuration file:
$ cat /usr/local/openresty/luajit/etc/luarocks/config-5.1.lua
-- LuaRocks configuration

rocks_trees = {
   { name = "user", root = home .. "/.luarocks" };
   { name = "system", root = "/usr/local/openresty/luajit" };
}
variables = {
   LUA_DIR = "/usr/local/openresty/luajit";
   LUA_INCDIR = "/usr/local/openresty/luajit/include/luajit-2.1";
   LUA_BINDIR = "/usr/local/openresty/luajit/bin";
   LUA_VERSION = "5.1";
   LUA = "/usr/local/openresty/luajit/bin/luajit";
}
  • LuaRocks output from when the issue occurred:
$  luarocks install lua-resty-session --pin 4.1.3
Installing https://luarocks.org/lua-resty-session-4.1.3-1.src.rock

Missing dependencies for lua-resty-session 4.1.3-1:
   lua-ffi-zlib >= 0.5 (not installed)
   lua-resty-openssl >= 1.5.0 (not installed)

lua-resty-session 4.1.3-1 depends on lua >= 5.1 (5.1-1 provided by VM: success)
lua-resty-session 4.1.3-1 depends on lua-ffi-zlib >= 0.5 (not installed)
Installing https://luarocks.org/lua-ffi-zlib-0.6-0.src.rock

Forcing lua to pinned version 5.1-1
Missing dependencies for lua-ffi-zlib 0.6-0:
Forcing lua to pinned version 5.1-1
   lua 5.1-1 (not installed)

Forcing lua to pinned version 5.1-1
lua-ffi-zlib 0.6-0 depends on lua >= 5.1 (not installed)
Forcing lua to pinned version 5.1-1

Error: Failed installing dependency: https://luarocks.org/lua-ffi-zlib-0.6-0.src.rock - Could not satisfy dependency lua 5.1-1: Rock lua 5.1-1 is already provided by VM or via 'rocks_provided' in the config file.

Verbose log.

  • LuaRocks output from when the issue does NOT occur:
$ luarocks install lua-resty-session
Installing https://luarocks.org/lua-resty-session-4.1.3-1.src.rock

Missing dependencies for lua-resty-session 4.1.3-1:
   lua-ffi-zlib >= 0.5 (not installed)
   lua-resty-openssl >= 1.5.0 (not installed)

lua-resty-session 4.1.3-1 depends on lua >= 5.1 (5.1-1 provided by VM: success)
lua-resty-session 4.1.3-1 depends on lua-ffi-zlib >= 0.5 (not installed)
Installing https://luarocks.org/lua-ffi-zlib-0.6-0.src.rock


lua-ffi-zlib 0.6-0 depends on lua >= 5.1 (5.1-1 provided by VM: success)
No existing manifest. Attempting to rebuild...
lua-ffi-zlib 0.6-0 is now installed in /usr/local/openresty/luajit

lua-resty-session 4.1.3-1 depends on lua-resty-openssl >= 1.5.0 (not installed)
Installing https://luarocks.org/lua-resty-openssl-1.6.1-1.src.rock


lua-resty-openssl 1.6.1-1 is now installed in /usr/local/openresty/luajit (license: BSD)

lua-resty-session 4.1.3-1 is now installed in /usr/local/openresty/luajit (license: BSD)

Verbose log.

thomasleplus avatar Jul 30 '25 10:07 thomasleplus

I don't know if it is a clue but I wonder why the logs say Forcing lua to pinned version 5.1-1 when it's the lua-resty-session version that is supposed to be pinned. However in both logs we end up with lua 5.1-1 in the end so I am not sure whether the version of lua is pinned or not to 5.1-1 can explain why the installation of lua-ffi-zlib 0.6-0 fails (its rockspec says lua >= 5.1).

thomasleplus avatar Jul 30 '25 12:07 thomasleplus

@luau-project any chance that this issue could be looked into? Thanks!

thomasleplus avatar Oct 04 '25 12:10 thomasleplus

Hi Thomas.

[!IMPORTANT]

Even though the --pin option name is suggestive (sounds like pin package version and its dependecies), I never used it myself and I don't know what is the expected behavior at all.

Under the disclaimer above, let's move on to my findings.

Findings

Introduction

  1. Locally on my computer, I built and installed OpenResty from GitHub HEAD
  2. Installed LuaRocks 3.12.2 from tarball configured to use OpenResty
  3. Tried to install lua-resty-session:
    • with --pin option, it fails to install
    • without the --pin option, it installs normally

which seems to be exactly your issue description.

Latest working LuaRocks version

Trying the last few LuaRocks versions, I found that LuaRocks 3.11.1 is able to install lua-resty-session using the --pin option. However, as probably you are aware of #1797, LuaJIT reached a limitation to install packages using LuaRocks versions older than 3.12.0.

What did I do to install lua-resty-session using the --pin option with LuaRocks 3.11.1?

  1. Download, build and install OpenResty from GitHub HEAD on a custom folder
  2. Download, build and install PUC-Lua (to avoid #1797 limitation) on a custom folder
  3. Download LuaRocks 3.11.1
  4. Setup LuaRocks to be driven by PUC-Lua (to avoid #1797 limitation)
  5. Configure LuaRocks to install packages using OpenResty details
  6. Install lua-resty-session using the --pin option

Reproduction

To reproduce my findings above, I wrote a GitHub Actions workflow (login to GitHub and inspect the runs at https://github.com/luau-project/ci-tests/actions/runs/18260329365) to compare LuaRocks 3.11.1 to 3.12.0.

As you can see, it installs nicely on 3.11.1, but not on 3.12.0.

Toggle to reveal/hide the workflow
name: LuaRocks issue 1816

on: push

jobs:
  reproduction:
    runs-on: ubuntu-latest

    strategy:

      fail-fast: false

      matrix:

        lua-version:
          - 5.1.5
          - 5.2.4
          - 5.3.6
          - 5.4.8

        luarocks-version:
          - 3.11.1
          - 3.12.0

    env:
      OPENRESTY_CHECKOUT_DIR: .openresty

    steps:

      - name: Set environment variables to hold install directories
        run: |
          echo "OPENRESTY_DIR=${{ runner.temp }}/openresty" >> ${{ github.env }}
          echo "LUA_DIR=${{ runner.temp }}/lua" >> ${{ github.env }}
          echo "LUAROCKS_DIR=${{ runner.temp }}/luarocks" >> ${{ github.env }}

      - name: Install Lua dependencies
        run: sudo apt install -y libreadline-dev

      - name: Checkout OpenResty
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          repository: openresty/luajit2
          path: ${{ env.OPENRESTY_CHECKOUT_DIR }}

      - name: Build and install OpenResty
        run: make -C "${{ env.OPENRESTY_CHECKOUT_DIR }}" "PREFIX=${{ env.OPENRESTY_DIR }}" all install

      - name: Download, extract, build and install PUC-Lua ${{ matrix.lua-version }}
        run: |
          cd ${{ runner.temp }}
          wget https://lua.org/ftp/lua-${{ matrix.lua-version }}.tar.gz
          tar -xf lua-${{ matrix.lua-version }}.tar.gz
          make -C lua-${{ matrix.lua-version }} "INSTALL_TOP=${{ env.LUA_DIR }}" linux test install

      - name: Download, extract, build and install LuaRocks ${{ matrix.luarocks-version }}
        run: |
          cd ${{ runner.temp }}
          wget https://luarocks.org/releases/luarocks-${{ matrix.luarocks-version }}.tar.gz
          tar -xf luarocks-${{ matrix.luarocks-version }}.tar.gz
          cd luarocks-${{ matrix.luarocks-version }}
          ./configure "--prefix=${{ env.LUAROCKS_DIR }}" "--with-lua=${{ env.LUA_DIR }}" && \
          make && \
          make install && \
          echo "${{ env.LUAROCKS_DIR }}/bin" >> ${{ github.path }}

      - name: Configure LuaRocks to use OpenResty
        run: |
          luarocks config lua_version "5.1"
          luarocks config lua_dir "${{ env.OPENRESTY_DIR }}"

      # the following step is mostly equivalent to the call: eval $(luarocks path)
      # note: it must be called after LuaRocks configuration for OpenResty
      - name: Export Lua / LuaRocks variables
        run: |
          echo "LUA_PATH=$(luarocks path --lr-path)" >> ${{ github.env }}
          echo "LUA_CPATH=$(luarocks path --lr-cpath)" >> ${{ github.env }}
          IFS=':' read -ra paths <<< "$(luarocks path --lr-bin)"
          for (( i=$(( ${#paths[@]} - 1 )); i>=0; i-- )); do
            p="${paths[$i]}"
            echo "Adding \"${p}\" to PATH environment variable"
            echo "${p}" >> ${{ github.path }}
          done

      - name: Install pinned lua-resty-session
        run: luarocks install --pin lua-resty-session 4.1.3
Image

Conclusion

Under the assumption of my disclaimer in the beginning of this post, since I don't know the expected behavior, there are at least three possibilities:

  1. My procedure to setup LuaRocks + PUC-Lua to controll package installation for OpenResty is flawed;
  2. LuaRocks 3.11.1 works as desired and LuaRocks 3.12.0 introduced the issue;
  3. LuaRocks 3.11.1 installs nicely, but not as it should.

In my opinion, the most likely possibility is the second (2.)

luau-project avatar Oct 05 '25 15:10 luau-project

Wow, thank you for the detailed analysis. I would tend to agree with you that scenario 2 seems the most likely.

My 2 cents is that I found the following information regarding the --pin option in LuaRocks' changelog:

  • Dependency pinning
    • Adds a new flag called --pin which creates a luarocks.lock when building a rock with luarocks build or luarocks make. This lock file contains the exact version numbers of every direct or indirect dependency of the rock (in other words, it is the transitive closure of the dependencies.) For make, the luarocks.lock file is created in the current directory. The lock file is also installed as part of the rock in its metadata directory alongside its rockspec. When using --pin, if a lock file already exists, it is ignored and overwritten.
    • When building a rock with luarocks make, if there is a luarocks.lock file in the current directory, the exact versions specified there will be used for resolving dependencies.
    • When building a rock with luarocks build, if there is a luarocks.lock file in root of its sources, the exact versions specified there will be used for resolving dependencies.
    • When installing a .rock file with luarocks install, if the rock contains a luarocks.lock file (i.e., if its dependencies were pinned with --pin when the rock was built), the exact versions specified there will be used for resolving dependencies.

thomasleplus avatar Oct 05 '25 18:10 thomasleplus

Hi,

Any chance that someone will look into this and fix it?

Cheers,

Tom

thomasleplus avatar Nov 18 '25 14:11 thomasleplus