0.1.10 • Published 4 months ago

@taubyte/spore-drive v0.1.10

Weekly downloads
-
License
BSD-3-Clause
Repository
-
Last release
4 months ago

@taubyte/spore-drive

Gone are the days of relying on third parties to build and maintain cloud infrastructure for your software. spore-drive empowers you to deploy, scale, and manage your Tau cloud infrastructure with code!

Installation

npm

npm install @taubyte/spore-drive

yarn

yarn add @taubyte/spore-drive

Example Usage

Load Configuration

Create a new configuration in memory:

import { Config } from "@taubyte/spore-drive";

const config = new Config();
await config.init();

Alternatively, load a configuration from a source, such as the local file system:

const config = new Config(`/absolute/path/to/config`);
await config.init();

Define Cloud Infrastructure

You can define your cloud infrastructure as follows:

await config.cloud.set({
  domain: {
    root: "test.com",
    generated: "gtest.com",
  },
});
await config.cloud.domain.validation.generate();
await config.cloud.p2p.swarm.generate();

Or for more granular control:

await config.cloud.domain.root.set("test.com");
await config.cloud.domain.generated.set("gtest.com");
await config.cloud.domain.validation.generate();
await config.cloud.p2p.swarm.generate();

Set Auth Configurations

await config.auth.set({
  main: {
    username: "tau1",
    password: "testtest",
  },
  withkey: {
    username: "tau2",
    key: "/keys/test.pem",
  },
});

Or

const mainAuth = config.auth.signer["main"];
await mainAuth.username.set("tau1");
await mainAuth.password.set("testtest");

const withKeyAuth = config.auth.signer["withkey"];
await withKeyAuth.username.set("tau2");
await withKeyAuth.key.path.set("/keys/test.pem");

Set Shapes Configurations

await config.shapes.set({
  shape1: {
    services: ["auth", "seer"],
    ports: {
      main: 4242,
      lite: 4262,
    },
  },
  shape2: {
    services: ["gateway", "patrick", "monkey"],
    ports: {
      main: 6242,
      lite: 6262,
    },
    plugins: ["plugin1@v0.1"],
  },
});

Or

const shape1 = config.shape["shape1"];
await shape1.services.set(["auth", "seer"]);
await shape1.ports.port["main"].set(4242);
await shape1.ports.port["lite"].set(4262);

Set Hosts

await config.hosts.set({
  host1: {
    addr: ["1.2.3.4/24", "4.3.2.1/24"],
    ssh: {
      addr: "1.2.3.4",
      port: 4242,
      auth: ["main"],
    },
    location: {
      lat: 1.25,
      long: 25.1,
    },
  },
  host2: {
    addr: ["8.2.3.4/24", "4.3.2.8/24"],
    ssh: {
      addr: "8.2.3.4",
      port: 4242,
      auth: ["withkey"],
    },
    location: {
      lat: 1.25,
      long: 25.1,
    },
  },
});

// Generate host instances key/id
await config.host["host1"].shape["shape1"].generate();
await config.host["host1"].shape["shape2"].generate();
await config.host["host2"].shape["shape1"].generate();
await config.host["host2"].shape["shape2"].generate();

Or

const host1 = config.host["host1"];
await host1.addresses.add(["1.2.3.4/24", "4.3.2.1/24"]);
await host1.ssh.address.set("1.2.3.4:4242");
await host1.ssh.auth.add(["main"]);
await host1.location.set("1.25, 25.1");
await host1.shape["shape1"].generate();
await host1.shape["shape2"].generate();

Set P2P Bootstrap

await config.cloud.p2p.set({
  bootstrap: {
    shape1: ["host2", "host1"],
    shape2: ["host2", "host1"],
  },
});

Or

await config.cloud.p2p.bootstrap.shape["shape1"].nodes.add([
  "host2",
  "host1",
]);

Instantiate a Drive

import { Drive, TauLatest } from "@taubyte/spore-drive";

const drive = new Drive(config, TauLatest);
await drive.init();

Plot a Course

const course = await drive.plot(new CourseConfig(["shape1"]));

shape1 is used to select hosts to be deployed to.

Deploy

await course.displace();

console.log("Displacing...");
for await (const progress of await course.progress()) {
    console.log(progress);
}
console.log("Done");

Progress Bars

You can visualize the deployment progress using progress bars:

import { ProgressBar } from "@opentf/cli-pbar";

// Extracts the host from the given path
function extractHost(path: string): string {
  const match = path.match(/\/([^\/]+):\d+/);
  return match ? match[1] : "unknown-host";
}

// Extracts the task from the given path
function extractTask(path: string): string {
  const parts = path.split("/");
  return parts[parts.length - 1] || "unknown-task";
}

async function displayProgress(course: Course) {
  const multiPBar = new ProgressBar({ size: "SMALL" });
  multiPBar.start();
  const taskBars: Record<string, any> = {};
  const errors: { host: string; task: string; error: string }[] = [];

  for await (const displacement of await course.progress()) {
    const host = extractHost(displacement.path);
    const task = extractTask(displacement.path);

    if (!taskBars[host]) {
      taskBars[host] = multiPBar.add({
        prefix: host,
        suffix: "...",
        total: 100,
      });
    }

    taskBars[host].update({ value: displacement.progress, suffix: task });

    if (displacement.error) {
      errors.push({ host, task, error: displacement.error });
    }
  }

  for (const host in taskBars) {
    const errorForHost = errors.find((err) => err.host === host);

    if (errorForHost) {
      taskBars[host].update({ value: 100, color: "r", suffix: "failed" });
    } else {
      taskBars[host].update({ value: 100, suffix: "successful" });
    }
  }

  multiPBar.stop();

  if (errors.length > 0) {
    console.log("\nErrors encountered:");
    errors.forEach((err) => {
      console.log(`Host: ${err.host}, Task: ${err.task}, Error: ${err.error}`);
    });
  }
}
0.1.10

4 months ago

0.1.8

4 months ago

0.1.9

4 months ago

0.1.7

6 months ago

0.1.6

7 months ago

0.1.5

7 months ago

0.1.4

9 months ago

0.1.2

9 months ago

0.1.3

9 months ago

0.1.1

9 months ago

0.1.0

9 months ago