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