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