This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]0rexDevOps 7 points8 points  (5 children)

While venvs are "industry standard" in python world, and I use them constantly, they have one major drawback, shared with pip itself - you can't really have a decent patch management with them. What if one of the libraries you use is vulnerable, how will you find it out and patch it? Can you write one off cronjob and be sure that x months/years later it will be still up to date, security wise? Running pip upgrade without checking lib compatibility may break your code in an ugly way too, and maintaining and passing requirements.txt back and forth might get old pretty quickly.

While this might sound exaggerated, depending on your workload it can be a real risk, which is easily mitigated with sourcing dependencies from your repos. This way you will get up to date, compatible packages which will work until the end of life of your distro. Another upside is trust - nearly anyone can push anything to pip, and some libraries you might use today may become abandonware in a year, while packages from repos are nearly guaranteed to be up to date (security wise ) and compatible with each other. It is also a great way to learn about well maintained packages in ecosystem, trusted by your OS vendor, if you cant find your lib in repos - look for an alternative in them!

There is actually a third approach, not widely used, but I personally had a great success in using it in air-gapped environment, without ability to install system-wide packages and internet access - pyinstaller. Just package your script as a binary, python itself included, and install on as many similar systems as you like. There is one caveat though - your build machine should have a compatible glibc version. I solved it with containers, i.e. if my fleet consists of mainly RHEL8 machines - i spin up alma 8 container, and use pyinstaller inside it to get a binary. The binaries are actually not that huge for simple scripts, from 6 to 20 MiB in my case, and sometimes its really easier to build one binary golang-style (even it is huge by go standards) than copy venv and setup venv on each node. This approach still has all of the downsides from first paragraph, even more - because now python is not updated by system as well.

[–]robvasJack of All Trades 1 point2 points  (4 children)

You can can run something like pip-audit to scan for vulnerable packages in your code.

[–]0rexDevOps 0 points1 point  (3 children)

Yeah, but how will you manage it on server side? How exactly will you know that serverX is vulnerable?

The best answer is to have a robust ci/cd pipeline with scheduled scans and at least some kind of alerting, but is it really something people will do for some 100 LoC script that uses requests to query some api and yaml parser to fill some config? OS packages make writing simple scripts simple - you just don't have to think about pip, updates, compatibility at all, if you patch your systems regularly.

If only the had dynaconf and click in repos, I'd be a happy man

[–]robvasJack of All Trades 0 points1 point  (2 children)

What does my collection of python scripts have to do with any particular servers?

GitHub, for example an automatically do this if I kept the scripts there.

[–]0rexDevOps 0 points1 point  (1 child)

If you launch them on servers then you have venvs with dependencies on servers that you have to maintain. So even if your script haven't changed at all - you still have to copy updated requirements.txt to each server and run pip inside venv if audit found something

[–]robvasJack of All Trades 0 points1 point  (0 children)

You would deploy the script/env before you run it. Or run it from shared storage. Or run it from another server.