Skip to content

Commit

Permalink
devnet release
Browse files Browse the repository at this point in the history
  • Loading branch information
hussein-aitlahcen committed Jan 5, 2022
1 parent 40c44c1 commit c89f486
Show file tree
Hide file tree
Showing 9 changed files with 5,673 additions and 0 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/devnet-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: "Devnet Community Release"

on:
push:
branches:
- nix-devnet

jobs:
deploy-devnet:
runs-on:
- ubuntu-latest
concurrency:
group: deploy-devnet
cancel-in-progress: false
steps:
- uses: actions/checkout@v2

- uses: google-github-actions/setup-gcloud@master
with:
service_account_key: ${{ secrets.GCP_CREDENTIALS }}
export_default_credentials: true

- uses: actions/setup-python@v2

- uses: cachix/install-nix-action@v16
with:
nix_path: nixpkgs=channel:nixos-unstable

- uses: cachix/cachix-action@v10
with:
name: composable-community
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
extraPullNames: composable-community

- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly-2021-11-30
override: true

- uses: Swatinem/rust-cache@v1

- name: Install wasm
run: |
rustup target add wasm32-unknown-unknown
- name: Set env
run: |
echo "RELEASE_VERSION=$GITHUB_SHA" >> $GITHUB_ENV
- name: Push artifact
run: |
cargo build --release -p composable -p picasso-runtime --features=develop
tar -czvf composable-picasso-${{ env.RELEASE_VERSION }}.tar.gz target/release/composable
gsutil mv *.tar.gz gs://composable-binaries/community-releases/picasso/
- name: Load state
run: |
cd nix
echo $(cat devnet.json | jq --arg version "${{ env.RELEASE_VERSION }}" '.composable.version = $version' | jq --arg hash "$(nix-prefetch-url https://storage.googleapis.com/composable-binaries/community-releases/picasso/composable-picasso-${{ env.RELEASE_VERSION }}.tar.gz)" '.composable.hash = $hash') > devnet.json
jq --null-input --arg client_email "$GCP_DEVNET_SERVICE_ACCOUNT" --arg project_id "$GCP_PROJECT_ID" --arg key "\"$GCP_DEVNET_SERVICE_ACCOUNT_KEY\"" '{ "project_id": $project_id, "private_key": ($key | fromjson), "client_email": $client_email }' > ops.json
if gsutil -q stat $NIXOPS_STATE_URL/$NIXOPS_STATE;
then
gsutil cp $NIXOPS_STATE_URL/$NIXOPS_STATE $NIXOPS_STATE
else
nix develop .#deploy --impure --command nixops create -d devnet-gce
fi
env:
NIXOPS_STATE_URL: "gs://composable-state"
NIXOPS_STATE: "deployment.nixops"
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
GCP_DEVNET_SERVICE_ACCOUNT: ${{ secrets.GCP_DEVNET_SERVICE_ACCOUNT }}
GCP_DEVNET_SERVICE_ACCOUNT_KEY: ${{ secrets.GCP_DEVNET_SERVICE_ACCOUNT_KEY }}

- name: Deploy
run: |
cd nix
nix develop .#deploy --impure --command nixops deploy --check --confirm -d devnet-gce
env:
NIXOPS_STATE: "deployment.nixops"

- name: Store state
if: always()
run: |
cd nix
gsutil cp $NIXOPS_STATE $NIXOPS_STATE_URL/
env:
NIXOPS_STATE: "deployment.nixops"
NIXOPS_STATE_URL: "gs://composable-state"

1 change: 1 addition & 0 deletions nix/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ops.json
17 changes: 17 additions & 0 deletions nix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Install Nix + Flakes

1. https://nixos.org/download.html
2. https://nixos.wiki/wiki/Flakes

# Run locally

1. `nix develop`
2. `launch-devnet`
3. Reach alice at `https://polkadot.js.org/apps/?rpc=ws://localhost:9944#/explorer`

# Deploy to GCE

1. Download your GCE service account key and save it as `ops.json`
2. `nix develop .#deploy`
3. `nixops create -d devnet-gce`
4. `nixops deploy -d devnet-gce`
109 changes: 109 additions & 0 deletions nix/devnet-gce.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{ composable,
polkadot,
credentials,
localtunnel,
}:
let
gcefy-version = version:
builtins.replaceStrings [ "." ] [ "-" ] version;
domain = "${composable.name}-${composable.spec}-${gcefy-version composable.version}";
domain-latest = "${composable.name}-${composable.spec}-latest";
in {
resources.gceNetworks.composable-devnet = credentials // {
name = "composable-devnet-network";
firewall = {
allow-http = {
targetTags = [ "http" ];
allowed.tcp = [ 80 ];
};
allow-https = {
targetTags = [ "https" ];
allowed.tcp = [ 443 ];
};
};
};
devnet-machine = { pkgs, resources, ... }:
let
devnet = pkgs.callPackage ./devnet.nix {
inherit composable;
inherit polkadot;
};
in {
deployment = {
targetEnv = "gce";
gce = credentials // {
machineName = "composable-devnet";
network = resources.gceNetworks.composable-devnet;
region = "europe-central2-c";
instanceType = "n2-standard-4";
rootDiskSize = 50;
tags = [
"http"
"https"
];
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
systemd.services.composable-devnet = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Composable Devnet";
serviceConfig = {
Type = "simple";
User = "root";
ExecStart = "${devnet}/bin/launch-devnet";
Restart = "always";
RuntimeMaxSec = "86400"; # 1 day lease period for rococo, restart it
};
};
systemd.services.localtunnel-commit = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Local Tunnel Server";
serviceConfig = {
Type = "simple";
User = "root";
Restart = "always";
ExecStart = "${localtunnel}/bin/lt --port 80 --subdomain ${domain}";
};
};
systemd.services.localtunnel-latest = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Local Tunnel Server";
serviceConfig = {
Type = "simple";
User = "root";
Restart = "always";
ExecStart = "${localtunnel}/bin/lt --port 80 --subdomain ${domain-latest}";
};
};
services.nginx =
let virtualConfig =
let
routify-nodes = prefix:
map (node: (node // {
name = prefix + node.name;
}));
routified-composable-nodes =
routify-nodes "parachain/" composable.nodes;
routified-polkadot-nodes =
routify-nodes "relaychain/" polkadot.nodes;
routified-nodes =
routified-composable-nodes ++ routified-polkadot-nodes;
in
{
locations = builtins.foldl' (x: y: x // y) {} (map (node: {
"/${node.name}" = {
proxyPass = "http://127.0.0.1:${builtins.toString node.wsPort}";
proxyWebsockets = true;
};
}) routified-nodes);
};
in {
enable = true;
virtualHosts."${domain}.loca.lt" = virtualConfig;
virtualHosts."${domain-latest}.loca.lt" = virtualConfig;
};
};
}
13 changes: 13 additions & 0 deletions nix/devnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"composable": {
"name": "picasso",
"version": "1.1.4",
"spec": "picasso-dev",
"hash": "sha256:0lh8v5m9nmyffgrqxpp2a395ia2m4ly91m8cnnkabx9kx868fx0r"
},
"polkadot": {
"version": "0.9.13",
"spec": "rococo-local",
"hash": "sha256:1iwhb1sgi8yk1nmmix7jr8rzjdl9kh50jx8s8a2fllzpllbbwdkw"
}
}
124 changes: 124 additions & 0 deletions nix/devnet.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{ pkgs,
fetchFromGitHub,
fetchurl,
composable,
polkadot,
}:
let
polkalaunch = pkgs.callPackage (pkgs.stdenv.mkDerivation {
name = "polkadot-launch";
version = "1.0.0";
src = fetchFromGitHub {
owner = "paritytech";
repo = "polkadot-launch";
rev = "99c395b9e7dc7468a4b755440d67e317370974c4";
hash = "sha256:0is74ad9khbqivnnqfarm8012jvbpg5mcs2p9gl9bz1p7sz1f97d";
};
patches = [ ./polkadot-launch.patch ];
installPhase = ''
mkdir $out
cp -r * $out
'';
}) {};

polkadot-bin = pkgs.stdenv.mkDerivation {
name = "polkadot-${polkadot.version}";
version = polkadot.version;
src = fetchurl {
url = "https://github.com/paritytech/polkadot/releases/download/v${polkadot.version}/polkadot";
sha256 = polkadot.hash;
};
nativeBuildInputs = [
pkgs.autoPatchelfHook
];
buildInputs = [ pkgs.stdenv.cc.cc ];
dontUnpack = true;
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/polkadot
chmod +x $out/bin/polkadot
'';
};

composable-bin = pkgs.stdenv.mkDerivation rec {
name = "composable-${composable.name}-${composable.version}";
version = composable.version;
src = fetchurl {
url = "https://storage.googleapis.com/composable-binaries/community-releases/${composable.name}/${name}.tar.gz";
sha256 = composable.hash;
};
nativeBuildInputs = [
pkgs.autoPatchelfHook
];
buildInputs = [ pkgs.stdenv.cc.cc pkgs.zlib ];
installPhase = ''
tar -xvf $src
mkdir -p $out/bin
mv release/composable $out/bin
'';
};

make-node = tmp-directory: node-type: { name, wsPort, port }: {
inherit name;
inherit wsPort;
inherit port;
basePath = "${tmp-directory}/${node-type}/${name}";
};

make-polkalaunch-config =
{ tmp-directory, relaychain-spec, relaychain-bin, parachain-spec, parachain-bin }: {
relaychain = {
bin = relaychain-bin;
chain = relaychain-spec;
nodes = map (make-node tmp-directory "relaychain") polkadot.nodes;
genesis = {
runtime = {
runtime_genesis_config = {
configuration = {
config = {
validation_upgrade_frequency = 1;
validation_upgrade_delay = 1;
};
};
};
};
};
};
parachains = [
{
bin = parachain-bin;
balance = "1000000000000000000000";
chain = parachain-spec;
nodes =
map (node:
(make-node tmp-directory "parachain" node) // {
flags = ["--" "--execution=wasm"];
}) composable.nodes;
}
];
types = {};
finalization = false;
simpleParachains = [];
};

tmp-directory = "/tmp/polkadot-launch";

devnet-config =
pkgs.writeTextFile {
name = "devnet.json";
text = builtins.toJSON (
make-polkalaunch-config
{ inherit tmp-directory;
relaychain-spec = polkadot.spec;
relaychain-bin = "${polkadot-bin}/bin/polkadot";
parachain-spec = composable.spec;
parachain-bin = "${composable-bin}/bin/composable";
}
);
};
in
pkgs.writeScriptBin "launch-devnet" ''
#!${pkgs.bash}/bin/bash -e
rm -rf ${tmp-directory}
${polkalaunch}/bin/polkadot-launch ${devnet-config}
''
Loading

0 comments on commit c89f486

Please sign in to comment.