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