Skip to content

Commit

Permalink
Release 0.14.0. See release notes.
Browse files Browse the repository at this point in the history
[Fixed]
- In KuboBootstrapper, calling Stop now gracefully shuts down the Kubo node by invoking the `ipfs shutdown` command and stopping the process, instead of killing it outright.
[Improvements]
- In KuboDownloader, GetBinaryVersionAsync and GetLatestBinaryAsync now have overloads for both HttpClient and IpfsClient.
- In KuboDownloader, GetBinaryVersionAsync and GetLatestBinaryAsync now crawls compressed archives directly from Http/Ipfs, returning an IFile of the Kubo binary without downloading and extracting to disk.
- The streams opened by IpfsFile and IpnsFile are now seekable.
- The streams opened by IpfsFile and IpnsFile now supply an accurate stream Length based on the Size given by Kubo.
[Breaking]
- The KuboDownloader class is now static.
- In KuboDownloader, the DownloadLatestBinaryAsync method has been replaced with GetLatestBinaryAsync.
- In KuboDownloader, the DownloadBinaryAsync method has been replaced with GetBinaryVersionAsync.
- In KuboDownloader, the return type on GetLatestKuboVersionAsync was changed. This method now returns a Version, without the - tuple and RawVersion.
- In KuboDownloader, the method parameters of GetLatestKuboVersionAsync were changed. This method now takes any `IFile` pointing - to a versions file, rather than a url pointing to the default versions file on http.
- In KuboBootstrapper, the constructor now takes the repoPath first for all constructors.
- In KuboBootstrapper, the IFile previous provided in the constructor has been replaced with an optional file delegate.
- In KuboBootstrapper, if the binary isn't in the BinaryWorkingFolder, it will be retrieved using the file delegate provided in - the constructor. If no delegate is provided, the latest version will be retrieved via Http.
- In KuboBootstrapper, ApplySettingsAsync is now ApplySettings, and is no longer async.
- In KuboBootstrapper, the Kubo binary is now copied directly to the given BinaryWorkingFolder, instead of making a subfolder. - The default location is still the system temp folder.
  • Loading branch information
Arlodotexe committed Nov 15, 2023
1 parent 0d3de18 commit 03ac7f4
Show file tree
Hide file tree
Showing 11 changed files with 434 additions and 256 deletions.
61 changes: 43 additions & 18 deletions docs/KuboBootstrapper.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,64 @@
# KuboBootstrapper
A no-hassle bootstrapper for the Kubo binary.

On startup, the binary is copied to the users's temp directory, where it can be executed on any platform.
When started, the binary retrieved and copied to the BinaryWorkingFolder where it can be executed on any platform. By default, this is the system temp folder.

> **Warning** Don't use the bootstrapper unless you need to. If the user already has a running Kubo node, use that instead of spawning another one.
> **Warning** If the user has their own local Kubo node, connect to that instead of bootstrapping a new one.
## Get a Kubo binary
Before you can use the bootstrapper, you need an `IFile` of the Kubo binary.

If the user is online, [KuboDownloader](KuboDownloader.md) can automatically download and extract the correct Kubo binary for the running operating system and architecture from the IPFS shipyard.
## Getting a Kubo binary
The [KuboDownloader](KuboDownloader.md) automatically downloads and extracts the correct Kubo binary for the running operating system and architecture.

## Basic usage

To fully customize the client and version used by KuboDownloader, see the [KuboDownloader docs](./KuboDownloader.md).

If the binary isn't in the BinaryWorkingFolder, it will be retrieved using the file delegate provided in the constructor. If no delegate is provided, the latest version will be retrieved via Http.

#### Get latest version
```cs
IFile kuboBinary = await GetKuboBinary();
var httpClient = new HttpClient();
var ipfsClient = new IpfsClient { ApiUri = new Uri(...) };

// Create a new boostrapper
var bootstrapper = new KuboBootstrapper(kuboBinary, repoPath);
// Setup bootstrapper.
// Latest binary, downloaded via default HttpClient.
using var bootstrapper = new KuboBootstrapper(repoPath);

// Latest binary, downloaded via custom HttpClient.
using var bootstrapper = new KuboBootstrapper(repoPath, cancel => KuboDownloader.GetLatestBinaryAsync(httpClient, cancel));

// Latest binary, downloaded via custom IpfsClient.
using var bootstrapper = new KuboBootstrapper(repoPath, cancel => KuboDownloader.GetLatestBinaryAsync(ipfsClient, cancel));

// Start the boostrapper. Once this task finishes, the API and Gateway will be ready for use.
await bootstrapper.StartAsync();
```

// Dispose of the bootstrapper to kill the process and clean up.
bootstrapper.Dispose();
#### Get specific version
```cs
var httpClient = new HttpClient();
var ipfsClient = new IpfsClient { ApiUri = new Uri(...) };

// Setup bootstrapper.
// v0.15.0 binary, downloaded via default HttpClient
using var bootstrapper = new KuboBootstrapper(repoPath, cancel => KuboDownloader.GetBinaryVersionAsync(Version.Parse("0.15.0"), cancel));

// v0.15.0 binary, downloaded via default HttpClient
using var bootstrapper = new KuboBootstrapper(repoPath, Version.Parse("0.15.0"));

// v0.15.0 binary, downloaded via custom HttpClient
using var bootstrapper = new KuboBootstrapper(repoPath, cancel => KuboDownloader.GetBinaryVersionAsync(httpClient, new Version(0, 15, 0), cancel));

// v0.15.0 binary, downloaded via custom IpfsClient
using var bootstrapper = new KuboBootstrapper(repoPath, cancel => KuboDownloader.GetBinaryVersionAsync(ipfsClient, new Version(0, 15, 0), cancel));
```

## Additional options
To make it easy to give users control over their node, we've exposed several options for the bootstrapper.
```cs
IFile kuboBinary = await GetKuboBinary();

// Create a new boostrapper
var bootstrapper = new KuboBootstrapper(kuboBinary, repoPath)
// Create a new bootstrapper. Remember to dispose when finished.
using var bootstrapper = new KuboBootstrapper(repoPath)
{
ApiUri = new Uri("http://127.0.0.1:7700"),
GatewayUri = new Uri("http://127.0.0.1:8081"),
Expand All @@ -44,21 +71,19 @@ var bootstrapper = new KuboBootstrapper(kuboBinary, repoPath)

// Start the boostrapper. Once this task finishes, the API and Gateway will be ready for use.
await bootstrapper.StartAsync();

// Dispose of the bootstrapper to kill the process and clean up.
bootstrapper.Dispose();
```

## Start the IpfsClient
Now that you have a running node, you can start using Kubo by passing the API url to a new `IpfsClient`.

```cs
// Start the binary
var bootstrapper = new KuboBootstrapper(kuboBinary, repoPath);

// Start the binary
await bootstrapper.StartAsync();

// Create a client
var ipfsClient = new IpfsClient(bootstrapper.ApiUri.ToString());
var ipfsClient = new IpfsClient { ApiUri = bootstrapper.ApiUri }

// Start using it
var ipnsFile = new IpnsFile("/ipns/ipfs.tech/index.html", ipfsClient);
Expand Down
63 changes: 43 additions & 20 deletions docs/KuboDownloader.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,63 @@ Works on Windows, Linux, MacOS and FreeBSD (with .NET 5+)

Works on x64, x86, ARM and ARM64

## Download latest version
## Basic usage
#### Get latest version
```cs
var downloader = new KuboDownloader();
var httpClient = new HttpClient();
var ipfsClient = new IpfsClient { ApiUri = new Uri(...) };

IFile latestKuboBinary = await downloader.DownloadLatestBinaryAsync();
// Latest binary, downloaded via default HttpClient
IFile latestKuboBinary = await KuboDownloader.GetLatestBinaryAsync();

// Latest binary, downloaded via custom HttpClient
IFile latestKuboBinary = await KuboDownloader.GetLatestBinaryAsync(httpClient);

// Latest binary, downloaded via custom IpfsClient
IFile latestKuboBinary = await KuboDownloader.GetLatestBinaryAsync(ipfsClient);
```
## Download a specific version

#### Get specific version
```cs
var downloader = new KuboDownloader();
var httpClient = new HttpClient();
var ipfsClient = new IpfsClient { ApiUri = new Uri(...) };

// v0.15.0 binary, downloaded via default HttpClient
IFile kuboBinary = await KuboDownloader.GetBinaryVersionAsync(Version.Parse("0.15.0"));

IFile kuboBinary = await downloader.DownloadBinaryAsync(Version.Parse("0.15.0"));
// v0.15.0 binary, downloaded via custom HttpClient
IFile kuboBinary = await KuboDownloader.GetBinaryVersionAsync(httpClient, new Version(0, 15, 0));

// v0.15.0 binary, downloaded via custom IpfsClient
IFile kuboBinary = await KuboDownloader.GetBinaryVersionAsync(ipfsClient, new Version(0, 15, 0));
```

## Save the downloaded binary
Once you have the binary downloaded, save it somewhere so you don't need to redownload every time.
## Using the binary

The `IFile` you're given is created by crawling the contents of the compressed archive directly from Http or Ipfs, and is not saved on disk. The stream supports reading and seeking, with lazy-loading of the underlying stream.

You can treat this `IFile` like any other file in OwlCore.Storage, whether copying it to another location (local, cloud, etc) or providing it to other tooling.

#### Bootstrap Kubo

This helper can be combined with the `KuboBootstrapper` to automatically download the binary, only when needed. It requires no additional copying or setup.

To learn how to use the bootstrapper, [see the docs](./KuboBootstrapper.md).

#### Save or copy the binary file.

The returned object is an `IFile`, which can be saved or copied as needed.

```cs
// Copy the binary to a known location.
// Any modifiable folder can be used, even if it's not on local disk!
// The returned file can be copied to any modifiable folder, if needed.
IModifiableFolder destination = new SystemFolder("/some/path");

var copiedFile = await destination.CreateCopyOfAsync(kuboBinary);
```

## Retrieve the saved binary
The recommended approach is to save the file ID, and provide it to `GetItemAsync()` in the folder that you copied the binary to:
#### Retrieve the copied binary after restart
The Id of a file or folder is contractually guaranteed to be unique within that filesystem (while Name may not be).

Given this, simply save the `copiedFile.Id` string. After a restart, provide it to `GetItemAsync()` or `GetItemRecursiveAsync` on the destination folder to retrieve it again.
```cs
var kuboBinary = await destination.GetItemAsync(copiedFileId);
```
This will work for all storage implementations, with maximum performance when the fast path supported by the storage implementor.


## Use the binary

To start the downloaded binary in your app, see [KuboBootstrapper](KuboBootstrapper.md).
Loading

0 comments on commit 03ac7f4

Please sign in to comment.