TritonDataCenter / pkgsrc

NetBSD/pkgsrc fork for our binary package repositories
https://pkgsrc.smartos.org/
131 stars 51 forks source link

/opt/local/sbin/pkg_alternatives: line 623: [: too many arguments #366

Open drboone opened 11 months ago

drboone commented 11 months ago

Various pkg_alternatives commands generate an error. E.g.

phantom 12 $ pkg_alternatives status go
/opt/local/sbin/pkg_alternatives: line 623: [: too many arguments
`bin/go' points to `/opt/local/go118/bin/go'
    candidate: /opt/local/go118/bin/go
    candidate: /opt/local/go119/bin/go
    candidate: /opt/local/go120/bin/go
`bin/gofmt' points to `/opt/local/go118/bin/gofmt'
    candidate: /opt/local/go118/bin/gofmt
    candidate: /opt/local/go119/bin/gofmt
    candidate: /opt/local/go120/bin/gofmt
`bin/go' points to `/opt/local/go118/bin/go'
    candidate: /opt/local/go118/bin/go
    candidate: /opt/local/go119/bin/go
    candidate: /opt/local/go120/bin/go
`bin/gofmt' points to `/opt/local/go118/bin/gofmt'
    candidate: /opt/local/go118/bin/gofmt
    candidate: /opt/local/go119/bin/gofmt
    candidate: /opt/local/go120/bin/gofmt
`bin/go' points to `/opt/local/go118/bin/go'
    candidate: /opt/local/go118/bin/go
    candidate: /opt/local/go119/bin/go
    candidate: /opt/local/go120/bin/go
`bin/gofmt' points to `/opt/local/go118/bin/gofmt'
    candidate: /opt/local/go118/bin/gofmt
    candidate: /opt/local/go119/bin/gofmt
    candidate: /opt/local/go120/bin/gofmt

This seems to be related to there being nothing much in the database directory:

phantom 19 $ dir /opt/local/share/pkg_alternatives/
total 34
drwxr-xr-x  2 root root    4 Sep 10 09:13 ./
drwxr-xr-x 33 root root   33 Sep 10 09:14 ../
-rw-r--r--  1 root root 2837 Sep  5 01:19 wrapper.man
-rw-r--r--  1 root root 2390 Sep  5 01:19 wrapper.sh

This even after a rebuild.

Have I managed to wound this machine's alternatives setup somehow?

jperkin commented 11 months ago

That line is:

[ ! -f ${PKG_DBDIR}/${1}*/+ALTERNATIVES ] && \
            err "no alternatives defined for the \`${1}' package"

That shell code isn't suitable for globs and should really be rewritten. I think the intention is that you should only be specifying a single package name (e.g. go120, and the rest of it is happening by accident.

FWIW on my macOS host:

$ pkg_alternatives status go
pkg_alternatives: the package `go' is not known
$ pkg_alternatives status go121
`bin/go' points to `/opt/pkg/go121/bin/go'
    candidate: /opt/pkg/go119/bin/go
    candidate: /opt/pkg/go121/bin/go
`bin/gofmt' points to `/opt/pkg/go121/bin/gofmt'
    candidate: /opt/pkg/go119/bin/gofmt
    candidate: /opt/pkg/go121/bin/gofmt
$ echo /opt/pkg/.pkgdb/go*/+ALTERNATIVES
/opt/pkg/.pkgdb/go119-1.19.12/+ALTERNATIVES /opt/pkg/.pkgdb/go121-1.21.1/+ALTERNATIVES

i.e. I'm not getting the same error, so I guess there's an earlier check that is somehow passing for you.

drboone commented 11 months ago

On the smartos machine, there is a go package, which is a meta for whatever is deemed the current release. That's probably what gets mine past the earlier checks.

jperkin commented 11 months ago

Oh ok, yeh those packages are fundamentally incompatible with pkg_alternatives and I usually remove them completely from our package sets (e.g lang/ruby). I think we decided to leave the go package as it was highly likely that people would want to pkgin install go, but it does result in problems like this.

drboone commented 11 months ago

That leads me to this question - there are a few other places, python is the one that comes to mind, where not being able to install one package name and get whatever is deemed current is a headache that leads to hardcoding versions in a bunch of playbooks, and the obvious downstream headache. Is there a better solution?

jperkin commented 11 months ago

Personally I think the best solution is being specific about the versions you want to install. Yes this means you may need to update them every so often, but at least you are then explicit about opting into a new version that has been tested with the rest of your stack, and the versions aren't bumped all that often.

The alternative would be for me to provide e.g. go-latest, python-latest meta-packages that pull in the latest, but that wouldn't be without problems. For example the latest, i.e. newest, version may not be what pkgsrc is currently using as the default, and may not be suitable (e.g. say we import a new python312 but lots of modules aren't yet compatible with it and we keep the default at python311 for a reasonable length of time).

drboone commented 11 months ago

One of the worst problems I have, which I end up fixing (it seems like) several times per year, is that the python offered on the gz tools platform only includes pip for one version. I never seem to notice in advance that an update to that is coming, and suddenly playbooks are crashing. So maybe the underpinning problem is that I need to figure out what to follow in order to know when to pre-emptively fix playbooks. There are a few other things that I retroactively discover -- I think the reason I have go installed on this one system is that some combination of numbered go packages progressing, and rabid dependency updates in stuff I go install kept driving me batty.

jperkin commented 11 months ago

Hmm, could you explain the pip issue a bit more? It looks like we don't ship pip in the gz tools set yet, so perhaps if we start doing that it should solve your issue.

Please make sure you raise issues for any problems that you hit, we want to be able to fix them!

jperkin commented 11 months ago

Oh, ignore part of that - while we don't explicitly list devel/py-pip in our tools builds, it does look like it's built as part of a dependency, and so yeh it will only be built for the current version of python (currently python 3.11).

jperkin commented 11 months ago

Ok I've added devel/py-pip to the tools build, so now there are versions of pip for all available python releases:

$ pkgin se py.*pip
py310-pip-23.2.1     Installs Python packages as an easy_install replacement
py311-pip-23.2.1     Installs Python packages as an easy_install replacement
py38-pip-23.2.1      Installs Python packages as an easy_install replacement
py39-pip-23.2.1      Installs Python packages as an easy_install replacement

I think this should help with the issue you had?

drboone commented 11 months ago

Will definitely help. Thanks!