Browse Source

Add parameters, remove docker build, update deployment

Anuj Bansal 3 years ago
parent
commit
e395c5f752

+ 29 - 0
devops/kubernetes/pulumi-common/configMap.ts

@@ -0,0 +1,29 @@
+import * as pulumi from '@pulumi/pulumi'
+import * as k8s from '@pulumi/kubernetes'
+import * as fs from 'fs'
+
+export class configMapFromFile extends pulumi.ComponentResource {
+  public readonly configName?: pulumi.Output<string>
+
+  constructor(name: string, args: ConfigMapArgs, opts: pulumi.ComponentResourceOptions = {}) {
+    super('pkg:query-node:configMap', name, {}, opts)
+
+    this.configName = new k8s.core.v1.ConfigMap(
+      name,
+      {
+        metadata: {
+          namespace: args.namespaceName,
+        },
+        data: {
+          'fileData': fs.readFileSync(args.filePath).toString(),
+        },
+      },
+      opts
+    ).metadata.apply((m) => m.name)
+  }
+}
+
+export interface ConfigMapArgs {
+  filePath: string
+  namespaceName: pulumi.Output<string>
+}

+ 1 - 0
devops/kubernetes/pulumi-common/index.ts

@@ -1,2 +1,3 @@
 export { CaddyServiceDeployment } from './caddy'
 export { PostgresServiceDeployment } from './database'
+export { configMapFromFile } from './configMap'

+ 17 - 9
devops/kubernetes/storage-node/Pulumi.yaml

@@ -7,27 +7,35 @@ template:
       default: joystream-user
     aws:region:
       default: us-east-1
+    isMinikube:
+      description: Whether you are deploying to minikube
+      default: false
     wsProviderEndpointURI:
       description: Chain RPC endpoint
       default: 'wss://rome-rpc-endpoint.joystream.org:9944/'
-    isAnonymous:
-      description: Whether you are deploying an anonymous storage node
-      default: true
     isLoadBalancerReady:
       description: Whether the load balancer service is ready and has been assigned an IP
       default: false
     colossusPort:
       description: Port that is exposed for the colossus container
-      default: 3000
+      default: 3333
     storage:
       description: Amount of storage in gigabytes for ipfs volume
       default: 40
-    providerId:
-      description: StorageProviderId assigned to you in working group
     keyFile:
-      description: Path to JSON key export file to use as the storage provider (role account)
-    publicURL:
-      description: API Public URL to announce
+      description: Key file for the account
     passphrase:
       description: Optional passphrase to use to decrypt the key-file
       secret: true
+    colossusImage:
+      description: The colossus image to use for running the storage node
+      default: joystream/colossus:latest
+    queryNodeHost:
+      description: Query node GraphQL endpoint
+      default: 'https://hydra.joystream.org/graphql'
+    workerId:
+      description: ID of the node operator (distribution working group worker)
+      default: 0
+    accountURI:
+      description: Account URI
+      default: '//Alice'

+ 7 - 6
devops/kubernetes/storage-node/README.md

@@ -39,18 +39,19 @@ After cloning this repo, from this working directory, run these commands:
    ```bash
    $ pulumi config set-all --plaintext aws:region=us-east-1 --plaintext aws:profile=joystream-user \
     --plaintext wsProviderEndpointURI='wss://rome-rpc-endpoint.joystream.org:9944/' \
-    --plaintext isMinikube=true --plaintext isAnonymous=true
+    --plaintext queryNodeHost='http://graphql-server.query-node-yszsbs2i:8081' \
+    --plaintext keyFile='../../../keyfile.json' \
+    --plaintext isMinikube=true
    ```
 
-   If running for production use the below mentioned config
+   If you want to build the stack on AWS set the `isMinikube` config to `false`
 
    ```bash
-   $ pulumi config set-all --plaintext aws:region=us-east-1 --plaintext aws:profile=joystream-user \
-    --plaintext wsProviderEndpointURI='wss://rome-rpc-endpoint.joystream.org:9944/' --plaintext isAnonymous=false --plaintext isMinikube=false \
-    --plaintext providerId=<ID> --plaintext keyFile=<PATH> --plaintext publicURL=<DOMAIN> --secret passphrase=<PASSPHRASE>
+   $ pulumi config set isMinikube false
    ```
 
-   You can also set the `storage` and the `colossusPort` config parameters if required
+   You can also set the `storage` and the `colossusPort` config parameters if required. Check `Pulumi.yaml` file
+   for additional parameters.
 
 1. Stand up the EKS cluster:
 

+ 5 - 0
devops/kubernetes/storage-node/docker_dummy/Dockerfile

@@ -0,0 +1,5 @@
+# Since Pulumi does not support push without a build
+# we build an image from an existing local image
+ARG SOURCE_IMAGE
+
+FROM --platform=linux/amd64 ${SOURCE_IMAGE}

+ 91 - 114
devops/kubernetes/storage-node/index.ts

@@ -4,40 +4,32 @@ import * as eks from '@pulumi/eks'
 import * as docker from '@pulumi/docker'
 import * as k8s from '@pulumi/kubernetes'
 import * as pulumi from '@pulumi/pulumi'
-import { CaddyServiceDeployment } from 'pulumi-common'
+import { CaddyServiceDeployment, configMapFromFile } from 'pulumi-common'
 import * as fs from 'fs'
 
 const awsConfig = new pulumi.Config('aws')
 const config = new pulumi.Config()
 
+const name = 'storage-node'
+
 const wsProviderEndpointURI = config.require('wsProviderEndpointURI')
-const isAnonymous = config.require('isAnonymous') === 'true'
+const queryNodeHost = config.require('queryNodeHost')
+const workerId = config.get('workerId') || '0'
+const accountURI = config.get('accountURI') || '//Alice'
 const lbReady = config.get('isLoadBalancerReady') === 'true'
-const name = 'storage-node'
-const colossusPort = parseInt(config.get('colossusPort') || '3000')
+const configColossusImage = config.get('colossusImage') || `joystream/colossus:latest`
+const colossusPort = parseInt(config.get('colossusPort') || '3333')
 const storage = parseInt(config.get('storage') || '40')
 const isMinikube = config.getBoolean('isMinikube')
 
 let additionalParams: string[] | pulumi.Input<string>[] = []
-let volumeMounts: pulumi.Input<pulumi.Input<k8s.types.input.core.v1.VolumeMount>[]> = []
-let volumes: pulumi.Input<pulumi.Input<k8s.types.input.core.v1.Volume>[]> = []
 
 export let kubeconfig: pulumi.Output<any>
-export let colossusImage: pulumi.Output<string>
+export let colossusImage: pulumi.Output<string> = pulumi.interpolate`${configColossusImage}`
 let provider: k8s.Provider
 
 if (isMinikube) {
   provider = new k8s.Provider('local', {})
-  // Create image from local app
-  colossusImage = new docker.Image('joystream/colossus', {
-    build: {
-      context: '../../../',
-      dockerfile: '../../../colossus.Dockerfile',
-    },
-    imageName: 'joystream/colossus:latest',
-    skipPush: true,
-  }).baseImageName
-  // colossusImage = pulumi.interpolate`joystream/colossus:latest`
 } else {
   // Create a VPC for our cluster.
   const vpc = new awsx.ec2.Vpc('storage-node-vpc', { numberOfAvailabilityZones: 2, numberOfNatGateways: 1 })
@@ -61,8 +53,9 @@ if (isMinikube) {
 
   // Build an image and publish it to our ECR repository.
   colossusImage = repo.buildAndPushImage({
-    dockerfile: '../../../colossus.Dockerfile',
-    context: '../../../',
+    context: './docker_dummy',
+    dockerfile: './docker_dummy/Dockerfile',
+    args: { SOURCE_IMAGE: colossusImage! },
   })
 }
 
@@ -96,74 +89,22 @@ const pvc = new k8s.core.v1.PersistentVolumeClaim(
   resourceOptions
 )
 
-volumes.push({
-  name: 'ipfs-data',
-  persistentVolumeClaim: {
-    claimName: `${name}-pvc`,
+const keyFile = config.require('keyFile')
+const keyConfigName = new configMapFromFile(
+  'key-config',
+  {
+    filePath: keyFile,
+    namespaceName: namespaceName,
   },
-})
-
-const caddyEndpoints = [
-  ` {
-    reverse_proxy storage-node:${colossusPort}
-}`,
-]
-
-export let endpoint1: pulumi.Output<string> = pulumi.interpolate``
-export let endpoint2: pulumi.Output<string> = pulumi.interpolate``
-
-if (!isMinikube) {
-  const caddy = new CaddyServiceDeployment(
-    'caddy-proxy',
-    { lbReady, namespaceName: namespaceName, caddyEndpoints },
-    resourceOptions
-  )
-
-  endpoint1 = pulumi.interpolate`${caddy.primaryEndpoint}`
-  endpoint2 = pulumi.interpolate`${caddy.secondaryEndpoint}`
-}
-
-export let appLink: pulumi.Output<string>
-
-if (lbReady) {
-  appLink = pulumi.interpolate`https://${endpoint1}`
-
-  if (!isAnonymous) {
-    const remoteKeyFilePath = '/joystream/key-file.json'
-    const providerId = config.require('providerId')
-    const keyFile = config.require('keyFile')
-    const publicUrl = config.get('publicURL') ? config.get('publicURL')! : appLink
-
-    const keyConfig = new k8s.core.v1.ConfigMap('key-config', {
-      metadata: { namespace: namespaceName, labels: appLabels },
-      data: { 'fileData': fs.readFileSync(keyFile).toString() },
-    })
-    const keyConfigName = keyConfig.metadata.apply((m) => m.name)
-
-    additionalParams = ['--provider-id', providerId, '--key-file', remoteKeyFilePath, '--public-url', publicUrl]
-
-    volumeMounts.push({
-      mountPath: remoteKeyFilePath,
-      name: 'keyfile-volume',
-      subPath: 'fileData',
-    })
+  resourceOptions
+).configName
 
-    volumes.push({
-      name: 'keyfile-volume',
-      configMap: {
-        name: keyConfigName,
-      },
-    })
+const remoteKeyFilePath = '/joystream/key-file.json'
+additionalParams = ['--key-file', remoteKeyFilePath]
 
-    const passphrase = config.get('passphrase')
-    if (passphrase) {
-      additionalParams.push('--passphrase', passphrase)
-    }
-  }
-}
-
-if (isAnonymous) {
-  additionalParams.push('--anonymous')
+const passphrase = config.get('passphrase')
+if (passphrase) {
+  additionalParams.push('--password', passphrase)
 }
 
 // Create a Deployment
@@ -182,27 +123,7 @@ const deployment = new k8s.apps.v1.Deployment(
           labels: appLabels,
         },
         spec: {
-          hostname: 'ipfs',
           containers: [
-            {
-              name: 'ipfs',
-              image: 'ipfs/go-ipfs:latest',
-              ports: [{ containerPort: 5001 }, { containerPort: 8080 }],
-              command: ['/bin/sh', '-c'],
-              args: [
-                'set -e; \
-                /usr/local/bin/start_ipfs config profile apply lowpower; \
-                /usr/local/bin/start_ipfs config --json Gateway.PublicGateways \'{"localhost": null }\'; \
-                /usr/local/bin/start_ipfs config Datastore.StorageMax 200GB; \
-                /sbin/tini -- /usr/local/bin/start_ipfs daemon --migrate=true',
-              ],
-              volumeMounts: [
-                {
-                  name: 'ipfs-data',
-                  mountPath: '/data/ipfs',
-                },
-              ],
-            },
             {
               name: 'colossus',
               image: colossusImage,
@@ -217,21 +138,57 @@ const deployment = new k8s.apps.v1.Deployment(
                   name: 'DEBUG',
                   value: 'joystream:*',
                 },
+                {
+                  name: 'COLOSSUS_PORT',
+                  value: `${colossusPort}`,
+                },
+                {
+                  name: 'QUERY_NODE_HOST',
+                  value: queryNodeHost,
+                },
+                {
+                  name: 'WORKER_ID',
+                  value: workerId,
+                },
+                {
+                  name: 'ACCOUNT_URI',
+                  value: accountURI,
+                },
               ],
-              volumeMounts,
-              command: [
-                'yarn',
-                'colossus',
-                '--ws-provider',
-                wsProviderEndpointURI,
-                '--ipfs-host',
-                'ipfs',
-                ...additionalParams,
+              volumeMounts: [
+                {
+                  name: 'colossus-data',
+                  mountPath: '/data',
+                  subPath: 'data',
+                },
+                {
+                  name: 'colossus-data',
+                  mountPath: '/keystore',
+                  subPath: 'keystore',
+                },
+                {
+                  mountPath: remoteKeyFilePath,
+                  name: 'keyfile-volume',
+                  subPath: 'fileData',
+                },
               ],
               ports: [{ containerPort: colossusPort }],
             },
           ],
-          volumes,
+          volumes: [
+            {
+              name: 'colossus-data',
+              persistentVolumeClaim: {
+                claimName: `${name}-pvc`,
+              },
+            },
+            {
+              name: 'keyfile-volume',
+              configMap: {
+                name: keyConfigName,
+              },
+            },
+          ],
         },
       },
     },
@@ -262,3 +219,23 @@ export const serviceName = service.metadata.name
 
 // Export the Deployment name
 export const deploymentName = deployment.metadata.name
+
+const caddyEndpoints = [
+  ` {
+    reverse_proxy storage-node:${colossusPort}
+}`,
+]
+
+export let endpoint1: pulumi.Output<string> = pulumi.interpolate``
+export let endpoint2: pulumi.Output<string> = pulumi.interpolate``
+
+if (!isMinikube) {
+  const caddy = new CaddyServiceDeployment(
+    'caddy-proxy',
+    { lbReady, namespaceName: namespaceName, caddyEndpoints },
+    resourceOptions
+  )
+
+  endpoint1 = pulumi.interpolate`${caddy.primaryEndpoint}`
+  endpoint2 = pulumi.interpolate`${caddy.secondaryEndpoint}`
+}