]> Cypherpunks.ru repositories - gocheese.git/blob - gocheese.texi
Simpler CSS inclusion
[gocheese.git] / gocheese.texi
1 \input texinfo
2 @documentencoding UTF-8
3 @settitle GoCheese
4
5 @copying
6 Copyright @copyright{} 2019-2021 @email{stargrave@@stargrave.org, Sergey Matveev}
7 @end copying
8
9 @node Top
10 @top
11
12 GoCheese is Python private package repository and caching proxy.
13
14 It serves two purposes:
15
16 @itemize
17 @item proxying and caching of missing packages from upstream
18     @url{https://pypi.org/, PyPI}, conforming to
19     @url{https://www.python.org/dev/peps/pep-0503/, PEP-0503}
20     (Simple Repository API)
21 @item hosting of private locally uploaded packages, conforming to
22     @url{https://warehouse.pypa.io/api-reference/legacy/, Warehouse Legacy API}
23 @end itemize
24
25 Why could you like it and how it can be better to fit your needs?
26
27 @itemize
28 @item No database required. Only filesystem storage with few simple
29     files per package. Package deletion, renaming, making it uploadable
30     (private) is done with simple @command{mkdir}, @command{touch}, etc
31     commands
32 @item Just single statically compiled Go binary
33 @item No configuration file, but several simple command line arguments
34 @item Consistency (because of atomic synced operations) and integrity
35     (because of SHA256 checksums stored nearby)
36 @end itemize
37
38 Initially it was created as a fork of
39 @url{https://github.com/c4s4/cheeseshop, cheeseshop},
40 but nearly all the code was rewritten. It has huge differences:
41
42 @itemize
43 @item Proxying and caching of missing packages, including GPG signatures
44 @item @url{https://pythonwheels.com/, Wheel} uploading support
45 @item Integrity check of proxied packages: MD5, SHA256, SHA512, BLAKE2b-256
46 @item SHA256 checksums for stored packages
47 @item Verifying of SHA256 checksum for uploaded packages
48 @item Ability to authenticate upstream PyPI with its X.509 certificate's hash
49 @item Storing of uploaded GPG signatures
50 @item Secure Argon2i (or SHA256) stored passwords hashing
51 @item No YAML configuration, just command-line arguments
52 @item No package overwriting ability (as PyPI does too)
53 @item Graceful HTTP-server shutdown
54 @item Atomic packages store on filesystem
55 @end itemize
56
57 Also it contains @file{contrib/pyshop2packages.sh} migration script for
58 converting @url{https://pypi.org/project/pyshop/, Pyshop} database into
59 GoCheese one, including private packages.
60
61 GoCheese is
62 @url{https://www.gnu.org/philosophy/pragmatic.html, copylefted}
63 @url{https://www.gnu.org/philosophy/free-sw.html, free software}
64 licenced under @url{https://www.gnu.org/licenses/gpl-3.0.html, GNU GPLv3}.
65
66 Please send questions, bug reports and patches to @url{gocheese@@cypherpunks.ru}.
67
68 @insertcopying
69
70 @menu
71 * Install::
72 * Usage::
73 * Password authentication: Passwords.
74 * TLS support: TLS.
75 * Storage format: Storage.
76 @end menu
77
78 @include install.texi
79
80 @node Usage
81 @unnumbered Usage
82
83 To use it for download purposes, just configure your @file{pip.conf}:
84
85 @example
86 [install]
87 index-url = http://gocheese.host:8080/simple/
88 @end example
89
90 @option{-refresh} URL (@code{/simple/} by default) automatically
91 refreshes metainformation (available versions and their checksums)
92 from the upstream, when queried for package directory listing.
93 @option{-norefresh} prevents upstream queries.
94
95 @option{-gpgupdate} is useful mainly for migrated for Pyshop migrated
96 repositories. It forces GPG signature files downloading for all existing
97 package files.
98
99 You can upload packages to it with @url{https://pypi.org/project/twine/, twine}:
100
101 @example
102 twine upload
103     --repository-url http://gocheese.host:8080/simple/ \
104     --username spam \
105     --password foo dist/tarball.tar.gz
106 @end example
107
108 Or you can store it permanently in @file{.pypirc}:
109
110 @example
111 [pypi]
112 repository: https://gocheese.host/simple/
113 username: spam
114 password: foo
115 @end example
116
117 If @command{twine} sends SHA256 checksum in the request, then uploaded
118 file is checked against it.
119
120 Pay attention that you have to manually create corresponding private
121 package directory! You are not allowed to upload anything explicitly
122 flagged as internal package.
123
124 It is advisable to run GoCheese under some kind of
125 @url{http://cr.yp.to/daemontools.html, daemontools}.
126
127 @node Passwords
128 @unnumbered Password authentication
129
130 Password authentication is required for packages uploading.
131 You have to store your authentication data in @option{-passwd} file in
132 following format:
133
134 @example
135 username:hashed-password
136 @end example
137
138 Empty lines and having @verb{|#|} at the beginning are skipped.
139
140 Supported hashing algorithms are:
141
142 @table @asis
143
144 @item @url{https://www.argon2i.com/, Argon2i} (recommended one!)
145     To get Argon2i hashed-password you can use any of following tools:
146     @itemize
147     @item go get @url{https://github.com/balakhonova/argon2i,
148         github.com/balakhonova/argon2i} (Go)
149     @item @url{https://github.com/p-h-c/phc-winner-argon2} (C)
150     @end itemize
151     Example user @code{foo} with password @code{bar} can have the
152     following password file entry:
153
154 @verbatim
155 foo:$argon2i$v=19$m=32768,t=3,p=4$OGU5MTM3YjVlYzQwZjhkZA$rVn53v6Ckpf7WH0676ZQLr9Hbm6VH3YnL6I9ONJcIIU
156 @end verbatim
157
158 @item SHA256
159     You can use your operating system tools:
160
161 @example
162 # BSD-based systems:
163 $ echo -n "password" | sha256
164
165 # GNU/Linux-based systems
166 $ echo -n "password" | sha256sum
167 @end example
168
169     Example user @code{foo} with password @code{bar} will have the
170     following password file entry:
171
172 @verbatim
173 foo:$sha256$fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9
174 @end verbatim
175
176 @end table
177
178 You can refresh passwords by sending @code{SIGHUP} signal to the working daemon:
179
180 @example
181 $ pkill -HUP gocheese
182 $ kill -HUP `pidof gocheese`
183 $ svc -h /var/service/gocheese
184 @end example
185
186 Before refreshing it's recommended to check @option{-passwd} file with
187 @option{-passwd-check} option to prevent daemon failure.
188
189 @node TLS
190 @unnumbered TLS support
191
192 You can enable TLS support by specifying PEM-encoded X.509 certificate
193 and private key files. Go's TLS implementation supports TLS 1.3, HTTP/2
194 negotiation, Keep-Alives, modern ciphersuites and ECC.
195
196 For example generate some self-signed certificate using GnuTLS toolset:
197
198 @example
199 $ certtool --generate-privkey --ecc --outfile prv.pem
200 $ cert_template=`mktemp`
201 $ echo cn=gocheese.host > $cert_template
202 $ certtool \
203     --generate-self-signed \
204     --load-privkey=prv.pem \
205     --template $cert_template \
206     --outfile=cert.pem
207 $ rm $cert_template
208 $ gocheese -tls-cert cert.pem -tls-key prv.pem [...]
209 @end example
210
211 @node Storage
212 @unnumbered Storage format
213
214 Root directory has the following hierarchy:
215
216 @verbatim
217 root
218   +-- public-package
219   |     +- public-package-0.1.tar.gz.md5
220   |     +- public-package-0.1.tar.gz.blake2_256
221   |     +- public-package-0.1.1.tar.gz.blake2_256
222   |     +- public-package-0.2.tar.gz
223   |     +- public-package-0.2.tar.gz.asc
224   |     +- public-package-0.2.tar.gz.sha256
225   +-- private-package
226   |     +- .internal
227   |     +- private-package-0.1.tar.gz
228   |     +- private-package-0.1.tar.gz.asc
229   |     +- private-package-0.1.tar.gz.sha256
230   |...
231 @end verbatim
232
233 Each directory is a normalized package name. When you try to list non
234 existent directory contents (you are downloading package you have not
235 seen before), then GoCheese will download information about package's
236 versions with checksums and write them in corresponding
237 @file{.sha256}, @file{.blake2_256}, @file{.sha512}, @file{.md5} files.
238 However no package package tarball is downloaded.
239
240 When you request for particular package version, then its tarball is
241 downloaded and verified against the stored checksum. But SHA256 is
242 forced to be stored and used later.
243
244 For example @file{public-package} has @code{0.1} version, downloaded a
245 long time ago with MD5 checksum. @code{0.1.1} version is downloaded more
246 recently with BLAKE2b-256 checksum, also storing that checksum for
247 @code{0.1}. @code{0.2} version is downloaded tarball, having forced
248 SHA256 recalculated checksum. Also upstream has corresponding
249 @file{.asc} signature file.
250
251 @file{private-package} is private package, because it contains
252 @file{.internal} file. It can be uploaded and queries to it are not
253 proxied to upstream PyPI. You have to create it manually. If you upload
254 GPG signature, then it will be also stored.
255
256 @bye