pkg --chroot [jail directory] install [some custom package]

OVERVIEW
I want to install custom packages into a stopped jail, something like this:

Code:
sudo pkg --chroot [/jails/containers/foo_jail] install my_custom_package-1.0.0

REPRO

1. Create package `my_custom_package-1.0.0.pkg`

2. Follow instructions to create a custom repository

Code:
sudo mkdir -p /opt/builds
cp my_custom_package-1.0.0.pkg  /opt/builds/.
cd /opt/builds
pkg repo .
mkdir -p /usr/local/etc/pkg/repos/

Edit /usr/local/etc/pkg/repos/local.conf
Code:
local: {
  url: "file:////opt/builds",
  enabled: yes
}


3. Verify custom packages from the local repository install into the host
Code:
sudo pkg install my_custom_package-1.0.0
This succeeds and asks if I want to proceed, I select No and continue my tests.

3. Verify custom packages from the local repository install into the stopped jail with chroot jail
Code:
sudo pkg --chroot /jails/containers/foo_jail/ install my_custom_package-1.0.0

ERROR

This fails with:
Code:
pkg: No packages available to install matching 'my_custom_package-1.0.0' have been found in the repositories

4. Try to install custom packages using --rootdir instead of --chroot
Code:
sudo pkg --rootdir /jails/containers/foo_jail/ install my_custom_package-1.0.0
This seems to work.

QUESTIONS


* So what is the difference bettween --chroot and --rootdir?
* When should you use one vs the other?
* Why does --rootdir recognize custom repos whereas --chroot does not?

From man pkg:
Code:
-c <chroot path>, --chroot <chroot path>
pkg will    chroot in the <chroot path> environment.

-r <root    directory>, --rootdir <root directory>
pkg will     install  all  packages     within     the  specified     <root
           directory>.

Unfortunately, my problem isn't quite solved, even if I use --rootdir instead of --chroot. My custom package depends on another package, in this case, `caddy`. However, when I install my_custom_package-1.0.0 (which depends on caddy (a load balancer)), then my +POST_INSTALL script fails:

# note: caddy has aleady been installed, so it doesn't show up in the list of new packages to be installed
# note: my_custom_package has already been installed, so I'm passing the -f flag here. What's weird is that -f isn't transitive, I would have expected it to also force the deps (caddy) to reinstall, too.
Code:
sudo pkg -r /jails/containers/foo_jail/ install -f my_custom_package-1.0.0

Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating local repository catalogue...
local repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        my_custom_package: 1.0.0 [local]

Number of packages to be installed: 1

Proceed with this action? [y/N]: y
[1/1] Installing my_custom_package-1.0.0...
[1/1] Extracting my_custom_package-1.0.0: 100%
/bin/sh: /usr/local/bin/caddy: not found
chown: /var/log/caddy: No such file or directory
chown: /var/run/caddy: No such file or directory
pkg: POST-INSTALL script failed

But then, when I start the jail, the caddy binary CAN be found, and the caddy directories DO exist.

QUESTIONS

* So am I incorrect in thinking that I can package up other 3rd party packages as meta packages and place all my configuration logic in my meta package?
* If I have a package A that depends on package B, when do the +POST-INSTALL scripts for A and B run?

LINKS

* https://forums.freebsd.org/threads/pkg-fetch.65685/
* https://forums.freebsd.org/threads/...freebsd-set-optional-jail.101154/#post-745236
* https://forums.freebsd.org/threads/pkg-chroot-problem.101382/
* https://brokenco.de/2021/02/02/freebsd-pkg-with-an-offline-jail.html
* https://forums.freebsd.org/threads/pkg-chroot-problem.101382/#post-740011
* https://man.freebsd.org/cgi/man.cgi?query=chroot&sektion=8&manpath=freebsd-release-ports
* https://man.freebsd.org/cgi/man.cgi?query=pkg-add&sektion=8&manpath=freebsd-release-ports
* https://man.freebsd.org/cgi/man.cgi?query=pkg-fetch&sektion=8&manpath=freebsd-release-ports
* https://gist.github.com/matthewp/431e0c89d9492ea5601ce9c01a5676af
 
I'm confused... why bother with a local repository in the first place? You can easily tell pkg to install a specific package by specifying the pkg file directly, no need for overhead.

Obviously if you use chroot you're restricting the scope of your access, so... I'd start by creating the package (pkg-create(8)), then copying that to a local directory within the jail structure (maybe /tmp?) and then... # chroot <jail> pkg install /tmp/package.pkg.

That should be enough to work around all this.
 
OVERVIEW
I want to install custom packages into a stopped jail, something like this:

Code:
sudo pkg --chroot [/jails/containers/foo_jail] install my_custom_package-1.0.0

REPRO

1. Create package `my_custom_package-1.0.0.pkg`

2. Follow instructions to create a custom repository

Code:
sudo mkdir -p /opt/builds
cp my_custom_package-1.0.0.pkg  /opt/builds/.
cd /opt/builds
pkg repo .
mkdir -p /usr/local/etc/pkg/repos/

Edit /usr/local/etc/pkg/repos/local.conf
Code:
local: {
  url: "file:////opt/builds",
  enabled: yes
}


3. Verify custom packages from the local repository install into the host
Code:
sudo pkg install my_custom_package-1.0.0
This succeeds and asks if I want to proceed, I select No and continue my tests.

3. Verify custom packages from the local repository install into the stopped jail with chroot jail
Code:
sudo pkg --chroot /jails/containers/foo_jail/ install my_custom_package-1.0.0

ERROR

This fails with:
Code:
pkg: No packages available to install matching 'my_custom_package-1.0.0' have been found in the repositories

4. Try to install custom packages using --rootdir instead of --chroot
Code:
sudo pkg --rootdir /jails/containers/foo_jail/ install my_custom_package-1.0.0
This seems to work.

QUESTIONS

* So what is the difference bettween --chroot and --rootdir?
* When should you use one vs the other?
* Why does --rootdir recognize custom repos whereas --chroot does not?

From man pkg:
Code:
-c <chroot path>, --chroot <chroot path>
pkg will    chroot in the <chroot path> environment.

-r <root    directory>, --rootdir <root directory>
pkg will     install  all  packages     within     the  specified     <root
           directory>.

Unfortunately, my problem isn't quite solved, even if I use --rootdir instead of --chroot. My custom package depends on another package, in this case, `caddy`. However, when I install my_custom_package-1.0.0 (which depends on caddy (a load balancer)), then my +POST_INSTALL script fails:

# note: caddy has aleady been installed, so it doesn't show up in the list of new packages to be installed
# note: my_custom_package has already been installed, so I'm passing the -f flag here. What's weird is that -f isn't transitive, I would have expected it to also force the deps (caddy) to reinstall, too.
Code:
sudo pkg -r /jails/containers/foo_jail/ install -f my_custom_package-1.0.0

Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
Updating local repository catalogue...
local repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        my_custom_package: 1.0.0 [local]

Number of packages to be installed: 1

Proceed with this action? [y/N]: y
[1/1] Installing my_custom_package-1.0.0...
[1/1] Extracting my_custom_package-1.0.0: 100%
/bin/sh: /usr/local/bin/caddy: not found
chown: /var/log/caddy: No such file or directory
chown: /var/run/caddy: No such file or directory
pkg: POST-INSTALL script failed

But then, when I start the jail, the caddy binary CAN be found, and the caddy directories DO exist.

QUESTIONS

* So am I incorrect in thinking that I can package up other 3rd party packages as meta packages and place all my configuration logic in my meta package?
* If I have a package A that depends on package B, when do the +POST-INSTALL scripts for A and B run?

LINKS

* https://forums.freebsd.org/threads/pkg-fetch.65685/
* https://forums.freebsd.org/threads/...freebsd-set-optional-jail.101154/#post-745236
* https://forums.freebsd.org/threads/pkg-chroot-problem.101382/
* https://brokenco.de/2021/02/02/freebsd-pkg-with-an-offline-jail.html
* https://forums.freebsd.org/threads/pkg-chroot-problem.101382/#post-740011
* https://man.freebsd.org/cgi/man.cgi?query=chroot&sektion=8&manpath=freebsd-release-ports
* https://man.freebsd.org/cgi/man.cgi?query=pkg-add&sektion=8&manpath=freebsd-release-ports
* https://man.freebsd.org/cgi/man.cgi?query=pkg-fetch&sektion=8&manpath=freebsd-release-ports
* https://gist.github.com/matthewp/431e0c89d9492ea5601ce9c01a5676af
Don't quite follow what the endgame here is… but, in any case, I'm certain reading the chroot(8) & chroot(2) man pages would help you a great deal in understanding what pkg --chroot is doing, and why when you use it the pkg utility is unable to see anything outside of the target directory, and from that how and why that invocation differs from one using the --rootdir flag instead.
 
You can use pkg-add(8) to install files directly, no repo required.

As for why pkg -r works and pkg -c fails, my memory is a bit fuzzy on this but here's what I think is going on... when you use -r it's saying "treat this as the root of where to install files", so it uses your host-level /usr/local/etc/pkg/repos/ but installs into the destdir. When you use -c it's saying "chroot to this dir before running pkg", so it uses the jail-level pkg config - it's chrooted and doesn't know anything about host-level files.

To do what you want with -c you would need to set up the config file at /jails/containers/foo_jail/usr/local/etc/pkg/repos, and create the repo at /jails/containers/foo_jail/opt/builds. That way when it chroots it finds the files at the expected paths.

It's just a tradeoff, with -r you can use the host config but install into another dir, whereas with -c you have to configure the jail fully.

One thing to be aware of is that some packages have pre-install scripts that are not well behaved. They install into /usr/local directly, rather than respecting LOCALBASE. Thus it is generally safer to use -c because it can't inadvertently install files to the host. The tradeoff is that you have to fully configure it.

One trick that you can do is mount_nullfs(8) your /usr/local/etc/pkg/repos/ and /opt/builds to their respective jail paths. Then when you pkg -c it does what you want, but the jail doesn't have a separate config.
 
Back
Top