Initial commit

This commit is contained in:
Anatolios Laskaris 2023-07-11 14:45:36 +03:00 committed by Anatoly Laskaris
commit aa78e6a078
22 changed files with 11322 additions and 0 deletions

View File

@ -0,0 +1 @@
node_modules

19
.github/actions/get-versions/action.yml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Get versions
description: |
Combine all dependencies from fluencelabs/cli version.json, package-lock.json and local versions.json
runs:
using: "node16"
main: "dist/index.js"
outputs:
versions:
description: "Merged versions.json file"
npm:
description: "List of npm packages"
nox:
description: "Nox version"
cli_tag:
description: "fluencelabs/cli repo tag"
cli_version:
description: "CLI version"

9733
.github/actions/get-versions/dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

86
.github/actions/get-versions/index.js vendored Normal file
View File

@ -0,0 +1,86 @@
const core = require("@actions/core");
const { Octokit } = require("@octokit/rest");
const fs = require("fs");
async function run() {
try {
const token = process.env.GITHUB_TOKEN;
const octokit = new Octokit({ auth: token });
// Load local versions.json file
const file = JSON.parse(fs.readFileSync("versions.json", "utf8"));
const cliVersion = file.cli.split("@")[2]; // Extract CLI version
// Get the package.json content from the fluencelabs/cli repository
const packageRes = await octokit.repos.getContent({
owner: "fluencelabs",
repo: "cli",
path: "package.json",
ref: `fluence-cli-v${cliVersion}`,
});
const packageContent = Buffer.from(packageRes.data.content, "base64")
.toString();
const packageJson = JSON.parse(packageContent);
// Filter only the direct dependencies starting with '@fluencelabs'
const filteredPackageJsonDependencies = {};
for (const dep in packageJson.dependencies) {
if (dep.startsWith("@fluencelabs")) {
filteredPackageJsonDependencies[dep] = packageJson.dependencies[dep];
}
}
// Get the src/versions.json content from the fluencelabs/cli repository
const versionsRes = await octokit.repos.getContent({
owner: "fluencelabs",
repo: "cli",
path: "src/versions.json",
ref: `fluence-cli-v${cliVersion}`,
});
const versions = JSON.parse(
Buffer.from(versionsRes.data.content, "base64").toString(),
);
// Merge dependencies from versions.json and package-lock.json
const mergedNpmDependencies = {
...versions.npm,
...filteredPackageJsonDependencies,
};
versions.npm = mergedNpmDependencies;
// Add 'nox' from local file
versions.nox = file.nox;
versions.redis = file.redis;
console.log(JSON.stringify(versions, null, 2));
core.setOutput("versions", JSON.stringify(versions));
// Add 'nox' output
const regex = /:(?:[a-zA-Z_]+_)?(\d+\.\d+\.\d+)$/;
const match = versions.nox.match(regex);
if (match) {
const noxVersion = match[1];
console.log(`nox version is set to ${noxVersion}`);
core.setOutput("nox", noxVersion);
} else {
core.setFailed("Couldn't get nox version.");
}
// Add 'cli' outputs
core.setOutput("cli_tag", `fluence-cli-v${cliVersion}`);
core.setOutput("cli_version", cliVersion);
// Add npm packages as list for CI matrix
const npmPackages = [];
for (const [name, version] of Object.entries(versions.npm)) {
npmPackages.push({ name, version: version.replace(/^\^/, "") });
}
core.setOutput("npm", JSON.stringify(npmPackages));
} catch (error) {
core.setFailed(error.message);
}
}
run();

273
.github/actions/get-versions/package-lock.json generated vendored Normal file
View File

@ -0,0 +1,273 @@
{
"name": "get-versions",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "get-versions",
"version": "1.0.0",
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.10.0",
"@octokit/rest": "^18.0.0",
"js-yaml": "^4.1.0"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1"
}
},
"node_modules/@actions/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/http-client": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"dependencies": {
"@octokit/types": "^6.40.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
}
},
"node_modules/@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"dependencies": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
},
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"node_modules/@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"dependencies": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"node_modules/@octokit/types": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"dependencies": {
"@octokit/openapi-types": "^12.11.0"
}
},
"node_modules/@vercel/ncc": {
"version": "0.36.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz",
"integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==",
"dev": true,
"bin": {
"ncc": "dist/ncc/cli.js"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
}
}

View File

@ -0,0 +1,17 @@
{
"name": "get-versions",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "ncc build index.js"
},
"author": "Fluence Labs",
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.10.0",
"@octokit/rest": "^18.0.0"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1"
}
}

8
.github/release-please/config.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"release-type": "simple",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"packages": {
".": {}
}
}

3
.github/release-please/manifest.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
".": "0.0.0"
}

260
.github/workflows/deploy.yml vendored Normal file
View File

@ -0,0 +1,260 @@
name: deploy
on:
workflow_call:
inputs:
env:
description: "env to deploy to"
type: string
required: true
ref:
description: "git ref to deploy from"
type: string
required: false
default: ${{ github.ref }}
workflow_dispatch:
inputs:
env:
description: "env to deploy to"
type: string
required: true
concurrency:
group: "${{ inputs.env }}"
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: ${{ inputs.env }}
url: "https://github.com/fluencelabs/fluence/tree/${{ github.sha }}"
defaults:
run:
working-directory: "deployment"
env:
NOMAD_JOB: nox
NOMAD_NAMESPACE: fluence
NOMAD_REGION: ${{ vars.ENV }}
TF_VAR_replicas: ${{ vars.REPLICAS }}
outputs:
NOMAD_REGION: ${{ vars.ENV }}
TF_VAR_replicas: ${{ vars.REPLICAS }}
npm: ${{ steps.cli.outputs.npm }}
nox: ${{ steps.cli.outputs.nox }}
cli_version: ${{ steps.cli.outputs.cli_version }}
cli_tag: ${{ steps.cli.outputs.cli_tag }}
permissions:
contents: write
actions: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref || github.ref }}
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
- name: Set nox version
run: echo "TF_VAR_nox=${{ fromJson(steps.versions.outputs.versions)['nox'] }}" >> $GITHUB_ENV
- name: Set cli version
id: cli
run: |
echo "cli_tag=${{ steps.versions.outputs.cli_tag }}" >> $GITHUB_OUTPUT
echo "cli_version=${{ steps.versions.outputs.cli_version }}" >> $GITHUB_OUTPUT
- name: Get vault token
uses: hashicorp/vault-action@v2.7.2
with:
url: "https://vault.fluence.dev"
path: jwt/github
role: fluence
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: true
- name: Setup consul-template
uses: nahsi/setup-hashi-tool@v1
with:
name: consul-template
- name: Prepare secrets
env:
VAULT_ADDR: "https://vault.fluence.dev"
run: |
# prepare secrets
consul-template -once -template "env.tmpl:env"
sleep 10
- name: Source secrets
run: |
while IFS='=' read -r key value; do
if [[ ! -z "$key" ]]; then
echo "::add-mask::$value"
echo "$key=$value" >> $GITHUB_ENV
fi
done < "env"
- name: Setup terraform
uses: hashicorp/setup-terraform@v2
- name: terraform init
id: init
run: terraform init
- name: Terraform create workspace
run: |
terraform workspace select -or-create=true ${{ inputs.env }}
- name: terraform plan
id: plan
run: terraform plan -no-color
- name: Print terraform plan to checks
run: |
cat <<'PLAN' >> $GITHUB_STEP_SUMMARY
## ${{ inputs.env }} plan
```
${{ steps.plan.outputs.stdout }}
```
PLAN
- name: terraform apply
run: terraform apply -auto-approve
- name: Setup nomad
uses: nahsi/setup-hashi-tool@v1
with:
name: nomad
- name: nomad job status
run: |
sleep 10
nomad job status -verbose ${NOMAD_JOB}
cat << STATUS > $GITHUB_STEP_SUMMARY
## ${{ inputs.env }} status
\`\`\`
$(nomad job status -verbose ${NOMAD_JOB})
\`\`\`
STATUS
# cli:
# needs:
# - deploy
# uses: fluencelabs/cli/.github/workflows/tests.yml@main
# with:
# fluence-env: ${{ inputs.env }}
# ref: ${{ needs.deploy.outputs.cli_tag }}
promote:
needs:
- deploy
uses: ./.github/workflows/promote.yml
with:
ref: ${{ inputs.ref || github.ref }}
env: ${{ inputs.env }}
revert:
if: failure()
runs-on: ubuntu-latest
needs:
- deploy
- cli
defaults:
run:
working-directory: "deployment"
env:
NOMAD_JOB: nox
NOMAD_NAMESPACE: fluence
NOMAD_REGION: ${{ needs.deploy.outputs.NOMAD_REGION }}
TF_VAR_replicas: ${{ needs.deploy.outputs.REPLICAS }}
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.env }}
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
- name: Set nox version
run: echo "TF_VAR_redis=${{ fromJson(steps.versions.outputs.versions)['redis'] }}" >> $GITHUB_ENV
- name: Get vault token
uses: hashicorp/vault-action@v2.7.2
with:
url: "https://vault.fluence.dev"
path: jwt/github
role: fluence
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: true
secrets: |
kv/github/tokens/fluencebot token | FLUENCEBOT_TOKEN
- name: Setup consul-template
uses: nahsi/setup-hashi-tool@v1
with:
name: consul-template
- name: Prepare secrets
env:
VAULT_ADDR: "https://vault.fluence.dev"
run: |
# prepare secrets
consul-template -once -template "env.tmpl:env"
sleep 10
- name: Source secrets
run: |
while IFS='=' read -r key value; do
if [[ ! -z "$key" ]]; then
echo "::add-mask::$value"
echo "$key=$value" >> $GITHUB_ENV
fi
done < "env"
- name: Setup terraform
uses: hashicorp/setup-terraform@v2
- name: terraform init
id: init
run: terraform init
- name: Terraform create workspace
run: |
terraform workspace select -or-create=true ${{ inputs.env }}
- name: terraform apply
run: terraform apply -auto-approve
- name: Setup nomad
uses: nahsi/setup-hashi-tool@v1
with:
name: nomad
- name: nomad job status
run: |
sleep 10
nomad job status -verbose ${NOMAD_JOB}

161
.github/workflows/promote.yml vendored Normal file
View File

@ -0,0 +1,161 @@
name: Promote packages
on:
workflow_call:
inputs:
ref:
description: "Git ref to checkout to"
type: string
required: true
env:
description: "Name of the channel/env to promote"
type: string
required: true
env:
CI: true
FORCE_COLOR: true
jobs:
tag:
name: "Tag commit"
runs-on: ubuntu-latest
outputs:
cli_version: ${{ steps.versions.outputs.cli_version }}
cli_tag: ${{ steps.versions.outputs.cli_tag }}
nox: ${{ steps.versions.outputs.nox }}
npm: ${{ steps.versions.outputs.npm }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref }}
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
- name: Tag commit
uses: rickstaa/action-create-tag@v1
with:
tag: ${{ inputs.env }}
force_push_tag: true
cli:
name: "Promote cli"
runs-on: ubuntu-latest
needs: tag
permissions:
contents: read
id-token: write
steps:
- name: Checkout cli repo
uses: actions/checkout@v3
with:
repository: fluencelabs/cli
ref: ${{ needs.tag.outputs.cli_tag }}
- name: Import secrets
uses: hashicorp/vault-action@v2.7.3
with:
url: https://vault.fluence.dev
path: jwt/github
role: ci
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: false
secrets: |
kv/ci/fcli-binaries id | AWS_ACCESS_KEY_ID ;
kv/ci/fcli-binaries secret | AWS_SECRET_ACCESS_KEY
- name: Promote cli
run: |
yarn oclif promote \
-t linux-x64,darwin-x64,darwin-arm64 \
--version ${{ needs.tag.outputs.cli_version }} \
--sha "$(git rev-parse --short HEAD)" \
--channel ${{ inputs.env }} --no-xz
npm:
runs-on: ubuntu-latest
name: "Tag npm packages"
needs: tag
permissions:
contents: read
id-token: write
steps:
- name: Import secrets
uses: hashicorp/vault-action@v2.7.3
with:
url: https://vault.fluence.dev
path: jwt/github
role: ci
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: false
secrets: |
kv/npmjs/fluencebot token | NODE_AUTH_TOKEN
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: "18"
registry-url: "https://registry.npmjs.org"
- name: Tag npm packages
run: |
# Tag npm packages
while read -r package version; do
echo "Promoting ${package}@${version} to ${{ inputs.env }}"
npm dist-tag add ${package}@${version} ${{ inputs.env }}
done < <(echo '${{ needs.tag.outputs.npm }}' | jq -r '.[] | "\(.name) \(.version)"')
- name: Tag fluence cli
run: |
# Tag fluence cli
echo "Tagging @fluencelabs/cli@${{ needs.tag.outputs.cli_version }} as ${{ inputs.env }}"
npm dist-tag add @fluencelabs/cli@${{ needs.tag.outputs.cli_version }} ${{ inputs.env }}
docker:
runs-on: ubuntu-latest
name: "Tag nox container"
needs: tag
permissions:
contents: read
id-token: write
steps:
- name: Import secrets
uses: hashicorp/vault-action@v2.7.3
with:
url: https://vault.fluence.dev
path: jwt/github
role: ci
method: jwt
jwtGithubAudience: "https://github.com/fluencelabs"
jwtTtl: 300
exportToken: false
secrets: |
kv/hub.docker.com/fluencebot username | DOCKER_USERNAME ;
kv/hub.docker.com/fluencebot password | DOCKER_PASSWORD
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Retag image
uses: akhilerm/tag-push-action@v2.1.0
with:
src: docker.io/fluencelabs/nox:${{ needs.tag.outputs.nox }}
dst: docker.io/fluencelabs/nox:${{ inputs.env }}

57
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: "release-please"
on:
push:
branches:
- "main"
jobs:
release-please:
runs-on: ubuntu-latest
concurrency:
group: "release-please"
outputs:
release-created: ${{ steps.release.outputs['release_created'] }}
tag-name: ${{ steps.release.outputs['tag_name'] }}
version: ${{ steps.release.outputs['version'] }}
pr: ${{ steps.release.outputs['pr'] }}
steps:
- name: Run release-please
id: release
uses: google-github-actions/release-please-action@v3
with:
token: ${{ secrets.FLUENCEBOT_RELEASE_PLEASE_PAT }}
command: manifest
config-file: .github/release-please/config.json
manifest-file: .github/release-please/manifest.json
- name: Show output from release-please
if: steps.release.outputs.releases_created
env:
RELEASE_PLEASE_OUTPUT: ${{ toJSON(steps.release.outputs) }}
run: echo "${RELEASE_PLEASE_OUTPUT}" | jq
stage:
needs: release-please
uses: ./.github/workflows/deploy.yml
with:
env: stage
testnet:
if: needs.release-please.outputs.release-created
needs: release-please
uses: ./.github/workflows/deploy.yml
with:
env: testnet
ref: ${{ needs.release-please.outputs.tag_name }}
kras:
if: needs.release-please.outputs.release-created
needs: release-please
uses: ./.github/workflows/deploy.yml
with:
env: kras
ref: ${{ needs.release-please.outputs.tag_name }}

41
.github/workflows/test.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: "test"
on:
pull_request:
paths:
- "!**.md"
- "deployment/**"
- "versions.json"
- ".github/workflows/test.yml"
types:
- "labeled"
- "synchronize"
- "opened"
- "reopened"
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
versions:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.versions.outputs.versions }}
cli_tag: ${{ steps.versions.outputs.cli_tag }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
cli:
needs: versions
uses: fluencelabs/cli/.github/workflows/tests.yml@main
with:
nox-image: "${{ fromJson(needs.versions.outputs.versions)['nox'] }}"
ref: "${{ needs.versions.outputs.cli_tag }}"

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# Carousel
Continuous Delivery
README coming soon!

2
deployment/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
env
.terraform

106
deployment/.terraform.lock.hcl generated Normal file
View File

@ -0,0 +1,106 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/cloudflare/cloudflare" {
version = "3.35.0"
constraints = "~> 3.0"
hashes = [
"h1:SFvdgX5bTGhOTMhywgjSOWlkET2el7STxdUSzxjz2pc=",
"zh:13aabc00fee823422831bcc870227650cc765fc4c9622074d24d6d62a4ac0e37",
"zh:1544405f0ea6b388dad7eb25c434427b2682417396da9186e1b33551e6b4adff",
"zh:5d58394cb8e71bd4bf6ef0135f1ca6a4ad2cec937f3731b224125eb34ee059f7",
"zh:648596ed545ed01ae757d5a0b37c20e8050cfb51d42e9a2c82fcc94d883ff11d",
"zh:68d75e14eef4f073faa975ed6baf4db7e0e1f2fc61a4e54fd95325df42793810",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:9916cc626fef57428c4c60db7897b34068c65639b68482e94f62d97d773d64bc",
"zh:9c8c9f369eb30e7360a0ebd7918e4846ca4d5bca430b861fdbde7522a3146459",
"zh:a40e244688bbcb6f1a771e6ea89fb0b0b7bb53be3fab718abc66b3593e0f8133",
"zh:cc5a6191aa8713275550ff2b6adda6e6d56e4780c9cbe3d1da1dc23ea893bfff",
"zh:d1dd435780e8c7e79bff26b46a76df0e123971849355ad17877d1e24dc5953c3",
"zh:d751fc72f2833f2bdb897fa89de2bb5b6efbad1e648896642f0e6fe5cde789c8",
"zh:dfc4c90b3605ec1bb7cc7a9f1fb1b67235578bdd6b9be78e7b3516b55d0422db",
"zh:e6101a80fe24e2df3ab60152458ff1666a4a1befc87c62e459a219cdbb53e6df",
"zh:e9bcf26c44dd231f74703b6a6717470021a3ba7e1d7531dcf7287a6441300e27",
]
}
provider "registry.terraform.io/digitalocean/digitalocean" {
version = "2.30.0"
constraints = "~> 2.0"
hashes = [
"h1:JkssHSfr8910VvwMd8HaiT6QHxB9H3R2epkqD/62dWY=",
"zh:0a6f0d7ac89c6f1835df9f8dc4464eb42893449a4d4f3a9e832472a3e4184c03",
"zh:299b78108f01f3ddcc35424ed20b79a810610612e3ee13958d7cd45a16d53628",
"zh:2dfcc11c79f058f76aa0545f842dede804cdc1cd40f48c3573312b7f93882923",
"zh:33271b4d8c75cef65b7f3d2bc3afbaa412849cea49593715806b25a9ffc8d03e",
"zh:448de7e2d46c4619cb98921c70b6a35a91256329457d27023a813c01635dfe65",
"zh:53bc104ae2bacbcaa5b0a4ce2caf06c1ac942c6114f2b5a12869d020c7580cc6",
"zh:54ee5aafe43b12b87901036d13fc399f511d4f5f6fef784a07a695bdeed300f1",
"zh:563ac07ff6d3379d23749e930007179a63e3b13317b214db5b8faf43fef21aea",
"zh:8f6a53f53b880f20e1f3953727c91888bf06aad5ba28dba9a69621b042cf2eb0",
"zh:9089f77da041e64e112e3efe2c013d7cb032362544724a672579919471a78571",
"zh:951fa4e16d05bb3e717a1f3ac0b91487eb554088fc0f96e188586e729a925d3b",
"zh:a287a3fc416a3e8b4794ed89bd24978b5d53ae110091ab7986c609a9e048c847",
"zh:b09ee82f32c819c477117b7692888e7d4b5a403316c3bab3bd55bae1133438b1",
"zh:c00fccb3699abc6277eb7750b0b85d8cd1f0a0f84c41d388e90ef039a830a5ca",
"zh:ce95cfc5e67276f8ded53cf8a5872720f17d1b0a1cbdef844a773d302524adef",
"zh:deb5add87e3040d18bfc111ec82cf61c3ebc1ebea1d594562952058ae061970c",
]
}
provider "registry.terraform.io/hashicorp/consul" {
version = "2.18.0"
hashes = [
"h1:ABHNF3vYoRej5vLiiKR/XYgjhjubsjlVROssc555Vj8=",
"zh:155f6899c8f1e0162169e4d09f426ea9a9738d74129f0ffc54b7570941c49cd4",
"zh:241ba909b387c349845b0371321af45ccbb00290edbe1ea0861ad8732951f718",
"zh:612f52be1fb5dd507b8064c67785313a531faad35873cba53f998f3766473335",
"zh:67fbd695381b9c5db83ffeeaec1bfdbcc477ccb1e9de1caff76a0186d4c85908",
"zh:7f88b151c9690a6addccbffe8484f0257344ef55424a9efb025dfddd052a4dc6",
"zh:8d954f3ffeb72b6c18cc5ae8c3189bb3a8cb66967b2106c7d0163009c12bba15",
"zh:913774c7eabc6e9078a1bd00347cc539b19a6f6b45dacbd21454dffdc9f4ae43",
"zh:9517558883f994649695643a6208079ed0445aaa0ac2dee69f88cb044d21c6c9",
"zh:a0211f596e35bd1b8d4bb9cda321cb1555a427a8d3f6724fe09893168fac9b7e",
"zh:a70eaa0a88f677f901855a4ab908ddcf961e4afaf3a0147b08faaead57b4fe07",
"zh:b02f5cd94ab236d988cfec531c56c199e3087803f1b2908a1a2b6da8a57b3751",
"zh:f3d3efac504c9484a025beb919d22b290aa6dbff256f6e86c1f8ce7817e077e5",
]
}
provider "registry.terraform.io/hashicorp/nomad" {
version = "2.0.0"
hashes = [
"h1:lIHIxA6ZmfyTGL3J9YIddhxlfit4ipSS09BLxkwo6L0=",
"zh:09b897d64db293f9a904a4a0849b11ec1e3fff5c638f734d82ae36d8dc044b72",
"zh:435cc106799290f64078ec24b6c59cb32b33784d609088638ed32c6d12121199",
"zh:7073444bd064e8c4ec115ca7d9d7f030cc56795c0a83c27f6668bba519e6849a",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:79d238c35d650d2d83a439716182da63f3b2767e72e4cbd0b69cb13d9b1aebfc",
"zh:7ef5f49344278fe0bbc5447424e6aa5425ff1821d010d944a444d7fa2c751acf",
"zh:92179091638c8ba03feef371c4361a790190f9955caea1fa59de2055c701a251",
"zh:a8a34398851761368eb8e7c171f24e55efa6e9fdbb5c455f6dec34dc17f631bc",
"zh:b38fd5338625ebace5a4a94cea1a28b11bd91995d834e318f47587cfaf6ec599",
"zh:b71b273a2aca7ad5f1e07c767b25b5a888881ba9ca93b30044ccc39c2937f03c",
"zh:cd14357e520e0f09fb25badfb4f2ee37d7741afdc3ed47c7bcf54c1683772543",
"zh:e05e025f4bb95138c3c8a75c636e97cd7cfd2fc1525b0c8bd097db8c5f02df6e",
]
}
provider "registry.terraform.io/hashicorp/vault" {
version = "3.20.0"
hashes = [
"h1:tAhOQy6jGSu4WTGWpMgUU+o6r6OSErEnfnjp7KhmHu0=",
"zh:233b54a177ee0e1caec685e888686251b4f609378fa3431367ef1edf76aaee69",
"zh:640a44674bf7a1f2177734a30fd435576cb8f6b33089e9203fd43747ecb9413b",
"zh:6e879dc8a4614a9dea75c106768e0130184d751a89f9ecaa9b2af93e17e838aa",
"zh:759f3e4dc20f9bf8d2ed3bfb945564c9f1a7df26922a93bbc6e884a571de65c6",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:7d93c37429da82b7ec26ec7ff92404ec0bb0b9bcc31afaf7e4fcab864aae9997",
"zh:ad476e4a8cdc837b6a2ec75e6b44bff233dcb917f0bf9bd45a148beddaee7fe1",
"zh:c876876c96234c6f18bebdedac85d5ff71f34d897af0f1747a727bc72e5e73d8",
"zh:c9f3e69bddf1db3ad47f9ccd0f3ee25ff06994f476246c77bfcab1f922e5fda7",
"zh:ea611784de08a6f02e7f85c05f770de5d44eefde6251e05758129c2689d9c3e1",
"zh:f88d817b5c26ce28f347943b69c9110eea830f67c1c2b0c36dc424a7fe7887a7",
"zh:faf281cb937125a4152f5afaba52aea7dd4be0bbaf671c30e3d86125080d41e0",
]
}

11
deployment/Config.toml Normal file
View File

@ -0,0 +1,11 @@
autodeploy_particle_ttl = "60s"
builtins_base_dir = "/builtins"
packet_split_size = 16384
[kademlia]
max_packet_size = 10040964096 # 100 Mb
query_timeout = "10s"
connection_idle_timeout = "1h"
peer_fail_threshold = 3
ban_cooldown = "60s"

49
deployment/backend.tf Normal file
View File

@ -0,0 +1,49 @@
terraform {
backend "consul" {
address = "hashi.fluence.dev:8501"
scheme = "https"
path = "terraform/carousel/nox"
}
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 3.0"
}
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
provider "cloudflare" {}
data "cloudflare_zone" "fluence_dev" {
name = "fluence.dev"
}
provider "consul" {
address = "https://hashi.fluence.dev:8501"
datacenter = terraform.workspace
}
provider "nomad" {
address = "https://hashi.fluence.dev:4646"
region = terraform.workspace
}
provider "vault" {
address = "https://hashi.fluence.dev:8200"
}
data "terraform_remote_state" "state" {
backend = "consul"
config = {
address = "hashi.fluence.dev:8501"
scheme = "https"
path = "terraform/${terraform.workspace}"
}
}

21
deployment/env.tmpl Normal file
View File

@ -0,0 +1,21 @@
VAULT_CAPATH=./certs/ca.pem
CONSUL_CACERT=./certs/ca.pem
CONSUL_CLIENT_CERT=./certs/cert.pem
CONSUL_CLIENT_KEY=./certs/key.pem
CONSUL_HTTP_TOKEN={{ with secret "consul/creds/gitops" }}{{ .Data.token }}{{ end }}
NOMAD_ADDR=https://hashi.fluence.dev:4646
NOMAD_CAPATH=./certs/ca.pem
NOMAD_CLIENT_CERT=./certs/cert.pem
NOMAD_CLIENT_KEY=./certs/key.pem
NOMAD_TOKEN={{ with secret "nomad/creds/gitops" }}{{ .Data.secret_id }}{{ end }}
CLOUDFLARE_API_TOKEN={{ with secret "kv/cloudflare/personal" }}{{ .Data.token }}{{ end }}
CLOUDFLARE_DNS_API_TOKEN=$CLOUDFLARE_API_TOKEN
{{- with secret "pki/issue/internal" "ttl=30m" "common_name=ci.node.consul" -}}
{{ .Data.issuing_ca | writeToFile "./certs/ca.pem" "" "" "0644" }}
{{ .Data.certificate | writeToFile "./certs/cert.pem" "" "" "0644" }}
{{ .Data.private_key | writeToFile "./certs/key.pem" "" "" "0644" }}
{{- end -}}

317
deployment/job.nomad.hcl Normal file
View File

@ -0,0 +1,317 @@
variable "env" {
type = string
}
variable "replicas" {
type = string
}
variable "nox-image" {
type = string
}
variable "nox-policy" {
type = string
}
variable "promtail-policy" {
type = string
}
job "nox" {
region = var.env
datacenters = [
"fra1"
]
namespace = "fluence"
group "nox" {
count = var.replicas
update {
max_parallel = 4
}
meta {
instance = "nox-${NOMAD_ALLOC_INDEX}"
}
network {
dns {
servers = [
"1.1.1.1",
]
}
port "tcp" {
host_network = "public"
}
port "ws" {
host_network = "public"
}
port "metrics" {}
port "ipfs_swarm" {}
port "ipfs_api" {}
port "ipfs_gateway" {}
port "promtail" {}
}
service {
name = "nox"
port = "metrics"
meta {
replica = "nox-${NOMAD_ALLOC_INDEX}"
}
check {
type = "http"
path = "/health"
port = "metrics"
interval = "10s"
timeout = "1s"
}
}
service {
name = "nox-${NOMAD_ALLOC_INDEX}"
port = "ws"
meta {
alloc_id = NOMAD_ALLOC_ID
replica = "nox-${NOMAD_ALLOC_INDEX}"
}
tags = [
"traefik.enable=true",
"traefik.http.routers.nox-${NOMAD_ALLOC_INDEX}.entrypoints=nox",
"traefik.http.routers.nox-${NOMAD_ALLOC_INDEX}.rule=Host(`${NOMAD_ALLOC_INDEX}-${NOMAD_REGION}.fluence.dev`)",
]
}
service {
name = "nox-legacy-${NOMAD_ALLOC_INDEX}"
port = "ws"
meta {
alloc_id = NOMAD_ALLOC_ID
replica = "nox-${NOMAD_ALLOC_INDEX}"
}
tags = [
"traefik.enable=true",
"traefik.http.routers.nox-legacy-${NOMAD_ALLOC_INDEX}.entrypoints=nox-legacy-${NOMAD_ALLOC_INDEX}",
"traefik.http.routers.nox-legacy-${NOMAD_ALLOC_INDEX}.rule=Host(`${NOMAD_REGION}.fluence.dev`)",
]
}
service {
name = "promtail"
port = "promtail"
meta {
sidecar_to = "nox"
instance = "nox-${NOMAD_ALLOC_INDEX}"
}
check {
type = "http"
path = "/ready"
port = "promtail"
interval = "10s"
timeout = "1s"
}
}
volume "nox" {
type = "csi"
source = "nox"
attachment_mode = "file-system"
access_mode = "single-node-writer"
per_alloc = true
}
task "nox" {
driver = "docker"
vault {
policies = [
var.nox-policy,
]
}
volume_mount {
volume = "nox"
destination = "/.fluence"
}
resources {
cpu = 1000
memory = 2000
memory_max = 3000
}
env {
IPFS_ADDRESSES_SWARM = "/ip4/0.0.0.0/tcp/${NOMAD_PORT_ipfs_swarm},/ip4/0.0.0.0/tcp/${NOMAD_PORT_ipfs_swarm}/ws"
IPFS_ADDRESSES_API = "/ip4/0.0.0.0/tcp/${NOMAD_PORT_ipfs_api}"
IPFS_ADDRESSES_GATEWAY = "/ip4/0.0.0.0/tcp/${NOMAD_PORT_ipfs_gateway}"
IPFS_ADDRESSES_ANNOUNCE = "/ip4/${attr.unique.network.ip-address}/tcp/${NOMAD_PORT_ipfs_swarm},/ip4/${attr.unique.network.ip-address}/tcp/${NOMAD_PORT_ipfs_swarm}/ws"
IPFS_PATH = "/.fluence/ipfs"
FLUENCE_ENV_AQUA_IPFS_EXTERNAL_API_MULTIADDR = "/ip4/${attr.unique.network.ip-address}/tcp/${NOMAD_PORT_ipfs_api}"
FLUENCE_ENV_AQUA_IPFS_LOCAL_API_MULTIADDR = "/ip4/127.0.0.1/tcp/${NOMAD_PORT_ipfs_api}"
FLUENCE_SYSTEM_SERVICES__ENABLE = "aqua-ipfs,decider"
FLUENCE_SYSTEM_SERVICES__DECIDER__DECIDER_PERIOD_SEC = "10"
FLUENCE_MAX_SPELL_PARTICLE_TTL = "9s"
FLUENCE_SYSTEM_SERVICES__DECIDER__NETWORK_ID = "80001"
FLUENCE_ENV_CONNECTOR_API_ENDPOINT = "https://polygon-mumbai.g.alchemy.com/v2/Lb6BZr1VMEgcpAfeUGCBw2-BMHzjWWoq"
FLUENCE_ENV_CONNECTOR_FROM_BLOCK = "0x25C5AD8"
FLUENCE_CONFIG = "/local/Config.toml"
FLUENCE_LOG__FORMAT = "logfmt"
CERAMIC_HOST = "https://ceramic-${NOMAD_REGION}.fluence.dev"
RUST_LOG = "info,ipfs_effector=off,ipfs_pure=off,run-console=info"
FLUENCE_HTTP_PORT = NOMAD_PORT_metrics
}
config {
image = var.nox-image
auth_soft_fail = true
network_mode = "host"
labels {
replica = "nox-${NOMAD_ALLOC_INDEX}"
}
args = [
"--allow-private-ips",
"${BOOTSTRAP}",
"-x=${attr.unique.network.ip-address}",
"--external-maddrs",
"/dns4/${NOMAD_ALLOC_INDEX}-${NOMAD_REGION}.fluence.dev/tcp/9000/wss",
"-k=${KEY}",
"-f=ed25519",
"--management-key=${MANAGEMENT_KEY}",
/* "--aqua-pool-size=${attr.cpu.numcores}", */
"--aqua-pool-size=2",
"--tcp-port=${NOMAD_PORT_tcp}",
"--ws-port=${NOMAD_PORT_ws}",
# "--metrics-port=${NOMAD_PORT_metrics}",
]
ports = [
"tcp",
"ws",
"metrics",
"ipfs_swarm",
"ipfs_api",
"ipfs_gateway",
]
}
template {
data = <<-EOH
{{ if eq (env "NOMAD_ALLOC_INDEX") "0" }}
BOOTSTRAP='--local'
{{ else }}
BOOTSTRAP="--bootstraps=/dns4/0-{{ env "NOMAD_REGION" }}.fluence.dev/tcp/9000/wss"
{{ end }}
EOH
destination = "local/bootstrap"
env = true
}
template {
data = <<-EOH
{{ key "configs/fluence/nox/Config.toml" }}
EOH
destination = "local/Config.toml"
}
template {
data = <<-EOH
{{- with secret "kv/nox/stage/management" -}}
MANAGEMENT_KEY='{{ .Data.peer_id }}'
{{- end -}}
EOH
destination = "secrets/secrets.env"
env = true
}
template {
data = <<-EOH
{{- with secret (env "NOMAD_ALLOC_INDEX" | printf "kv/nox/stage/nodes/%s") -}}
KEY={{ .Data.private }}
FLUENCE_ENV_CONNECTOR_WALLET_KEY={{ .Data.wallet_key }}
FLUENCE_ENV_CONNECTOR_CONTRACT_ADDRESS="0x38A7fF922d7FeAE7CA7D3242BC4e87614f1FfDda"
{{- end -}}
EOH
destination = "secrets/node-secrets.env"
env = true
}
}
task "promtail" {
driver = "docker"
user = "nobody"
lifecycle {
hook = "poststart"
sidecar = true
}
vault {
policies = [
var.promtail-policy,
]
}
resources {
cpu = 50
memory = 64
memory_max = 128
}
env {
INSTANCE = "nox-${NOMAD_ALLOC_INDEX}"
}
config {
image = "grafana/promtail:2.6.1"
args = [
"-config.file=local/promtail.yml",
"-config.expand-env=true",
]
ports = [
"promtail",
]
}
template {
data = <<-EOH
{{ key "configs/fluence/nox/promtail.yml" }}
EOH
destination = "local/promtail.yml"
}
template {
data = <<-EOH
{{- with secret "kv/loki/basicauth/promtail" -}}
{{ .Data.password }}{{ end }}
EOH
destination = "secrets/auth"
}
}
}
}

118
deployment/job.tf Normal file
View File

@ -0,0 +1,118 @@
variable "replicas" {
description = "replicas to run"
type = string
}
variable "nox" {
description = "nox docker image"
type = string
}
resource "consul_keys" "configs" {
# nox config
key {
path = "configs/fluence/nox/Config.toml"
value = file("Config.toml")
delete = true
}
# promtail config
key {
path = "configs/fluence/nox/promtail.yml"
value = file("promtail.yml")
delete = true
}
}
resource "vault_policy" "nox" {
name = "${terraform.workspace}/nox"
policy = <<-EOT
path "kv/nox/${terraform.workspace}/*"
{
capabilities = ["read"]
}
EOT
}
resource "vault_policy" "promtail" {
name = "${terraform.workspace}/nox/promtail"
policy = <<-EOT
path "kv/loki/basicauth/promtail"
{
capabilities = ["read"]
}
EOT
}
resource "nomad_csi_volume" "nox" {
count = var.replicas
namespace = "fluence"
plugin_id = "do-csi"
volume_id = "nox[${count.index}]"
name = "${terraform.workspace}-nox-${count.index}"
capacity_min = "50GiB"
capacity_max = "50GiB"
capability {
access_mode = "single-node-writer"
attachment_mode = "file-system"
}
mount_options {
fs_type = "ext4"
mount_flags = ["noatime"]
}
}
resource "nomad_job" "nox" {
depends_on = [
nomad_csi_volume.nox,
vault_policy.nox,
vault_policy.promtail,
consul_keys.configs,
]
jobspec = file("${path.module}/job.nomad.hcl")
detach = false
purge_on_destroy = true
hcl2 {
vars = {
env = terraform.workspace
replicas = var.replicas
nox-image = var.nox
nox-policy = "${terraform.workspace}/nox"
promtail-policy = "${terraform.workspace}/nox/promtail"
}
}
}
resource "cloudflare_record" "nox" {
count = var.replicas
zone_id = data.cloudflare_zone.fluence_dev.zone_id
name = "${count.index}-${terraform.workspace}"
value = data.terraform_remote_state.state.outputs.ingress_ip4
type = "A"
}
resource "cloudflare_record" "nox-legacy" {
zone_id = data.cloudflare_zone.fluence_dev.zone_id
name = terraform.workspace
value = data.terraform_remote_state.state.outputs.ingress_ip4
type = "A"
}
data "vault_generic_secret" "keys" {
count = var.replicas
path = "kv/nox/${terraform.workspace}/nodes/${count.index}"
}
output "peer_ids" {
value = [
for i in range(var.replicas) :
"/dns4/${i}-${terraform.workspace}.fluence.dev/tcp/9000/wss/p2p/${data.vault_generic_secret.keys.*.data[i].peer_id}"
]
sensitive = true
}

30
deployment/promtail.yml Normal file
View File

@ -0,0 +1,30 @@
server:
http_listen_port: ${NOMAD_PORT_promtail}
positions:
filename: "${NOMAD_ALLOC_DIR}/data/positions.yml"
clients:
- url: "https://loki.fluence.dev/loki/api/v1/push"
tenant_id: "fluencelabs"
basic_auth:
username: "promtail"
password_file: "/secrets/auth"
scrape_configs:
- job_name: "nox"
static_configs:
- labels:
source: "nox"
instance: "${INSTANCE}"
env: "stage"
__path__: "${NOMAD_ALLOC_DIR}/logs/nox.stdout.*"
pipeline_stages:
- logfmt:
mapping:
time:
level:
particle_id:
- timestamp:
source: time
format: "RFC3339Nano"

4
versions.json Normal file
View File

@ -0,0 +1,4 @@
{
"nox": "fluencelabs/nox:rich_0.2.5",
"cli": "@fluencelabs/cli@0.8.2"
}