Skip to content

Commit 4696d38

Browse files
committed
Merge branch 'master' into central-server
2 parents 0ea8705 + 1c35e03 commit 4696d38

File tree

4 files changed

+43
-287
lines changed

4 files changed

+43
-287
lines changed

.github/workflows/nix-shell.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# https://nix.dev/tutorials/continuous-integration-github-actions
2+
name: "Test nix-shell"
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
paths-ignore: []
8+
pull_request:
9+
paths-ignore: []
10+
11+
jobs:
12+
nix-shell:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/[email protected]
16+
- uses: cachix/install-nix-action@v16
17+
with:
18+
nix_path: nixpkgs=channel:nixos-21.11
19+
- run: nix-shell --pure --run "cabal update && cabal build all --enable-tests"

README.md

Lines changed: 4 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -4,276 +4,7 @@ central-server branch: the hackage.haskell.org instance
44
This is the branch for the "official" Hackage server at hackage.haskell.org. Most changes should not be here, but should be made to master.
55

66
# General Documentation
7-
8-
This is the `hackage-server` code. This is what powers <http://hackage.haskell.org>, and many other private hackage instances. The `master` branch is suitable for general usage. Specific policy and documentation for the central hackage instance exists in the `central-server` branch.
9-
10-
## Installing dependencies
11-
12-
`hackage-server` depends on `icu` and `zlib`. You'll also need `libbrotli-dev` for enabling tests.
13-
14-
ICU stands for "International Components for Unicode". The `icu4c` is a set
15-
of libraries that provide Unicode and Globalization support.
16-
The [text-icu](https://hackage.haskell.org/package/text-icu) Haskell package
17-
uses the [icu4c](http://icu-project.org/apiref/icu4c/) library to build.
18-
19-
### Nix shell
20-
21-
If you have the Nix package manager installed, the easiest way to obtain
22-
`hackage-server`'s dependencies is using the Nix shell:
23-
24-
nix-shell
25-
26-
Note: `libbrotli-dev` has to be installed manually.
27-
28-
### Manually
29-
30-
You can also install dependencies manually via your operating system's package
31-
manager.
32-
33-
#### ICU
34-
35-
You'll need to do the following to get `hackage-server`'s dependency `text-icu` to build:
36-
37-
- Mac OS X
38-
39-
brew install icu4c
40-
brew link icu4c --force
41-
42-
Besides that, you might also need to include these in the `cabal.project.local` you created:
43-
44-
```
45-
package text-icu
46-
extra-include-dirs: /usr/local/opt/icu4c/include
47-
extra-lib-dirs: /usr/local/opt/icu4c/lib
48-
```
49-
50-
- Ubuntu/Debian
51-
52-
sudo apt-get update
53-
sudo apt-get install unzip libicu-dev
54-
55-
- Fedora/CentOS
56-
57-
sudo dnf install unzip libicu-devel
58-
59-
- Nix/NixOS
60-
61-
nix-shell --packages icu
62-
63-
#### libbrotli
64-
65-
- Ubuntu/Debian
66-
67-
sudo apt update
68-
sudo apt install libbrotli-dev
69-
70-
- Fedora/CentOS
71-
72-
sudo dnf install brotli-devel
73-
74-
#### openssl
75-
76-
- Fedora/CentOS
77-
78-
sudo dnf install openssl-devel
79-
80-
#### zlib
81-
82-
- Mac OS X
83-
84-
brew install zlib
85-
86-
- Ubuntu/Debian
87-
88-
sudo apt-get update
89-
sudo apt-get install zlib
90-
91-
- Fedora/CentOS
92-
93-
sudo dnf install zlib
94-
95-
- Nix/NixOS
96-
97-
nix-shell --packages zlib
98-
99-
100-
## Setting up security infrastructure
101-
102-
Out of the box the server comes with some example keys and
103-
[TUF](https://theupdateframework.io) metadata. The example keys are in
104-
`example-keys/`; these keys were used to create
105-
106-
datafiles/TUF/root.json
107-
datafiles/TUF/mirrors.json
108-
datafiles/TUF/timestamp.private
109-
datafiles/TUF/snapshot.private
110-
111-
While these files will enable you to start the server without doing anything
112-
else, you should replace all these files before deploying your server. In the
113-
remainder of this section we will explain how to do that.
114-
115-
The first step is to create your own keys using the
116-
[hackage-repo-tool](http://hackage.haskell.org/package/hackage-repo-tool):
117-
118-
hackage-repo-tool create-keys --keys /path/to/keys
119-
120-
Then copy over the timestamp and snapshot keys to the TUF directory:
121-
122-
cp /path/to/keys/timestamp/<id>.private datafiles/TUF/timestamp.private
123-
cp /path/to/keys/snapshot/<id>.private datafiles/TUF/snapshot.private
124-
125-
Create root information:
126-
127-
hackage-repo-tool create-root --keys /path/to/keys -o datafiles/TUF/root.json
128-
129-
And finally create a list of mirrors (this is necessary even if you don't have
130-
any mirrors):
131-
132-
hackage-repo-tool create-mirrors --keys /path/to/keys -o datafiles/TUF/mirrors.json
133-
134-
The `create-mirrors` command takes a list of mirrors as additional arguments if
135-
you do want to list mirrors.
136-
137-
In order for secure clients to bootstrap the root security metadata from your
138-
server, you will need to provide them with the public key IDs of your root keys;
139-
you can find these as the file names of the files created in
140-
`/path/to/keys/root` (as well as in the generated root.json under the
141-
`signed.roles.root.keyids`). An example `cabal` client configuration might look
142-
something like
143-
144-
repository my-private-hackage
145-
url: http://example.com:8080/
146-
secure: True
147-
root-keys: 865cc6ce84231ccc990885b1addc92646b7377dd8bb920bdfe3be4d20c707796
148-
dd86074061a8a6570348e489aae306b997ed3ccdf87d567260c4568f8ac2cbee
149-
e4182227adac4f3d0f60c9e9392d720e07a8586e6f271ddcc1697e1eeab73390
150-
key-threshold: 2
151-
152-
Note that if you elect to not use a secure client, the hackage server will not
153-
provide your client the most recent versions of packages from its index. The
154-
cabal-version:2.0 format packages are thus only available in the newer secure
155-
repository mode. See [Issue #4625](https://github.com/haskell/cabal/issues/4624)
156-
for further information.
157-
158-
## Running
159-
160-
cabal install
161-
162-
hackage-server init
163-
hackage-server run
164-
165-
If you want to run the server directly from the build tree, run
166-
167-
cabal v2-run -- hackage-server init
168-
169-
once to initialise the state. After that you can run the server with
170-
171-
cabal v2-run -- hackage-server run --static-dir=datafiles/ --base-uri=http://127.0.0.1:8080
172-
173-
By default the server runs on port `8080` with the following settings:
174-
175-
URL: http://localhost:8080/
176-
username: admin
177-
password: admin
178-
179-
To specify something different, see `hackage-server init --help` for details.
180-
181-
The http://127.0.0.1:8080/packages/uploaders/edit is used to add users
182-
(e.g. `admin`) to *Uploaders* group.
183-
184-
The server can be stopped by using `Control-C`.
185-
186-
This will save the current state and shutdown cleanly. Running again
187-
will resume with the same state.
188-
189-
### Resetting
190-
191-
To reset everything, kill the server and delete the server state:
192-
193-
```bash
194-
rm -rf state/
195-
```
196-
197-
Note that the `datafiles/` and `state/` directories differ:
198-
`datafiles` is for static html, templates and other files.
199-
The `state` directory holds the database (using `acid-state`
200-
and a separate blob store).
201-
202-
### Creating users & uploading packages
203-
204-
* Admin front-end: <http://localhost:8080/admin>
205-
* List of users: <http://localhost:8080/users/>
206-
* Register new users: <http://localhost:8080/users/register>
207-
208-
Currently there is no restriction on registering, but only an admin
209-
user can grant privileges to registered users e.g. by adding them to
210-
other groups. In particular there are groups:
211-
212-
* admins `http://localhost:8080/users/admins/` -- administrators can
213-
do things with user accounts like disabling, deleting, changing
214-
other groups etc.
215-
* trustees `http://localhost:8080/packages/trustees/` -- trustees can
216-
do janitorial work on all packages
217-
* mirrors `http://localhost:8080/packages/mirrorers/` -- for special
218-
mirroring clients that are trusted to upload packages
219-
* per-package maintainer groups
220-
`http://localhost:8080/package/foo/maintainers` -- users allowed to
221-
upload packages
222-
* uploaders `http://localhost:8080/packages/uploaders/` -- for
223-
uploading new packages
224-
225-
### Mirroring
226-
227-
There is a client program included in the `hackage-server` package called
228-
`hackage-mirror`. It's intended to run against two servers, syncing all the
229-
packages from one to the other, e.g. getting all the packages from the old
230-
hackage and uploading them to a local instance of a hackage-server.
231-
232-
To try it out:
233-
234-
1. On the target server, add a user to the mirrorers group via
235-
http://localhost:8080/packages/mirrorers/.
236-
237-
2. Create a config file that contains the source and target
238-
servers. Assuming you are cloning the packages on
239-
<http://hackage.haskell.org> locally, create the file `servers.cfg`:
240-
241-
```
242-
source "hackage"
243-
uri: http://hackage.haskell.org
244-
type: secure
245-
246-
target "mirror"
247-
uri: http://admin:admin@localhost:8080
248-
type: hackage2
249-
250-
post-mirror-hook: "shell command to execute"
251-
```
252-
Recognized types are `hackage2`, `secure` and `local`.
253-
The target server name was displayed when you ran.
254-
255-
Note, the target must _not_ have a trailing slash, or confusion
256-
will tend to occur. Additionally, if you have ipv6 setup on the
257-
machine, you may need to replace `localhost` with `127.0.0.1`.
258-
259-
Also note that you should mirror _from_ `hackage2` or `secure`
260-
typically and mirror _to_ `hackage2`. Only mirroring from `secure`
261-
will include dependency revision information.
262-
263-
```bash
264-
hackage-server run
265-
```
266-
267-
3. Run the client, pointing to the config file:
268-
269-
```bash
270-
hackage-mirror servers.cfg
271-
```
272-
273-
This will do a one-time sync, and will bail out at the first sign of
274-
trouble. You can also do more robust and continuous mirroring. Use the
275-
flag `--continuous`. It will sync every 30 minutes (configurable with
276-
`--interval`). In this mode it carries on even when some packages
277-
cannot be mirrored for some reason and remembers them so it doesn't
278-
try them again and again. You can force it to try again by deleting
279-
the state files it mentions.
7+
=======
8+
[![Build Status](https://travis-ci.org/haskell/hackage-server.png?branch=master)](https://travis-ci.org/haskell/hackage-server)
9+
[![Build status](https://github.com/haskell/hackage-server/actions/workflows/ci.yml/badge.svg)](https://github.com/haskell/hackage-server/actions/workflows/ci.yml)
10+
[![Build status](https://github.com/haskell/hackage-server/actions/workflows/nix-shell.yml/badge.svg)](https://github.com/haskell/hackage-server/actions/workflows/nix-shell.yml)

shell.nix

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
let
22
nixpkgs = builtins.fetchTarball {
3-
# master on 2021-08-02
4-
url = "https://github.com/NixOS/nixpkgs/archive/70e001f35cc363eb789ea0a04eff11b86c440ba3.tar.gz";
5-
sha256 = "1mrhbcfa8kkx1qnax8xh41grinqiycl56wlws5vvrli8w0pzgl1r";
3+
# master on 2022-05-14
4+
url = "https://github.com/NixOS/nixpkgs/archive/1d370bd07399fb52cea6badfbffbc90ac9b0f8f0.tar.gz";
5+
sha256 = "1ln4vwy185gwhbf4f8vanrlj4w4bhwrcsb2m8fnm99f4zqzvp7fs";
66
};
77

88
pkgs = import nixpkgs { config = { }; };
99

1010
in
1111
pkgs.mkShell {
12-
buildInputs = [
12+
buildInputs = with pkgs; [
1313
# Haskell development
14-
pkgs.cabal-install
15-
pkgs.ghc
14+
cabal-install
15+
ghc
1616

1717
# Dependencies
18-
pkgs.icu
19-
pkgs.zlib
20-
pkgs.brotli
18+
glibc
19+
icu67
20+
zlib
21+
openssl
22+
cryptodev
23+
pkg-config
24+
brotli
2125
];
2226
}

src/Distribution/Server/Util/Validators.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ guardValidLookingEmail str = either errBadEmail return $ do
3030
guard (T.all (not.isAngle) str) ?! "Please use just the email address, not \"name\" <[email protected]> style."
3131
where
3232
isAngle c = c == '<' || c == '>'
33-
hasAtSomewhere =
34-
let (before, after) = T.span (/= '@') str
35-
in T.length before >= 1
36-
&& T.length after > 1
37-
&& not ('@' `T.elem` after)
33+
hasAtSomewhere = case T.span (/= '@') str of
34+
(before, rest)
35+
| Just (_, after) <- T.uncons rest ->
36+
T.length before >= 1
37+
&& T.length after > 0
38+
&& not ('@' `T.elem` after)
39+
_ -> False
3840

3941
errBadUserName, errBadRealName, errBadEmail :: String -> ServerPartE a
4042
errBadUserName err = errBadRequest "Problem with login name" [MText err]

0 commit comments

Comments
 (0)