Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle it with Docker #35

Merged
merged 7 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Dockerfile
result/
bin/
.github
.git
41 changes: 36 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
# From https://mitchellh.com/writing/nix-with-dockerfiles
FROM nixos/nix:latest AS builder

WORKDIR /tmp
RUN mkdir -p ./nix-store-closure

COPY . /tmp/build
WORKDIR /tmp/build

RUN mkdir /tmp/nix-store-closure
RUN --mount=type=cache,target=/nix/store,from=nixos/nix:latest,source=/nix/store nix \
--extra-experimental-features "nix-command flakes" \
--option filter-syscalls false \
build && \
build .#server && \
cp -R $(nix-store -qR result/) /tmp/nix-store-closure && \
cp -R result/bin ./

FROM scratch
WORKDIR /tmp/root
RUN mkdir -p ./bin
RUN cp -R $(nix-store -qR /nix/store/*-shadow-*/) /tmp/nix-store-closure
RUN cp $(ls -1 /nix/store/*-shadow-*/bin/newuidmap) ./bin/newuidmap && \
chmod u+s ./bin/newuidmap && \
cp $(ls -1 /nix/store/*-shadow-*/bin/newgidmap) ./bin/newgidmap && \
chmod u+s ./bin/newgidmap

FROM nixos/nix:latest AS setup

WORKDIR /bin
WORKDIR /tmp/root
RUN mkdir -p ./etc/ayup ./var/lib/ayup ./run/ayup ./tmp ./bin \
./run/buildkit ./run/runc ./var/lib/cni
RUN chown 1000:1000 ./etc/ayup ./var/lib/ayup ./run/ayup ./tmp \
./run/buildkit ./run/runc ./var/lib/cni
RUN echo 'ayup:x:1000:100:Ayup user:/:/bin/ay' > ./etc/passwd
RUN echo 'ayup:100000:65536' > ./etc/subgid
RUN echo 'ayup:100000:65536' > ./etc/subuid

FROM scratch

COPY --from=builder /tmp/root /
COPY --from=setup /tmp/root /
COPY --from=builder /tmp/nix-store-closure /nix/store
COPY --from=builder /tmp/build/bin/ay ./ay
COPY --from=builder /tmp/build/bin/ay /bin/ay

VOLUME ["/etc/ayup", "/var/lib/ayup", "/run/ayup"]

USER 1000:100

ENV PATH=/bin
ENV XDG_RUNTIME_DIR=/run
ENV XDG_DATA_HOME=/var/lib
ENV XDG_CONFIG_HOME=/etc

CMD ["/bin/ay"]
66 changes: 46 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ In the pipeline (in no particular order)

# Install

## Client

The client CLI can be installed by copying the following into a terminal session:

```sh
Expand All @@ -51,32 +53,39 @@ curl -#L https://raw.githubusercontent.com/premAI-io/Ayup/main/script/install.sh
Or you can download the executable from the [release page](https://github.com/premAI-io/Ayup/releases/latest).
It's just one file, you can copy it to `/usr/bin` or wherever you put executables on your system.

Presently the server is in the same executable as the client. However it has some dependencies which
are a pain. Eventually we'll magic these away, but in the mean time see the Development section.
Presently the server is in the same executable as the client. However it has some dependencies.

# Running
## Server

## Config
There are two easy ways to install the server: Nix and Docker. In both cases installing and running
are practically the same operation.

All of Ayup's configuration is done via environment variables or command line switches. However you
can also set environment variables in `~/.config/ayup/env` which is in the usual
[dotenv format](https://github.com/joho/godotenv).
For Docker you can do

Settings you choose interactively will be persisted to the env file if possible. Command line switches and
environment variables take precedence over the env file.
```sh
$ mkdir ~/.config/ayup
$ docker run --privileged --rm -it -v ~/.config/ayup:/etc/ayup -p 50051:50051 premai/ayup:latest ay daemon start --host=/ip4/0.0.0.0/tcp/50051
```

You can see all available config using the `--help` switch e.g. `ay push --help`, `ay daemon start
--help`
> [!TIP]
> The Ayup server only supports Linux, but Docker Desktop should be able to run it on Windows
> and Mac.

## Server
With Nix you can start a shell and run `ay`

Presently the server has three prerequisites: Buildkit, Rootlesskit and the CNI plugins. We plan to
bundle them, but for now you need to install them or use Nix as described in the development
section.
```sh
$ nix shell github:premAI-io/Ayup
$ ay daemon start --host=/ip4/0.0.0.0/tcp/50051
```

You don't need to start Buildkitd, Ayup will start it for you inside Rootlesskit.
See the development section for more information on Nix.

### Start
To install the server manually, follow the instructions for the client and then install the
dependencies listed in `distros/nix/server.nix`.

# Running

## Server

To start Ayup listening for local connections do

Expand All @@ -96,6 +105,11 @@ encrypted connections using libp2p.
Ayup will print details on how to login to the server from a client. This requires shell access to
the Ayup server so that you can interactively authorize the client.

> [!NOTE]
> The IP address in the printed multiaddress will only be accessible locally when using Docker. It may need
> to be replaced with the host's public IP or DNS name. For e.g
> `/dns4/example.com/tcp/50051/p2p/1...`

Clients can also be pre-authorized by adding their peer IDs to `AYUP_P2P_AUTHORIZED_CLIENTS`

## Client
Expand Down Expand Up @@ -123,6 +137,18 @@ The login command will set `AYUP_PUSH_HOST` in `~/.config/ayup/env` to the addre
to. So that `ay push` will use it by default. You can override it in the environment or by using
`--host`.

## Config

All of Ayup's configuration is done via environment variables or command line switches. However you
can also set environment variables in `~/.config/ayup/env` which is in the usual
[dotenv format](https://github.com/joho/godotenv).

Settings you choose interactively will be persisted to the env file if possible. Command line switches and
environment variables take precedence over the env file.

You can see all available config using the `--help` switch e.g. `ay push --help`, `ay daemon start
--help`

## Examples

There is an [examples directory](https://github.com/premAI-io/Ayup/tree/main/examples) that contains
Expand Down Expand Up @@ -161,17 +187,17 @@ Then there is a choice between using the Nix dev shell...

Or using Nix to build/run the project...

3. `sudo nix run .#server` run the server
3. `nix run .#server` run the server
4. `nix run .#cli` run the cli

Also you don't need to Git clone this project onto a system to run it with Nix. You can run the
flake from this repo with

`sudo nix run github:premAI-io/Ayup#<server,cli>`
`nix run github:premAI-io/Ayup#<server,cli>`

Or if you want to try out a dev branch

`sudo nix run github:<user>/<repo>/<branch>#<server,cli>`
`nix run github:<user>/<repo>/<branch>#<server,cli>`

# Logs and tracing

Expand Down
1 change: 0 additions & 1 deletion distros/nix/cli-cross.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ in
version = version;
src = srcWithProtobuf;
modRoot = "./go";
# Use lib.fakeHash when updating deps
inherit vendorHash;
# Avoids workspace mode error
proxyVendor = true;
Expand Down
19 changes: 16 additions & 3 deletions distros/nix/server.nix
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
{
lib, stdenv, makeWrapper, version, buildkit, cli
lib, stdenv, makeWrapper, version, cli,
buildkit, slirp4netns, rootlesskit, runc, cni, buildkit-cni-plugins,
util-linux, iproute2, iptables, cacert
}:
let
runtimeDeps = [ buildkit ];
runtimeDeps = [
slirp4netns
rootlesskit
runc
cni
buildkit-cni-plugins
buildkit
util-linux # unshare,nsenter for rootlesskit
iproute2 # ip for slirp4netns
iptables # for CNI
];
in
stdenv.mkDerivation {
pname = "ayup-server";
Expand All @@ -15,6 +27,7 @@ in
mkdir -p $out/bin
cp $src/bin/ay $out/bin/
wrapProgram $out/bin/ay \
--prefix PATH : ${ lib.makeBinPath runtimeDeps }
--prefix PATH : ${ lib.makeBinPath runtimeDeps } \
--set SSL_CERT_FILE "${cacert}/etc/ssl/certs/ca-bundle.crt"
'';
}
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
GOARCH = "amd64";
};
server = pkgs.callPackage ./distros/nix/server.nix {
inherit version cli;
inherit version cli buildkit-cni-plugins;
};
in
{
Expand Down
9 changes: 3 additions & 6 deletions go/cmd/ay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"premai.io/Ayup/go/cli/key"
"premai.io/Ayup/go/cli/login"
"premai.io/Ayup/go/cli/push"
"premai.io/Ayup/go/internal/conf"
"premai.io/Ayup/go/internal/terror"
ayTrace "premai.io/Ayup/go/internal/trace"
"premai.io/Ayup/go/internal/tui"
Expand Down Expand Up @@ -118,11 +119,8 @@ func Main(version string) {
errorStyle := tui.ErrorStyle
fmt.Print(titleStyle.Render("Ayup!"), " ", versionStyle.Render("v"+version), "\n\n")

confDir, userConfDirErr := os.UserConfigDir()
var godotenvLoadErr error
if userConfDirErr == nil {
godotenvLoadErr = godotenv.Load(filepath.Join(confDir, "ayup", "env"))
}
confDir := conf.UserConfigDir()
godotenvLoadErr := godotenv.Load(filepath.Join(confDir, "env"))

ktx := kong.Parse(&cli, kong.UsageOnError(), kong.Description("Just make it run!"))

Expand All @@ -147,7 +145,6 @@ func Main(version string) {
ctx, span := tracer.Start(ctx, "main")
defer span.End()

terror.Ackf(ctx, "os UserConfigDir: %w", userConfDirErr)
terror.Ackf(ctx, "godotenv load: %w", godotenvLoadErr)

err := ktx.Run(Globals{
Expand Down
12 changes: 9 additions & 3 deletions go/srv/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/charmbracelet/huh"
"github.com/muesli/termenv"
"go.opentelemetry.io/otel/trace"

"premai.io/Ayup/go/internal/conf"
Expand Down Expand Up @@ -49,14 +50,19 @@ func (s *Srv) Login(ctx context.Context, in *pb.LoginReq) (*pb.LoginReply, error

// TODO: timeout

accessible := false
if termenv.ColorProfile() == termenv.Ascii {
accessible = true
}

authed := false
err = huh.NewConfirm().
hconf := huh.NewConfirm().
Title("Authorize client?").
Description(fmt.Sprintf("Peer ID: %s", peerId.String())).
Value(&authed).
Run()
WithAccessible(accessible)

if err != nil {
if err := hconf.Run(); err != nil {
return internalError(err)
}

Expand Down
2 changes: 1 addition & 1 deletion go/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.0
0.7.1