Many things
This commit is contained in:
		
							parent
							
								
									c02c4e07da
								
							
						
					
					
						commit
						256d5d1f2b
					
				
							
								
								
									
										12
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										12
									
								
								Makefile
								
								
								
								
							|  | @ -72,7 +72,7 @@ else | ||||||
| SHELL_PORTS := | SHELL_PORTS := | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| SHELL_ENV := -e Z -e CI -e TEST_PATIENCE -e TEST_CONCURRENCY | SHELL_ENV := -e Z -e CI -e TEST_PATIENCE -e TEST_CONCURRENCY -e TEST_TIMEOUT_SECS -e FATHOM_SITE_ID | ||||||
| 
 | 
 | ||||||
| ifeq ($(I),lang) | ifeq ($(I),lang) | ||||||
| LANG_TAG := lang-$(L) | LANG_TAG := lang-$(L) | ||||||
|  | @ -202,6 +202,12 @@ lsp: # L=<lang|cmd> : Run LSP REPL for language or custom command line | ||||||
| 
 | 
 | ||||||
| ### Fetch artifacts from registries
 | ### Fetch artifacts from registries
 | ||||||
| 
 | 
 | ||||||
|  | PUBLIC_DOCKER_REPO_PULL ?= public.ecr.aws/raxod502/riju | ||||||
|  | 
 | ||||||
|  | sync-ubuntu: # Pull Riju Ubuntu image from public Docker registry
 | ||||||
|  | 	docker pull $(PUBLIC_DOCKER_REPO_PULL):ubuntu | ||||||
|  | 	docker tag $(PUBLIC_DOCKER_REPO_PULL):ubuntu riju:ubuntu | ||||||
|  | 
 | ||||||
| pull: # I=<image> : Pull last published Riju image from Docker registry
 | pull: # I=<image> : Pull last published Riju image from Docker registry
 | ||||||
| 	@: $${I} $${DOCKER_REPO} | 	@: $${I} $${DOCKER_REPO} | ||||||
| 	docker pull $(DOCKER_REPO):$(I) | 	docker pull $(DOCKER_REPO):$(I) | ||||||
|  | @ -239,9 +245,11 @@ upload: # L=<lang> T=<type> : Upload .deb to S3 | ||||||
| deploy-config: # Generate deployment config file
 | deploy-config: # Generate deployment config file
 | ||||||
| 	node tools/generate-deploy-config.js | 	node tools/generate-deploy-config.js | ||||||
| 
 | 
 | ||||||
| deploy: deploy-config # Upload deployment config to S3 and update ASG instances
 | deploy-latest: # Upload deployment config to S3 and update ASG instances
 | ||||||
| 	aws s3 cp $(BUILD)/config.json $(S3_CONFIG) | 	aws s3 cp $(BUILD)/config.json $(S3_CONFIG) | ||||||
| 
 | 
 | ||||||
|  | deploy: deploy-config deploy-latest # Shorthand for deploy-config followed by deploy-latest
 | ||||||
|  | 
 | ||||||
| ### Infrastructure
 | ### Infrastructure
 | ||||||
| 
 | 
 | ||||||
| packer: supervisor # Build and publish a new AMI
 | packer: supervisor # Build and publish a new AMI
 | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ const host = process.env.HOST || "localhost"; | ||||||
| const port = parseInt(process.env.PORT || "") || 6119; | const port = parseInt(process.env.PORT || "") || 6119; | ||||||
| const tlsPort = parseInt(process.env.TLS_PORT || "") || 6120; | const tlsPort = parseInt(process.env.TLS_PORT || "") || 6120; | ||||||
| const useTLS = process.env.TLS ? true : false; | const useTLS = process.env.TLS ? true : false; | ||||||
| const analyticsEnabled = process.env.ANALYTICS ? true : false; | const fathomSiteId = process.env.FATHOM_SITE_ID || ""; | ||||||
| 
 | 
 | ||||||
| const app = express(); | const app = express(); | ||||||
| 
 | 
 | ||||||
|  | @ -25,7 +25,7 @@ app.get("/", (_, res) => { | ||||||
|   if (Object.keys(langs).length > 0) { |   if (Object.keys(langs).length > 0) { | ||||||
|     res.render(path.resolve("frontend/pages/index"), { |     res.render(path.resolve("frontend/pages/index"), { | ||||||
|       langs, |       langs, | ||||||
|       analyticsEnabled, |       fathomSiteId, | ||||||
|     }); |     }); | ||||||
|   } else { |   } else { | ||||||
|     res |     res | ||||||
|  | @ -59,7 +59,7 @@ app.get("/:lang", (req, res) => { | ||||||
|   } |   } | ||||||
|   res.render(path.resolve("frontend/pages/app"), { |   res.render(path.resolve("frontend/pages/app"), { | ||||||
|     config: langs[lang], |     config: langs[lang], | ||||||
|     analyticsEnabled, |     fathomSiteId, | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
| app.use("/css", express.static("frontend/styles")); | app.use("/css", express.static("frontend/styles")); | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ function parseIntOr(thing, def) { | ||||||
|   return Number.isNaN(num) ? def : num; |   return Number.isNaN(num) ? def : num; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const TIMEOUT = parseIntOr(process.env.TEST_TIMEOUT_SECS, 15); | const TIMEOUT = parseIntOr(process.env.TEST_TIMEOUT_SECS, 30); | ||||||
| const PATIENCE = parseIntOr(process.env.TEST_PATIENCE, 1); | const PATIENCE = parseIntOr(process.env.TEST_PATIENCE, 1); | ||||||
| const CONCURRENCY = parseIntOr(process.env.TEST_CONCURRENCY, 2); | const CONCURRENCY = parseIntOr(process.env.TEST_CONCURRENCY, 2); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								doc/build.md
								
								
								
								
							
							
						
						
									
										33
									
								
								doc/build.md
								
								
								
								
							|  | @ -4,6 +4,39 @@ Riju's build system is complex and takes some time to explain. Bear | ||||||
| with me. (If you just want to add or modify a language, you can read | with me. (If you just want to add or modify a language, you can read | ||||||
| the [tutorial](tutorial.md) instead.) | the [tutorial](tutorial.md) instead.) | ||||||
| 
 | 
 | ||||||
|  | ## Depgraph | ||||||
|  | 
 | ||||||
|  | The high level interface to Riju's build system is a tool called | ||||||
|  | Depgraph, which knows about all the build artifacts and has advanced | ||||||
|  | mechanisms for determining which of them need to rebuild based on | ||||||
|  | content hashes. Normally you can just use Depgraph to build the | ||||||
|  | artifacts you need. However, in some cases you may want to interact | ||||||
|  | with the lower level for more precise operations. This is done via | ||||||
|  | Makefile. (Furthermore, there are a few one-off artifacts such as the | ||||||
|  | admin image which are not part of the main build system, which means | ||||||
|  | that they are managed directly by Makefile.) | ||||||
|  | 
 | ||||||
|  | ### Available build artifacts | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### Usage of Depgraph | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | $ dep --help | ||||||
|  | Usage: dep <target>... | ||||||
|  | 
 | ||||||
|  | Options: | ||||||
|  |   --list         list available artifacts; ignore other arguments | ||||||
|  |   --manual       operate explicitly on manual artifacts | ||||||
|  |   --hold-manual  prefer local versions of manual artifacts | ||||||
|  |   --all          do not skip unneeded intermediate artifacts | ||||||
|  |   --local-only   do not fetch artifacts from remote registries | ||||||
|  |   --publish      publish artifacts to remote registries | ||||||
|  |   --yes          execute plan without confirmation | ||||||
|  |   -h, --help     display help for command | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| To get a quick overview, run `make help`. | To get a quick overview, run `make help`. | ||||||
| 
 | 
 | ||||||
| ## Build artifacts | ## Build artifacts | ||||||
|  |  | ||||||
|  | @ -3,13 +3,30 @@ | ||||||
| You can host your own instance of Riju! This requires a bit of manual | You can host your own instance of Riju! This requires a bit of manual | ||||||
| setup, but everything that *can* be automated, *has* been automated. | setup, but everything that *can* be automated, *has* been automated. | ||||||
| 
 | 
 | ||||||
|  | **Warning: AWS is expensive and you are responsible for your own | ||||||
|  | spending. If you would be perturbed by accidentally burning a few | ||||||
|  | hundred dollars on unexpected compute, you probably shouldn't follow | ||||||
|  | these instructions.** | ||||||
|  | 
 | ||||||
| ## Sign up for accounts | ## Sign up for accounts | ||||||
| 
 | 
 | ||||||
| * [AWS](https://aws.amazon.com/) | * [AWS](https://aws.amazon.com/) | ||||||
| * [Docker Hub](https://hub.docker.com/) | * [CloudFlare](https://www.cloudflare.com/) | ||||||
|  | * [Fathom Analytics](https://usefathom.com/) (if you want analytics) | ||||||
| * [GitHub](https://github.com/) | * [GitHub](https://github.com/) | ||||||
|  | * [Namecheap](https://www.namecheap.com/) | ||||||
|  | * [PagerDuty](https://www.pagerduty.com/) (if you want alerts) | ||||||
| 
 | 
 | ||||||
| ## Configure accounts | ## Configure accounts | ||||||
|  | ### GitHub | ||||||
|  | 
 | ||||||
|  | Fork the Riju repository under your account. | ||||||
|  | 
 | ||||||
|  | ### PagerDuty | ||||||
|  | 
 | ||||||
|  | Set up notification rules as desired. Configure the AWS CloudWatch | ||||||
|  | integration and obtain an integration URL. | ||||||
|  | 
 | ||||||
| ### AWS | ### AWS | ||||||
| 
 | 
 | ||||||
| You need to generate an access key with sufficient permission to apply | You need to generate an access key with sufficient permission to apply | ||||||
|  | @ -23,24 +40,35 @@ don't already know your way around IAM is: | ||||||
| * Attach the "AdministratorAccess" policy | * Attach the "AdministratorAccess" policy | ||||||
| * Copy and save the access key ID and secret access key | * Copy and save the access key ID and secret access key | ||||||
| 
 | 
 | ||||||
| You also need to create an S3 bucket to store Terraform's state. Go to | You also need to create an S3 bucket to store Terraform state. [Go to | ||||||
| [S3 in | S3](https://s3.console.aws.amazon.com/s3/home?region=us-west-1), | ||||||
| us-west-1](https://s3.console.aws.amazon.com/s3/home?region=us-west-1#) | select your favorite AWS region, and create a new bucket called | ||||||
| and create a new bucket called `riju-yourname-tf`. | `riju-yourname-tf`. | ||||||
| 
 | 
 | ||||||
| ### Docker Hub | Finally, if you don't have a personal SSH key, generate one with | ||||||
|  | `ssh-keygen`, and upload the public key (e.g. `~/.ssh/id_rsa.pub`) as | ||||||
|  | an [EC2 Key | ||||||
|  | Pair](https://us-west-1.console.aws.amazon.com/ec2/v2/home?region=us-west-1#KeyPairs:). | ||||||
|  | Remember the name you use for the key pair. | ||||||
| 
 | 
 | ||||||
| Create a new repository to use for Riju. | ### Namecheap | ||||||
| 
 | 
 | ||||||
| ### GitHub | Buy a domain name at which to host. | ||||||
| 
 | 
 | ||||||
| Fork the Riju repository under your account. | ### CloudFlare | ||||||
|  | 
 | ||||||
|  | Enter your domain name and go through the setup and DNS verification. | ||||||
|  | Update the nameserver settings on Namecheap's side, and enable all the | ||||||
|  | fun CloudFlare options you'd like. | ||||||
|  | 
 | ||||||
|  | ### Fathom Analytics | ||||||
|  | 
 | ||||||
|  | Enter your domain name and get a site ID. | ||||||
| 
 | 
 | ||||||
| ## Install dependencies | ## Install dependencies | ||||||
| 
 | 
 | ||||||
| * [Docker](https://www.docker.com/) | * [Docker](https://www.docker.com/) | ||||||
| * [Git](https://git-scm.com/) | * [Git](https://git-scm.com/) | ||||||
| * [SSH](https://www.openssh.com/) |  | ||||||
| 
 | 
 | ||||||
| ## Set up Riju locally | ## Set up Riju locally | ||||||
| 
 | 
 | ||||||
|  | @ -59,164 +87,168 @@ and refer to a [tmux | ||||||
| cheatsheet](https://danielmiessler.com/study/tmux/) if you are | cheatsheet](https://danielmiessler.com/study/tmux/) if you are | ||||||
| unfamiliar with tmux usage. | unfamiliar with tmux usage. | ||||||
| 
 | 
 | ||||||
| ## Configure your instance | ## Authenticate with AWS | ||||||
| ### AWS |  | ||||||
| 
 | 
 | ||||||
| Sign in locally to the AWS CLI by running | Run `aws configure` and enter your IAM access credentials and your | ||||||
|  | preferred AWS region. | ||||||
| 
 | 
 | ||||||
|     $ aws configure | ## Create local configuration (part 1 of 3) | ||||||
| 
 | 
 | ||||||
| and entering the access key that you generated on AWS. The default | Create a file `.env` in the Riju directory with the following | ||||||
| region is unimportant, although you may want to set it to `us-west-1` | contents, referring to the following sub-sections for how to fill in | ||||||
| because this is where Riju is configured to be deployed and having | the values properly: | ||||||
| that be consistent with your default command-line environment may |  | ||||||
| reduce confusion. |  | ||||||
| 
 |  | ||||||
| ### Password |  | ||||||
| 
 |  | ||||||
| You need an administrator password that will be used for `sudo` access |  | ||||||
| on the production instance of Riju. You can generate one using `pwgen |  | ||||||
| -s 20 1`. |  | ||||||
| 
 |  | ||||||
| ### SSH keys |  | ||||||
| 
 |  | ||||||
| You need two keys. One is used for administrator login on the |  | ||||||
| production instance, and the other is used to trigger deployments. You |  | ||||||
| can use your personal SSH key, if you already have one, for the admin |  | ||||||
| key. However, you should definitely generate a new key for |  | ||||||
| deployments. To generate an SSH key, use the `ssh-keygen` utility. |  | ||||||
| 
 |  | ||||||
| Place both keys in `~/.ssh`. This directory is automatically mounted |  | ||||||
| into the admin shell at `/home/riju/.ssh`. |  | ||||||
| 
 |  | ||||||
| ### Additional configuration |  | ||||||
| 
 |  | ||||||
| You also need to have: |  | ||||||
| 
 |  | ||||||
| * The name of the Docker Hub repository that you created earlier (e.g. |  | ||||||
|   `raxod502/riju`). |  | ||||||
| * The base name of the S3 bucket(s) for Riju that will be created in |  | ||||||
|   your AWS account. The official buckets use prefix `riju`, but since |  | ||||||
|   S3 buckets must be globally unique you should use `riju-yourname`. |  | ||||||
| 
 |  | ||||||
| With configuration in hand, create a file `.env` in the Riju directory |  | ||||||
| with the following contents, adjusting the values to match your |  | ||||||
| configuration: |  | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|  | # Packer | ||||||
| ADMIN_PASSWORD=50M9QDBtkQLV6zFAwhVg | ADMIN_PASSWORD=50M9QDBtkQLV6zFAwhVg | ||||||
| ADMIN_SSH_PUBLIC_KEY_FILE=/home/riju/.ssh/id_rsa.pub | FATHOM_SITE_ID= | ||||||
| DEPLOY_SSH_PUBLIC_KEY_FILE=/home/riju/.ssh/id_rsa_riju_deploy.pub | SUPERVISOR_ACCESS_TOKEN=5ta2qzMFS417dG9gbfcMgjsbDnGMI4 | ||||||
| DOCKER_REPO=raxod502/riju |  | ||||||
| S3_BUCKET=riju-yourname |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Create infrastructure | ### ADMIN\_PASSWORD | ||||||
| 
 | 
 | ||||||
| Run `make env` in the admin shell to start a subshell with environment | This will be the `sudo` password for Riju server nodes. Generate one | ||||||
| variables set from `.env`. Your first step will be to create an | randomly with `pwgen -s 20 1`. | ||||||
| [AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) | 
 | ||||||
| for Riju. | ### FATHOM\_SITE\_ID | ||||||
|  | 
 | ||||||
|  | This is the site ID from your Fathom Analytics account. If you don't | ||||||
|  | need analytics, just leave this unset. | ||||||
|  | 
 | ||||||
|  | ### SUPERVISOR\_ACCESS\_TOKEN | ||||||
|  | 
 | ||||||
|  | This is a static shared secret used for the Riju server's supervisor | ||||||
|  | API. Generate one randomly with `pwgen -s 30 1`. | ||||||
|  | 
 | ||||||
|  | ## Build AMI | ||||||
|  | 
 | ||||||
|  | You'll want to run `make env` to load in the new variables from | ||||||
|  | `.env`. Now run `make packer`. This will take up to 10 minutes to | ||||||
|  | build a timestamped AMI with a name like `riju-20210711223158`. | ||||||
|  | 
 | ||||||
|  | ## Create local configuration (part 2 of 3) | ||||||
|  | 
 | ||||||
|  | Add to `.env` the following contents: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| $ cd packer | # Terraform | ||||||
| $ packer build config.json | AMI_NAME=riju-20210711223158 | ||||||
|  | AWS_REGION=us-west-1 | ||||||
|  | S3_BUCKET=yourname-riju | ||||||
|  | SSH_KEY_NAME=something | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| This will take several minutes. Note the name of the AMI that is | ### AMI\_NAME | ||||||
| printed, and add a corresponding line to `.env`: | 
 | ||||||
|  | This is the AMI name from the Packer build. | ||||||
|  | 
 | ||||||
|  | ### AWS\_REGION | ||||||
|  | 
 | ||||||
|  | This is the region in which most Terraform infrastructure will be | ||||||
|  | created. It should be the same as the default region you configured | ||||||
|  | for the AWS CLI. It doesn't have to be the same as the region in which | ||||||
|  | your Terraform state bucket is configured, although it simplifies | ||||||
|  | matters to keep them in the same region. | ||||||
|  | 
 | ||||||
|  | The main utility of having this as an explicit environment variable is | ||||||
|  | that Terraform respects it and won't always ask you what region to | ||||||
|  | use. | ||||||
|  | 
 | ||||||
|  | ### S3\_BUCKET | ||||||
|  | 
 | ||||||
|  | This is the name of the S3 bucket that will be used to store Riju | ||||||
|  | build artifacts (aside from Docker images). It needs to be globally | ||||||
|  | unique, so `yourname-riju` is a good choice. | ||||||
|  | 
 | ||||||
|  | ### SSH\_KEY\_NAME | ||||||
|  | 
 | ||||||
|  | This is the name of the EC2 Key Pair you created in the AWS console. | ||||||
|  | You'll use it to connect to the development server. | ||||||
|  | 
 | ||||||
|  | ## Set up Terraform infrastructure | ||||||
|  | 
 | ||||||
|  | Run `make env` again to load in the new variables from `.env`. | ||||||
|  | 
 | ||||||
|  | Now run `terraform init` and fill in the appropriate region and bucket | ||||||
|  | name for the Terraform state bucket you created in the AWS console. | ||||||
|  | 
 | ||||||
|  | At this point you can run `terraform apply` to create all the needed | ||||||
|  | infrastructure. Caution! At this point you probably want to go to the | ||||||
|  | EC2 console and stop the dev server. It is very expensive and will | ||||||
|  | rack up a few hundred dollars a month of compute. You should only have | ||||||
|  | it running when you're actively working on Riju. | ||||||
|  | 
 | ||||||
|  | ## Finish AWS configuration | ||||||
|  | 
 | ||||||
|  | Go back to the AWS console and take care of a few loose ends: | ||||||
|  | 
 | ||||||
|  | * If you want, register a [custom public registry alias for | ||||||
|  |   ECR](https://us-west-1.console.aws.amazon.com/ecr/registries?region=us-west-1). | ||||||
|  |   This will make your public registry URL easier to remember. | ||||||
|  | * In the "View push commands" modal dialogs, take note of the | ||||||
|  |   repository URLs for your public and private Riju ECR repositories. | ||||||
|  | * If you want alerts, [create an SNS | ||||||
|  |   subscription](https://us-west-1.console.aws.amazon.com/sns/v3/home?region=us-west-1#/subscriptions) | ||||||
|  |   from the Riju SNS topic to the PagerDuty integration URL. | ||||||
|  | 
 | ||||||
|  | ## Create local configuration (part 3 of 3) | ||||||
|  | 
 | ||||||
|  | Add to `.env` the following contents: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| AMI_NAME=riju-1609531301 | # Build | ||||||
|  | DOCKER_REPO=800516322591.dkr.ecr.us-west-1.amazonaws.com/riju | ||||||
|  | PUBLIC_DOCKER_REPO=public.ecr.aws/yourname/riju | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Next, we will create the rest of the infrastructure. | ### DOCKER\_REPO | ||||||
|  | 
 | ||||||
|  | This is the URL for your private ECR repository. | ||||||
|  | 
 | ||||||
|  | ### PUBLIC\_DOCKER\_REPO | ||||||
|  | 
 | ||||||
|  | This is the URL for your public ECR repository. | ||||||
|  | 
 | ||||||
|  | ## Configure DNS | ||||||
|  | 
 | ||||||
|  | Obtain the DNS record for Riju's ALB from `terraform output` and | ||||||
|  | install it as a proxied CNAME record in CloudFlare DNS for your apex | ||||||
|  | domain. After DNS propagates, you should now be able to receive a 502 | ||||||
|  | from Riju with no body content. | ||||||
|  | 
 | ||||||
|  | ## Set up dev server | ||||||
|  | 
 | ||||||
|  | The dev server is provisioned with a fresh Ubuntu AMI. You probably | ||||||
|  | want to clone your repository up there, enable SSH agent forwarding, | ||||||
|  | etc. Doing a full build on your laptop is feasible, but unless you | ||||||
|  | have symmetric gigabit ethernet you're not going to get all the build | ||||||
|  | artifacts uploaded in less than a week. | ||||||
|  | 
 | ||||||
|  | ## Build and deploy | ||||||
|  | 
 | ||||||
|  | Invoke Depgraph: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| $ cd ../tf | $ dep deploy:live --publish | ||||||
| $ terraform init -backend-config="bucket=riju-yourname-tf" |  | ||||||
| $ terraform apply |  | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| This will print out the IP address of your newly provisioned server, | After innumerable hours of build time (and probably some debugging to | ||||||
| as well as permission-limited AWS credentials for use in CI. Add a | fix languages that have broken since the last full build), Riju | ||||||
| line to `.env` with the IP address: | should(tm) be live on your domain. You can connect to the live server | ||||||
| 
 | using EC2 Instance Connect by retrieving its instance ID from the AWS | ||||||
| ``` | console and running `mssh admin@i-theinstanceid`. Then you can check | ||||||
| DOMAIN=54.183.183.91 | (using the previously configured admin password) `sudo journalctl -efu | ||||||
| ``` | riju` to see the supervisor logs. | ||||||
| 
 |  | ||||||
| ## Bootstrap server |  | ||||||
| 
 |  | ||||||
| Your newly provisioned server also isn't running anything yet. |  | ||||||
| You'll want to bootstrap it with the official image to make sure |  | ||||||
| everything is in working order: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| $ ./tools/deploy.bash raxod502/riju:app |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| This may take a while. After it's finished, however, you should be |  | ||||||
| able to navigate to the IP address of your server in a browser and see |  | ||||||
| Riju up and running. |  | ||||||
| 
 |  | ||||||
| ## Bootstrap S3 |  | ||||||
| 
 |  | ||||||
| You probably don't want to build all of Riju's languages from scratch |  | ||||||
| when deploying a modified version, since that would take a long time. |  | ||||||
| You can avoid it by copying the latest built languages from Riju's |  | ||||||
| production S3 bucket. This will be fastest if you SSH into your |  | ||||||
| production server, which lives in AWS: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| $ ssh admin@your-ip-address |  | ||||||
| $  export AWS_ACCESS_KEY_ID=... |  | ||||||
| $  export AWS_SECRET_ACCESS_KEY=... |  | ||||||
| $ aws s3 cp --recursive --source-region us-west-1 s3://riju-debs s3://riju-yourname-debs |  | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| ## Set up CI | ## Set up CI | ||||||
| 
 | 
 | ||||||
| Go to [CircleCI](https://app.circleci.com/dashboard) and enable builds | In your GitHub repo settings, create the secrets `AWS_ACCESS_KEY_ID` | ||||||
| for your fork of Riju. In the project settings, configure the | and `AWS_SECRET_ACCESS_KEY` with the values from `terraform output | ||||||
| following environment variables: | -json`. GitHub Actions should be good to go! However, I would | ||||||
|  | recommend doing builds from the EC2 dev server when you need to | ||||||
|  | rebuild a lot of artifacts. | ||||||
| 
 | 
 | ||||||
| * `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`: the AWS access | You'll also want to go to `.github/workflows/main.yml` and update the | ||||||
|   credentials generated by Terraform | environment variables `AWS_REGION`, `DOCKER_REPO`, | ||||||
| * `DEPLOY_SSH_PRIVATE_KEY`: base64-encoded SSH private key, e.g. from | `PUBLIC_DOCKER_REPO`, and `S3_BUCKET` as appropriate for your own | ||||||
|   `base64 -w0 ~/.ssh/id_rsa_riju_deploy` | deployment (see the `.env` file you created earlier). | ||||||
| * `DOCKER_REPO`: same as in `.env` |  | ||||||
| * `DOCKER_USERNAME` and `DOCKER_PASSWORD`: your credentials for Docker |  | ||||||
|   Hub |  | ||||||
| * `DOMAIN`: same as in `.env` |  | ||||||
| * `S3_BUCKET`: same as in `.env` |  | ||||||
| 
 |  | ||||||
| You should now be able to trigger a build and see the production |  | ||||||
| instance updated automatically with a newly built image. |  | ||||||
| 
 |  | ||||||
| ## Enable TLS |  | ||||||
| 
 |  | ||||||
| By default Riju will serve HTTP traffic if a TLS certificate is not |  | ||||||
| available. You can fix this. First, you'll need a domain name (or |  | ||||||
| subdomain on an existing domain). If you don't have one, you can buy |  | ||||||
| one at e.g. [Namecheap](https://www.namecheap.com/). |  | ||||||
| 
 |  | ||||||
| In your domain registrar's configuration interface, go to the |  | ||||||
| manual/advanced DNS settings and create an A record for your domain |  | ||||||
| pointing at your server's IP address. (To point the top-level domain |  | ||||||
| at Riju, set the host to `@`; to point a subdomain |  | ||||||
| `foo.yourdomain.io`, set the host to `foo`.) |  | ||||||
| 
 |  | ||||||
| Now SSH into the production server and run: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| $ sudo systemctl stop riju |  | ||||||
| $ sudo certbot certonly --standalone |  | ||||||
| $ riju-install-certbot-hooks |  | ||||||
| $ sudo systemctl start riju |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Alternatively, if you have an existing Certbot certificate you'd like |  | ||||||
| to transfer to the new server, you can copy over the entire |  | ||||||
| `/etc/letsencrypt` direction exactly as it stands, and run |  | ||||||
| `riju-install-certbot-hooks`. |  | ||||||
|  |  | ||||||
|  | @ -48,6 +48,15 @@ keybindings are: | ||||||
|   use `control-b` twice to do a command on the inner one instead of |   use `control-b` twice to do a command on the inner one instead of | ||||||
|   the outer one |   the outer one | ||||||
| 
 | 
 | ||||||
|  | ## Fetch base Ubuntu image | ||||||
|  | 
 | ||||||
|  | Make sure you're using the same version of Ubuntu as the mainline | ||||||
|  | Riju: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | $ make sync-ubuntu | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## Start Riju server | ## Start Riju server | ||||||
| 
 | 
 | ||||||
| Use `dep`, the Riju build tool, to compile the Docker image that the | Use `dep`, the Riju build tool, to compile the Docker image that the | ||||||
|  | @ -105,7 +114,7 @@ language: | ||||||
| 
 | 
 | ||||||
| * [Install your language](tutorial/install.md) | * [Install your language](tutorial/install.md) | ||||||
| * [Provide run commands](tutorial/run.md) | * [Provide run commands](tutorial/run.md) | ||||||
| * [Configure tests](tutorial/tests.md) |  | ||||||
| * [Provide metadata](tutorial/metadata.md) |  | ||||||
| * [Add code formatter](tutorial/formatter.md) | * [Add code formatter](tutorial/formatter.md) | ||||||
| * [Add language server](tutorial/lsp.md) | * [Add language server](tutorial/lsp.md) | ||||||
|  | * [Configure tests](tutorial/tests.md) | ||||||
|  | * [Provide metadata](tutorial/metadata.md) | ||||||
|  |  | ||||||
|  | @ -166,3 +166,26 @@ template: | | ||||||
| run: | | run: | | ||||||
|   zoem -I main.azm; zoem |   zoem -I main.azm; zoem | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | ## Required input | ||||||
|  | 
 | ||||||
|  | Sometimes languages really don't want to provide a way to run code | ||||||
|  | noninteractively. In this case, you can include instructions about how | ||||||
|  | the user can manually run the code: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | repl: | | ||||||
|  |   hhvm -a | ||||||
|  | input: | | ||||||
|  |   print 123 * 234 | ||||||
|  | 
 | ||||||
|  | main: "main.hack" | ||||||
|  | template: | | ||||||
|  |   <<__EntryPoint>> | ||||||
|  |   function main(): void { | ||||||
|  |     echo "Hello, world!\n"; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | run: | | ||||||
|  |   echo "Type 'r' at the debugger prompt to run the code" && hhvm -a main.hack | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | @ -1 +1,167 @@ | ||||||
| TODO | # Tutorial: Configure tests | ||||||
|  | 
 | ||||||
|  | Riju has far too many languages to rely on manual testing to ensure | ||||||
|  | that features are not broken by upstream updates. As such, we have a | ||||||
|  | system to automatically generate test cases which are validated | ||||||
|  | whenever language configuration changes. | ||||||
|  | 
 | ||||||
|  | Here are the tests that can be configured for each language: | ||||||
|  | 
 | ||||||
|  | * `run` (mandatory for all languages): Verify that the `template` code | ||||||
|  |   prints `Hello, world!` when run using the `run` command. | ||||||
|  | * `repl` (mandatory for all languages with `repl`): Verify that | ||||||
|  |   submitting `123 * 234` to the `repl` command causes `28782` to be | ||||||
|  |   printed. | ||||||
|  | * `runrepl` (mandatory for all languages with `repl`): Same as `repl`, | ||||||
|  |   but using the `run` command instead of the `repl` command (i.e., | ||||||
|  |   test that the `run` command starts a REPL after executing `main`). | ||||||
|  | * `scope` (optional, only for languages with variable-scope-preserving | ||||||
|  |   `repl`): Verify that if a variable assignment is appended to `main`, | ||||||
|  |   then that variable can be evaluated from the REPL using the `run` | ||||||
|  |   command. | ||||||
|  | * `format` (mandatory for all languages with `format`): Verify that a | ||||||
|  |   misformatted version of the `template` code is correctly formatted | ||||||
|  |   back to its canonical form when executing `format.run`. | ||||||
|  | * `lsp` (mandatory for all languages with `lsp`): Verify that the | ||||||
|  |   language server produces a given autocompletion in a given context. | ||||||
|  | * `ensure` (optional): Verify that a specific shell command executes | ||||||
|  |   successfully. This is currently unused. | ||||||
|  | 
 | ||||||
|  | ## Test configuration | ||||||
|  | 
 | ||||||
|  | See [`jsonschema.yaml`](../../lib/jsonschema.yaml) for full | ||||||
|  | documentation. | ||||||
|  | 
 | ||||||
|  | * `run` | ||||||
|  |     * If your language can't be made to print exactly `Hello, world!`, | ||||||
|  |       specify the actual output using the `hello` key. | ||||||
|  |         * In extraordinary circumstances, a language may be unable to | ||||||
|  |           produce deterministic output (e.g. Entropy). In such cases, | ||||||
|  |           `hello` can also be a JavaScript-compatible regular | ||||||
|  |           expression, and you must specify `helloMaxLength` which is | ||||||
|  |           the maximum possible length of the `Hello, world` output | ||||||
|  |           matched by the regex. | ||||||
|  |     * Some languages require user input at the REPL to run the code, | ||||||
|  |       despite our best efforts to the contrary. In this case, you can | ||||||
|  |       specify the required input in the `helloInput` key. (See | ||||||
|  |       "Specifying user input" below.) | ||||||
|  |     * If a language *doesn't* have `repl`, then the `run` command is | ||||||
|  |       expected to terminate after executing user code. By default the | ||||||
|  |       expected exit status is 0, and the `run` test will fail | ||||||
|  |       otherwise. If for some reason your language exits with a nonzero | ||||||
|  |       status even in the absence of an error, then you can specify the | ||||||
|  |       expected status in the `helloStatus` key. | ||||||
|  | * `repl` | ||||||
|  |     * We try to compute `123 * 234` in most languages' REPLs. | ||||||
|  |       Naturally, the syntax may vary depending on the language, so you | ||||||
|  |       can specify an alternate input using the `input` key. (See | ||||||
|  |       "Specifying user input" below.) | ||||||
|  |     * The result of `123 * 234` is generally `28782`. In the case that | ||||||
|  |       we get the output in some other format, you can specify the | ||||||
|  |       expected output using the `output` key. | ||||||
|  | * `runrepl` | ||||||
|  |     * In the case that `input` needs to be different for `runrepl` | ||||||
|  |       than for `repl`, you can override it specifically for `runrepl` | ||||||
|  |       using the `runReplInput` key. | ||||||
|  |     * In the case that `output` needs to be different for `runrepl` | ||||||
|  |       than for `repl`, you can override it specifically for `runrepl` | ||||||
|  |       using the `runReplOutput` key. | ||||||
|  | * `scope` | ||||||
|  |     * *Required:* In `scope.code`, specify the code that is needed to | ||||||
|  |       assign `123 * 234` to a local variable named `x`, or as close to | ||||||
|  |       that as the language can manage. For example, in Python, this | ||||||
|  |       would be `x = 123 * 234`. | ||||||
|  |     * By default, `scope.code` is appended at the end of `template`. | ||||||
|  |       However, if it needs to go in the middle, you can specify | ||||||
|  |       `scope.after`, which should match an entire line of `template`. | ||||||
|  |       Then `scope.code` will be placed on the next list after | ||||||
|  |       `scope.after`. | ||||||
|  |     * By default, it's expected that typing `x` into the REPL will | ||||||
|  |       produce `28782`. You can override the input to something else by | ||||||
|  |       specifying `scope.input`. (See "Specifying user input" below.) | ||||||
|  |     * If the expected output is something other than `28782`, you can | ||||||
|  |       override it using `scope.output`. | ||||||
|  | * `format` | ||||||
|  |     * *Required:* In `format.input`, specify the input code. This | ||||||
|  |       should be distinct from `template`, but should turn into | ||||||
|  |       `template` when the `format` command is run on it. | ||||||
|  |     * In the case that you can't come up with input that formats to | ||||||
|  |       `template`, you can specify `format.output` as the expected | ||||||
|  |       result of formatting `format.input`. | ||||||
|  | * `lsp` | ||||||
|  |     * *Required:* In `lsp.code`, specify input (not necessarily an | ||||||
|  |       entire line) that we should pretend the user has typed. We | ||||||
|  |       expect an autocompletion to be presented with the cursor at the | ||||||
|  |       end of this input. | ||||||
|  |     * *Required:* In `lsp.item`, specify the text of an autocompletion | ||||||
|  |       that we expect the language server to generate. This should not | ||||||
|  |       match any text that actually appears in `template` or | ||||||
|  |       `lsp.code`. | ||||||
|  |     * In `lsp.after`, you can specify a string that will match exactly | ||||||
|  |       one place in `template`. This is where the cursor will be | ||||||
|  |       positioned before `lsp.code` is inserted. If `lsp.after` is not | ||||||
|  |       specified, then `lsp.code` will be inserted at the end of | ||||||
|  |       `template` on a new line. | ||||||
|  | * `ensure` | ||||||
|  |     * If you want to use an `ensure` test, just supply the shell | ||||||
|  |       command using the `ensure` key. | ||||||
|  | 
 | ||||||
|  | ## Specifying user input | ||||||
|  | 
 | ||||||
|  | We have a couple different formats for common types of user input. | ||||||
|  | This will type `eval` and send a newline: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | input: | | ||||||
|  |   eval | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This will type `eval`, send a newline, then type `go` and send another | ||||||
|  | newline: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | input: | | ||||||
|  |   eval | ||||||
|  |   go | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This will type `foo`, send a newline, wait 1 second, then type `bar` | ||||||
|  | and send another newline: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | input: | | ||||||
|  |   foo | ||||||
|  |   DELAY: 1 | ||||||
|  |   bar | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Why is this useful? Unfortunately, many languages have race conditions | ||||||
|  | and will fail to notice input if you send it before they have finished | ||||||
|  | starting up. | ||||||
|  | 
 | ||||||
|  | Finally, this will type `foo` and then send a newline followed by an | ||||||
|  | EOF: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | input: | | ||||||
|  |   foo | ||||||
|  |   EOF | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Broken tests | ||||||
|  | 
 | ||||||
|  | We try very hard to get tests working for every newly added language. | ||||||
|  | However, sometimes there's something truly puzzling going on that's | ||||||
|  | not worth blocking a new language being added. For that reason it's | ||||||
|  | possible to mark a test as temporarily skipped, e.g.: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | skip: | ||||||
|  |   - repl | ||||||
|  |   - runrepl | ||||||
|  |   - scope | ||||||
|  |   - lsp | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | This is unfortunately currently the case for many of the LSP tests due | ||||||
|  | to the fragility of most language servers. | ||||||
|  |  | ||||||
|  | @ -48,6 +48,7 @@ moreutils | ||||||
| nodejs | nodejs | ||||||
| packer | packer | ||||||
| psmisc | psmisc | ||||||
|  | python3-pip | ||||||
| pwgen | pwgen | ||||||
| skopeo | skopeo | ||||||
| ssh | ssh | ||||||
|  | @ -65,6 +66,8 @@ yarn | ||||||
| apt-get update | apt-get update | ||||||
| apt-get install -y $(sed 's/#.*//' <<< "${packages}") | apt-get install -y $(sed 's/#.*//' <<< "${packages}") | ||||||
| 
 | 
 | ||||||
|  | pip3 install ec2instanceconnectcli | ||||||
|  | 
 | ||||||
| wget -nv https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -O awscli.zip | wget -nv https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -O awscli.zip | ||||||
| unzip -q awscli.zip | unzip -q awscli.zip | ||||||
| ./aws/install | ./aws/install | ||||||
|  |  | ||||||
|  | @ -23,8 +23,8 @@ | ||||||
|      window.rijuConfig = <%- JSON.stringify(config) %>; |      window.rijuConfig = <%- JSON.stringify(config) %>; | ||||||
|     </script> |     </script> | ||||||
|     <script src="/js/app.js"></script> |     <script src="/js/app.js"></script> | ||||||
|     <% if (analyticsEnabled) { %> |     <% if (fathomSiteId) { %> | ||||||
|       <script src="https://cdn.usefathom.com/script.js" site="JOBZEHJE" defer></script> |       <script src="https://cdn.usefathom.com/script.js" data-site="<%= fathomSiteId %>" defer></script> | ||||||
|     <% } %> |     <% } %> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -30,8 +30,8 @@ | ||||||
|     <% } else { %> |     <% } else { %> | ||||||
|       <i>Riju is loading language configuration...</i> |       <i>Riju is loading language configuration...</i> | ||||||
|     <% } %> |     <% } %> | ||||||
|     <% if (analyticsEnabled) { %> |     <% if (fathomSiteId) { %> | ||||||
|       <script src="https://cdn.usefathom.com/script.js" site="JOBZEHJE" defer></script> |       <script src="https://cdn.usefathom.com/script.js" data-site="<%= fathomSiteId %>" defer></script> | ||||||
|     <% } %> |     <% } %> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ install: | ||||||
| repl: | | repl: | | ||||||
|   abc |   abc | ||||||
| input: | | input: | | ||||||
|   DELAY: 1 |   DELAY: 2 | ||||||
|   WRITE 123 * 234 |   WRITE 123 * 234 | ||||||
| 
 | 
 | ||||||
| main: "main.abc" | main: "main.abc" | ||||||
|  |  | ||||||
|  | @ -17,29 +17,38 @@ install: | ||||||
|     - purescript |     - purescript | ||||||
|     - spago |     - spago | ||||||
|   manual: | |   manual: | | ||||||
|     install -d "${pkg}/opt/purescript" |     install -d "${pkg}/opt/purescript/skel-home" | ||||||
|  |     install -d "${pkg}/opt/purescript/skel-src" | ||||||
| 
 | 
 | ||||||
|     mkdir skel |  | ||||||
|     pushd skel |  | ||||||
|     spago init -C |     spago init -C | ||||||
|     rm -rf .gitignore test |     rm -rf .gitignore test | ||||||
|     sed -i 's#, "test/\*\*/\*\.purs"##' spago.dhall |     sed -i 's#, "test/\*\*/\*\.purs"##' spago.dhall | ||||||
|     cat <<"EOF" > src/Main.spago | 
 | ||||||
|  |     cat <<"EOF" > src/Main.purs | ||||||
|  |     module Main where | ||||||
|  | 
 | ||||||
|     import Prelude |     import Prelude | ||||||
| 
 | 
 | ||||||
|     import Effect (Effect) |     import Effect (Effect) | ||||||
|  |     import Effect.Console (log) | ||||||
| 
 | 
 | ||||||
|     main :: Effect Unit |     main :: Effect Unit | ||||||
|     main = pure unit |     main = log "Hello, world!" | ||||||
|     EOF |     EOF | ||||||
|  | 
 | ||||||
|     spago build |     spago build | ||||||
|     spago repl < /dev/null |     spago repl < /dev/null | ||||||
|  | 
 | ||||||
|     rm -rf src |     rm -rf src | ||||||
|     popd | 
 | ||||||
|     cp -R skel "${pkg}/opt/purescript/" |     shopt -s dotglob | ||||||
|  |     cp -R --preserve=timestamps * "${pkg}/opt/purescript/skel-src/" | ||||||
|  |     cp -R --preserve=timestamps "${HOME}/.cache" "${pkg}/opt/purescript/skel-home/" | ||||||
| 
 | 
 | ||||||
| setup: | | setup: | | ||||||
|   shopt -s dotglob; cp -R /opt/purescript/skel/* "$PWD/" |   shopt -s dotglob | ||||||
|  |   cp -R --preserve=timestamps /opt/purescript/skel-home/* "${HOME}/" | ||||||
|  |   cp -R --preserve=timestamps /opt/purescript/skel-src/* "${PWD}/" | ||||||
| 
 | 
 | ||||||
| repl: | | repl: | | ||||||
|   spago repl |   spago repl | ||||||
|  |  | ||||||
|  | @ -902,7 +902,7 @@ properties: | ||||||
|   format: |   format: | ||||||
|     type: object |     type: object | ||||||
|     additionalProperties: false |     additionalProperties: false | ||||||
|     required: [run] |     required: [run, input] | ||||||
|     properties: |     properties: | ||||||
|       run: |       run: | ||||||
|         type: string |         type: string | ||||||
|  |  | ||||||
|  | @ -51,6 +51,7 @@ sudo sed -Ei 's/^#?PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config | ||||||
| sudo sed -Ei 's/^#?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config | sudo sed -Ei 's/^#?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config | ||||||
| sudo sed -Ei 's/^#?PermitEmptyPasswords .*/PermitEmptyPasswords no/' /etc/ssh/sshd_config | sudo sed -Ei 's/^#?PermitEmptyPasswords .*/PermitEmptyPasswords no/' /etc/ssh/sshd_config | ||||||
| sudo sed -Ei "s/\\\$AWS_REGION/${AWS_REGION}/" /etc/systemd/system/riju.service | sudo sed -Ei "s/\\\$AWS_REGION/${AWS_REGION}/" /etc/systemd/system/riju.service | ||||||
|  | sudo sed -Ei "s/\\\$FATHOM_SITE_ID/${FATHOM_SITE_ID:-}/" /etc/systemd/system/riju.service | ||||||
| sudo sed -Ei "s/\\\$S3_BUCKET/${S3_BUCKET}/" /etc/systemd/system/riju.service | sudo sed -Ei "s/\\\$S3_BUCKET/${S3_BUCKET}/" /etc/systemd/system/riju.service | ||||||
| sudo sed -Ei "s/\\\$SUPERVISOR_ACCESS_TOKEN/${SUPERVISOR_ACCESS_TOKEN}/" /etc/systemd/system/riju.service | sudo sed -Ei "s/\\\$SUPERVISOR_ACCESS_TOKEN/${SUPERVISOR_ACCESS_TOKEN}/" /etc/systemd/system/riju.service | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ ExecStart=riju-supervisor | ||||||
| Restart=always | Restart=always | ||||||
| RestartSec=5 | RestartSec=5 | ||||||
| Environment=AWS_REGION=$AWS_REGION | Environment=AWS_REGION=$AWS_REGION | ||||||
|  | Environment=FATHOM_SITE_ID=$FATHOM_SITE_ID | ||||||
| Environment=S3_BUCKET=$S3_BUCKET | Environment=S3_BUCKET=$S3_BUCKET | ||||||
| Environment=SUPERVISOR_ACCESS_TOKEN=$SUPERVISOR_ACCESS_TOKEN | Environment=SUPERVISOR_ACCESS_TOKEN=$SUPERVISOR_ACCESS_TOKEN | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -347,11 +347,13 @@ func (sv *supervisor) reload() error { | ||||||
| 		"-v", "/var/run/riju:/var/run/riju", | 		"-v", "/var/run/riju:/var/run/riju", | ||||||
| 		"-v", "/var/run/docker.sock:/var/run/docker.sock", | 		"-v", "/var/run/docker.sock:/var/run/docker.sock", | ||||||
| 		"-p", fmt.Sprintf("127.0.0.1:%d:6119", port), | 		"-p", fmt.Sprintf("127.0.0.1:%d:6119", port), | ||||||
|  | 		"-e", "FATHOM_SITE_ID", | ||||||
| 		"-e", "RIJU_DEPLOY_CONFIG", | 		"-e", "RIJU_DEPLOY_CONFIG", | ||||||
| 		"-e", "ANALYTICS=1", |  | ||||||
| 		"--label", fmt.Sprintf("riju.deploy-config-hash=%s", deployCfgHash), | 		"--label", fmt.Sprintf("riju.deploy-config-hash=%s", deployCfgHash), | ||||||
| 		"--name", name, | 		"--name", name, | ||||||
| 		"--restart=unless-stopped", | 		"--restart", "unless-stopped", | ||||||
|  | 		"--oom-kill-disable", | ||||||
|  | 		"--cpu-shares", "2048", | ||||||
| 		fmt.Sprintf("riju:%s", deployCfg.AppImageTag), | 		fmt.Sprintf("riju:%s", deployCfg.AppImageTag), | ||||||
| 	) | 	) | ||||||
| 	dockerRun.Stdout = os.Stdout | 	dockerRun.Stdout = os.Stdout | ||||||
|  |  | ||||||
|  | @ -107,9 +107,9 @@ void session(char *uuid, char *lang, char *imageHash) | ||||||
|       "--user", "root", |       "--user", "root", | ||||||
|       "--hostname", lang, |       "--hostname", lang, | ||||||
|       "--name", container, |       "--name", container, | ||||||
|       "--cpus", "0.25", |       "--cpus", "1", | ||||||
|       "--memory", "100m", |       "--memory", "1g", | ||||||
|       "--memory-swap", "900m", |       "--memory-swap", "3g", | ||||||
|       image, "bash", "-c", |       image, "bash", "-c", | ||||||
|       "cat /var/run/riju/sentinel/fifo | ( sleep 10; while read -t2; do :; done; pkill -g0 )", |       "cat /var/run/riju/sentinel/fifo | ( sleep 10; while read -t2; do :; done; pkill -g0 )", | ||||||
|       NULL, |       NULL, | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| terraform { | terraform { | ||||||
|   backend "s3" { |   backend "s3" { | ||||||
|     key    = "state" |     key    = "state" | ||||||
|     region = "us-west-1" |  | ||||||
|   } |   } | ||||||
|   required_providers { |   required_providers { | ||||||
|     aws = { |     aws = { | ||||||
|  | @ -30,7 +29,6 @@ locals { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| provider "aws" { | provider "aws" { | ||||||
|   region = "us-west-1" |  | ||||||
|   default_tags { |   default_tags { | ||||||
|     tags = local.tags |     tags = local.tags | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -2,5 +2,5 @@ | ||||||
| 
 | 
 | ||||||
| set -euo pipefail | set -euo pipefail | ||||||
| 
 | 
 | ||||||
| make ecr system | make ecr | ||||||
| make env CMD="dep deploy:live --publish --yes" Z=xz CI=1 TEST_PATIENCE=4 TEST_CONCURRENCY=1 | make env CMD="dep deploy:live --publish --yes" Z=xz CI=1 TEST_PATIENCE=4 TEST_CONCURRENCY=1 | ||||||
|  |  | ||||||
|  | @ -276,7 +276,7 @@ async function getDeployLiveArtifact(langs) { | ||||||
|     dependencies: ["deploy:ready"], |     dependencies: ["deploy:ready"], | ||||||
|     publishTarget: true, |     publishTarget: true, | ||||||
|     publishToRegistry: async () => { |     publishToRegistry: async () => { | ||||||
|       await runCommand(`make deploy`); |       await runCommand(`make deploy-latest`); | ||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | @ -679,7 +679,7 @@ async function main() { | ||||||
|   if (program.args.length === 0) { |   if (program.args.length === 0) { | ||||||
|     program.help({ error: true }); |     program.help({ error: true }); | ||||||
|   } |   } | ||||||
|   await runCommand("make all-scripts"); |   await runCommand("make all-scripts system"); | ||||||
|   await executeDepGraph({ |   await executeDepGraph({ | ||||||
|     depgraph, |     depgraph, | ||||||
|     manual, |     manual, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Radon Rosborough
						Radon Rosborough