Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/habitat package #2453

Merged
merged 10 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bldr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ paths = [
]
pkg_targets = [
"x86_64-linux"
]
]
4 changes: 1 addition & 3 deletions .expeditor/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ pipelines:
- habitat/verify:
public: true
definition: .expeditor/verify.habitat-packages.yml
- omnibus/release:
env:
- IGNORE_CACHE: true
- omnibus/release
- omnibus/adhoc:
definition: .expeditor/release.omnibus.yml
env:
Expand Down
78 changes: 78 additions & 0 deletions bin/ci/check-bad-patterns.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env bash

set -euo pipefail
plan_path=$1

hab_usage=()
sleep_usage=()
exit_code=0

# Until the following PRs land, we cannot sleep in a lifecycle hook
# with the exception of 'run'
# habitat-sh/habitat#5954
# habitat-sh/habitat#5955
# habitat-sh/habitat#5956
# habitat-sh/habitat#5957
# habitat-sh/habitat#5958
# habitat-sh/habitat#5959
check_for_sleep() {
local file

file="$1"
# Match lines containing `sleep N`, ignoring comments
match="^([^#])*sleep [0-9]+"

if grep -qE "$match" "$file"; then
sleep_usage+=("$file")
exit_code=1
fi
}

check_for_hab() {
local file

file="$1"
# Match anything that looks like we're attempting to call the hab cli
# ignoring comments
match="^([^#])*(\(\s*|\s+)hab\s"
if grep -E -q "$match" "$file"; then
hab_usage+=("$file")
exit_code=1
fi
}

echo "--- :thinking_face: [$plan_path] Checking for bad patterns"
readarray -t files < <(find "$plan_path" -type f)

for file in "${files[@]}"; do
case $file in
*/plan.sh | */plan.ps1 )
check_for_sleep "$file"
;;
*hooks/run )
check_for_hab "$file"
;;
*hooks/*)
check_for_hab "$file"
check_for_sleep "$file"
;;
**)
echo "Skipping $file"
;;
esac
done

if [[ "${#hab_usage[@]}" -ne 0 ]]; then
echo "--- :habicat: The following files appear to be calling 'hab'"
printf "%s\n" "${hab_usage[@]}"
fi

if [[ "${#sleep_usage[@]}" -ne 0 ]]; then
echo "--- :sleep: The following files appear to be calling 'sleep'"
printf "%s\n" "${sleep_usage[@]}"
fi

if [[ "$exit_code" -eq 0 ]]; then
echo "--- :smiling_face: [$plan_path] No bad patterns found!"
fi
exit "$exit_code"
35 changes: 35 additions & 0 deletions bin/ci/check-default-variables.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

set -euo pipefail

required_variables=(
pkg_description
pkg_license
pkg_maintainer
pkg_name
pkg_origin
pkg_upstream_url
)

plan_path="$1"

retval=0

echo "--- :open_book: [$plan_path] Checking for default variables"
for var in "${required_variables[@]}"; do
if ! grep -Eq "^$var" "$plan_path/plan.sh"; then
echo " Unable to find '$var' in $*"
retval=1
fi
done


if [[ $retval -ne 0 ]]; then
echo "--- :octogonal_sign: Missing required variables"
echo "Ensure that your plan.sh contains all of:"
IFS=$'\n'; echo "${required_variables[*]}"
else
echo "--- :closed_book: [$plan_path] Found all default variables"
fi

exit $retval
46 changes: 46 additions & 0 deletions bin/ci/shellcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

set -euo pipefail

# Run shellcheck against any files that appear to be shell script based on
# filename or `file` output
# Exclude *.ps1 files because shellcheck doesn't support them
# Exclude hooks and config because the handlebars syntax confuses shellcheck
# Exclude the following shellcheck issues since they're pervasive and innocuous:
# https://github.com/koalaman/shellcheck/wiki/SC1008
# https://github.com/koalaman/shellcheck/wiki/SC1083
# https://github.com/koalaman/shellcheck/wiki/SC1090
# https://github.com/koalaman/shellcheck/wiki/SC1091
# https://github.com/koalaman/shellcheck/wiki/SC1117
# https://github.com/koalaman/shellcheck/wiki/SC2027
# https://github.com/koalaman/shellcheck/wiki/SC2034
# https://github.com/koalaman/shellcheck/wiki/SC2039
# https://github.com/koalaman/shellcheck/wiki/SC2140
# https://github.com/koalaman/shellcheck/wiki/SC2148
# https://github.com/koalaman/shellcheck/wiki/SC2153
# https://github.com/koalaman/shellcheck/wiki/SC2154
# https://github.com/koalaman/shellcheck/wiki/SC2164
# https://github.com/koalaman/shellcheck/wiki/SC2239

SHELLCHECK_IGNORE="SC1008,SC1083,SC1090,SC1091,SC1117,SC2027,SC2034,SC2039,SC2140,SC2148,SC2153,SC2154,SC2164,SC2239"

plan_path="$1"

echo "--- :bash: [$plan_path] Running shellcheck"

# Record what version of shellcheck we used in this CI run
shellcheck --version

find "$plan_path" -type f \
-and \( -name "*.*sh" \
-or -exec sh -c 'file -b "$1" | grep -q "shell script"' -- {} \; \) \
-and \! -path "*.ps1" \
-and \! -path "$plan_path/hooks/*" \
-and \! -path "$plan_path/config/*" \
-print0 \
| xargs -0 shellcheck --external-sources --exclude="${SHELLCHECK_IGNORE}"

# shellcheck disable=SC2181
if [[ $? -eq 0 ]]; then
echo "--- :shell: [$plan_path] Shellcheck run successful"
fi
98 changes: 98 additions & 0 deletions dev-docs/habitat_configurations_for_development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Steps to get habitat services up and running in dev environment

## Prerequisites

1. Install [Docker Desktop](https://www.docker.com/get-started). Start docker before trying to start the Habitat Studio.
2. [Install](https://docs.chef.io/habitat/install_habitat/) Chef Habitat. The Habitat package installs with Chef Workstation so you may already have it on your computer.
3. [Set up](https://docs.chef.io/habitat/hab_setup/) the Habitat CLI with the command `hab cli setup`.
- Habitat Builder Instance: No
- Set up a default origin: Yes
- Habitat Personal Access Token: Yes PROVIDE value as `chef`
- Supervisor Control Gateway Secret: No

Start with `hab studio enter`

## Create supermarket user in the hab environment

`hab pkg exec core/busybox-static adduser supermarket`

## Create openssl certificates required for nginx

`hab pkg exec core/openssl openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /hab/svc/supermarket-nginx/cert.key -out /hab/svc/supermarket-nginx/cert.cert`


## default.toml changes

1. postgresql \
listen_addresses = ['*']

2. redis \
bind = [*]

3. habitat-web

fqdn = 'localhost'\
port = 3000\
secret_key_base = "<appropriate value>"\
protocol = 'https'\
allowed_host = "localhost"

[nginx]\
force_ssl = true\
port = 4000\
ssl_port = 4000

[fieri]
url = 'http://localhost:3000/fieri/jobs'
supermarket_endpoint = 'http://localhost:3000'

### All the chef-server configurations will also be done in this file itself

4. nginx

[ssl]\
enabled = true\
certificate = "cert.cert"\
certificate_key = "cert.key"

5. habitat-sidekiq \
secret_key_base = "<appropriate value>"

## pg_hba.conf changes
Add this line in file `postgresq/config/pg_hba.conf` this is required for local development
since we are not making postgres listen to system ip

```
host all all 0.0.0.0/0 md5
```

## use the following file for nginx/config/sites_enabled/rails in dev setup

```
server {
listen 4000 ssl;
server_name localhost;
ssl_certificate cert.cert;
ssl_certificate_key cert.key;

location / {
proxy_pass http://localhost:3000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $http_port;
proxy_set_header origin 'https://localhost:4000';
}
}
```

## load services
run script `./load_hab_services.sh` to build and load all the services from local
In case you need to unload all the running services use script `./unload_hab_services`

## Once the services are loaded, you should be able to access the application from browser
`https://localhost:4000`



20 changes: 20 additions & 0 deletions load_hab_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash -e

# This script builds the services from local folder and loads them to habitat studio

# delete the results folder if any
rm -rf results/

# build services
build redis
build nginx
build postgresql
build src/supermarket/habitat-sidekiq
build src/supermarket/habitat-web

## load services
hab svc load chef/supermarket-postgresql
hab svc load chef/supermarket-redis
hab svc load chef/supermarket --bind database:supermarket-postgresql.default --bind redis:supermarket-redis.default
hab svc load chef/supermarket-nginx --bind rails:supermarket.default
hab svc load chef/supermarket-sidekiq --bind redis:supermarket-redis.default --bind database:supermarket-postgresql.default --bind rails:supermarket.default
35 changes: 35 additions & 0 deletions nginx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Nginx

This package wraps the [Chef Base Plans Nginx Package](https://github.com/chef-base-plans/nginx). More documentation can be found in the original package repository's [README](https://github.com/chef-base-plans/nginx#readme) and the [Nginx documentation](https://www.nginx.org/docs/).

This document is to be used in addition to the previous two documents and will not cover Nginx configurations or the package specifics in depth (such as bindings, topologies, update strategies), but will focus on the usage of the application package in the Supermarket context.

## Maintainers

* The Chef Maintainers <humans@chef.io>

## Type of Package

Service package

## Usage

This plan should be used by starting the service with:

```
$ hab [svc load|start] chef/supermarket-nginx --bind rails:supermarket.default
```

Note: It requires a binding to the rails (web) application.

The package hooks will run as the `root:root` but will make use of `worker[user|group]` configuration values (`supermarket:supermarket` by default) for the worker processes.

## Bindings

The application provides no exports but requires a bind to the rails web server providing the port the server is listening on, the ports nginx should listen on, the SSL switch, as well as the FQDN. Note that FQDN comes in two properties as a sanitized version is required for the redirect configuration, but habitat configuration templating does not provide a way to modify values.

## Configuration

Every available configuration item is given a reasonable default. Generally a user should only have to modify `ssl` configurations as the service port (i.e. the port the rails application is listening on) is pulled in through the bind - as well as the ports nginx itself will listen on. This seems a bit of an anti-pattern but due to the need for the rails application itself to be aware of the particular port to build URLs to itself, this allows this configuration value to be set once and propagated for the application and the proxy.

Most of the configuration files are directly copied from the Chef Base Plans repository with additional values/configurations inserted for Supermarket specific defaults or to allow for additional items to be configured that were not configurable in the original package (such as log directory).
Loading