-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chocolatey Package Caching and Checksums for Performance and Security #397
Comments
We cannot bootstrap the cache directory in gitlab directly. It has to be done through the first time run of the job on cicd. So one has to check first if a particular directory has the relevant contents, if not, acquire it from the community upstream but with a predefined checksum that we embedded locally from our own development machines and Ideally this would be done automatically if we add our |
You may need my help on the windows machine due to admin access to work with chocolatey. Let's do this in the office. |
This tutorial https://docs.chocolatey.org/en-us/features/host-packages#local-folder-unc-share-cifs for internalising a package doesn't work for It should look like this (the tools folder is needed in particular) |
Can you search around why? |
I think it's because |
You'd think it would be easier to "internalize" a portable application
and harder to "internalize" a package with native installer. This is
quite strange...
…On 7/5/22 14:44, emmacasolin wrote:
I think it's because |nodejs|/|python| don't have/require a native
installer to use, so they're treated slightly differently by
Chocolatey
https://docs.chocolatey.org/en-us/faqs#what-distinction-does-chocolatey-make-between-an-installable-and-a-portable-application.
There's a command you can run on the business version of Chocolatey to
do the whole process automatically and they give an example of it with
nodejs, so there should be a way to do it manually, I'll just need to
work out how.
—
Reply to this email directly, view it on GitHub
<#397 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAE4OHN5FOUSKOVXDIWU34TVSO4S5ANCNFSM52OWKHEQ>.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
I've found a version that has the tools subfolder now - needed to download the "install" version https://community.chocolatey.org/packages/nodejs.install/16.14.2 |
Now that I'm using the correct version I've successfully created a package for
I haven't tested it yet though since I can't do so without overriding the currently installed version, but this |
What version of python are we using? I can't see it in the CI/CD. |
Package checksums:
|
I've internalised the packages for both |
In the end it was indeed easier to internalise |
This internalizing process will need to occur in the CICD in order to prime the cache. Basically upon first run it would need to check a folder source, if not exists, download and internalised to the directory. Then subsequent runs install from the directory. You would check if you can install from folder if it exists there and look for an error or conditional to switch to downloading from chocolatey. |
I think with the conditionals and internalisation we might need a PowerShell script to do everything. Since we're not using Chocolatey Pro we don't have access to Chocolatey commands and options like |
Yea you can write a PowerShell script in scripts dir and execute it there.
On 6 July 2022 11:10:44 am AEST, emmacasolin ***@***.***> wrote:
I think with the conditionals and internalisation we might need a PowerShell script to do everything. Since we're not using Chocolatey Pro we don't have access to Chocolatey commands and options like `download` and `install --download-cache` that would make it easier to do these things without a script.
--
Reply to this email directly or view it on GitHub:
#397 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
|
Some notes while I'm working on the script:
|
By internalizing the nupkg file is that also internalizing all the package contents, the goal is to avoid redownloading things over the internet. Also I suspect that by adding a folder source as a separate command that it would enable falling back to chocolatey community source. That's how most package managers work. Not sure about the source option in install though. |
I also provided some options required during install where you can pass the desired checksum. I posted it up somewhere. |
It internalises the installer. So nothing needs to be redownloaded over the internet but it does still need to re-create and reinstall the package contents.
Yeah |
I've got the internalising part working on the ci/cd, now I just need to move the created file into our
Would it be possible to use a gitlab variable there instead of writing out the path? |
Isn't it possible to directly internalize into that directory in the first place? As for env variables, yea just use I'd suggest avoiding embedding any gitlab variables into our scripts. Our scripts should work without the presence of those variables. So all paths should be made relative to the script's directory. In bash, I have a snippet that acquires the script's directory. Powershell will probably have their own mechanism. Google around for it. |
Yes it looks like I can internalise directly into the directory we want using
when running |
I've got the Side note that the default mode for caching on the CI/CD is to only upload the cache if the job succeeds, but this means that the Jest cache (and also Homebrew/Chocolatey) would only be kept if all of the tests passed. Failed test data is still useful for running the tests on the next run, and we still want to keep other cache data even if tests fail, so I've set # Cached directories shared between jobs & pipelines per-branch per-runner
cache:
key: $CI_COMMIT_REF_SLUG
when: 'always'
paths:
- ./tmp/npm/
- ./tmp/ts-node-cache/
# Homebrew cache is only used by the macos runner
- ./tmp/Homebrew
# Chocolatey cache is only used by the windows runner
- ./tmp/chocolatey/
# `jest` cache is configured in jest.config.js
- ./tmp/jest/ |
The cache works and the CI/CD will attempt to build from it if it exists! There are some errors that I need to look into but they can most likely be fixed by adding command line options.
For nodejs I think I just need to add the |
The windows runner comes with the nodejs 12, so you want to force install over it.
|
Chocolatey caching is now set up and working! All I needed to fix the errors above was to specify the version when installing (this has a similar effect to When a source is specified it overrides the default source, so because of this (and also since we only want to do the internalisation if it hasn't been done already), I'm running a different install command depending on whether the cache exists. if ( Test-Path -Path ".\tmp\chocolatey\nodejs.install\nodejs.install.16.14.2.nupkg" -PathType Leaf ) {
choco install nodejs.install --version="16.14.2" --source=".\tmp\chocolatey\nodejs.install" -y
} else {
choco install nodejs --version="16.14.2" --require-checksums -y
Rename-Item -Path "C:\ProgramData\chocolatey\lib\nodejs.install\nodejs.install.nupkg" -NewName "nodejs.install.nupkg.zip"
Expand-Archive -LiteralPath "C:\ProgramData\chocolatey\lib\nodejs.install\nodejs.install.nupkg.zip" -DestinationPath "C:\ProgramData\chocolatey\lib\nodejs.install" -Force
Remove-Item "C:\ProgramData\chocolatey\lib\nodejs.install\_rels" -Recurse
Remove-Item "C:\ProgramData\chocolatey\lib\nodejs.install\package" -Recurse
Remove-Item "C:\ProgramData\chocolatey\lib\nodejs.install\[Content_Types].xml"
New-Item -Path ".\tmp\chocolatey\nodejs.install" -ItemType "directory"
choco pack "C:\ProgramData\chocolatey\lib\nodejs.install\nodejs.install.nuspec" --outdir ".\tmp\chocolatey\nodejs.install"
}
if ( Test-Path -Path ".\tmp\chocolatey\python3\python3.3.9.12.nupkg" -PathType Leaf ) {
choco install python3 --version="3.9.12" --source=".\tmp\chocolatey\python3" -y
} else {
choco install python --version="3.9.12" --require-checksums -y
Rename-Item -Path "C:\ProgramData\chocolatey\lib\python3\python3.nupkg" -NewName "python3.nupkg.zip"
Expand-Archive -LiteralPath "C:\ProgramData\chocolatey\lib\python3\python3.nupkg.zip" -DestinationPath "C:\ProgramData\chocolatey\lib\python3" -Force
Remove-Item "C:\ProgramData\chocolatey\lib\python3\_rels" -Recurse
Remove-Item "C:\ProgramData\chocolatey\lib\python3\package" -Recurse
Remove-Item "C:\ProgramData\chocolatey\lib\python3\[Content_Types].xml"
New-Item -Path ".\tmp\chocolatey\python3" -ItemType "directory"
choco pack "C:\ProgramData\chocolatey\lib\python3\python3.nuspec" --outdir ".\tmp\chocolatey\python3"
} |
I've now switched to using |
Optimised Windows CI/CD setup by internalising and caching chocolatey packages Fixes #397
Optimised Windows CI/CD setup by internalising and caching chocolatey packages Fixes #397
Optimised Windows CI/CD setup by internalising and caching chocolatey packages Fixes #397
Optimised Windows CI/CD setup by internalising and caching chocolatey packages Fixes #397
Specification
The
build:windows
and subsequentlyintegration:windows
jobs involve using chocolatey to download packages to be usable on Windows. In particularnodejs
andpython
.The current configuration in
.gitlab-ci.yml
will redownload packages and reinstall each time. This is slow, error prone and results in our CI/CD getting rate limited from chocolatey (#394 (comment)).On top of that the chocolatey community software packages on https://community.chocolatey.org/packages, which is the default source of packages is not entirely secure, or at least not recommended for organisational usage https://docs.chocolatey.org/en-us/community-repository/community-packages-disclaimer.
Furthermore when downloading and installing chocolatey packages, we are simply relying on the checksum specified by the package maintainer. This is the case with nixpkgs, but with nixpkgs we can pin our package set from
nixpkgs-overlay
, with chocolatey, this is not the case. We can get halfway there by doing TOFU, and acquiring the checksum for a trusted version of the package, and then enforce that installing the package again must also have the same checksum.This is particularly important because some packages download things over the internet during installation (this is due to chocolatey lacking distribution rights, thus the "package" is just an instruction set on how to download & install, but not the actual software runtime being installed). Having a checksum specified at our CI/CD level just ensures some level of end-to-end trust of immutability.
Additional context
--checksum
and below parameters and find out which we can use to ensure integrity of our installed packages on chocolatey.VERIFICATION.txt
files available in the installation packages. Note that we are often using meta packages that then point to a particular package under dependencies. These dependencies then haveFiles
, one of them beingVERIFICATION.txt
. This can be used to acquire checksums as well, however you have to check whether this is actually different or related to the package checksum. If it is possible to rely on the package checksum which itself contains checksums on its contents, then prefer to use the package checksum.Tasks
matrix-win-1
computer first before applying to gitlab cicdnodejs
andpython
into that directory.gitlab-ci.yml
choco info <packageName>
and specify these checksums when performing a installationchoco install
is installing from the our local directory source by using--source
option, and not from the upstream community source, this should remove any 429 too many request rate limitingThe text was updated successfully, but these errors were encountered: