-
Notifications
You must be signed in to change notification settings - Fork 26
/
integration.sh
executable file
·197 lines (173 loc) · 5.68 KB
/
integration.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#! /bin/bash
# preflight
set -ev
unset BUNDLE_GEMFILE
K8S_VERSION='1.19.10-00'
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y jq kubelet=$K8S_VERSION kubeadm=$K8S_VERSION kubectl=$K8S_VERSION
cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
podSubnet: "192.168.0.0/16"
controllerManager:
extraArgs:
enable-hostpath-provisioner: "true"
EOF
sudo kubeadm init --config ./kubeadm-config.yaml
# copy kubeconfig to default location so kubectl works
mkdir -p ~/.kube
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
# start up the calico CNI
kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml
# make hostpath storage class available
cat <<'EOF' | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
namespace: kube-system
name: hostpath
annotations:
storageclass.beta.kubernetes.io/is-default-class: "true"
labels:
addonmanager.kubernetes.io/mode: EnsureExists
provisioner: kubernetes.io/host-path
EOF
# allow pods to be scheduled on the master node
kubectl taint nodes --all node-role.kubernetes.io/master-
# clone rails app
gem install prebundler -v '< 1'
git clone --depth=1 https://github.com/getkuby/kuby_test.git
cd kuby_test
printf "\ngem 'kuby-core', github: 'getkuby/kuby-core', branch: '${GITHUB_REF##*/}'\n" >> Gemfile
bundle lock
cat <<'EOF' > .prebundle_config
Prebundler.configure do |config|
config.storage_backend = Prebundler::S3Backend.new(
client: Aws::S3::Client.new(
region: 'default',
credentials: Aws::Credentials.new(
ENV['PREBUNDLER_ACCESS_KEY_ID'],
ENV['PREBUNDLER_SECRET_ACCESS_KEY']
),
endpoint: 'https://us-east-1.linodeobjects.com',
http_continue_timeout: 0
),
bucket: 'prebundler',
region: 'us-east-1'
)
end
EOF
prebundle install --jobs 2 --retry 3
yarn install
bundle exec bin/rails g kuby
cat <<'EOF' > kuby.rb
class PrebundlerPhase < Kuby::Docker::BundlerPhase
def apply_to(dockerfile)
dockerfile.arg('PREBUNDLER_ACCESS_KEY_ID')
dockerfile.arg('PREBUNDLER_SECRET_ACCESS_KEY')
dockerfile.copy('.prebundle_config', '.')
dockerfile.run('gem', 'install', 'prebundler', '-v', "'< 1'")
super
dockerfile.commands.each do |cmd|
next unless cmd.is_a?(Kuby::Docker::Dockerfile::Run)
if cmd.args[0..1] == ['bundle', 'install']
cmd.args[0] = 'prebundle'
end
end
end
end
require 'active_support/core_ext'
require 'active_support/encrypted_configuration'
# keep this in here to make sure RAILS_MASTER_KEY is being provided somehow
app_creds = ActiveSupport::EncryptedConfiguration.new(
config_path: File.join('config', 'credentials.yml.enc'),
key_path: File.join('config', 'master.key'),
env_key: 'RAILS_MASTER_KEY',
raise_if_missing_key: true
)
Kuby.define('Kubyapp') do
environment(:production) do
docker do
image_url 'localhost:5000/kubyapp'
insert :prebundler_phase, PrebundlerPhase.new(environment), after: :bundler_phase
delete :bundler_phase
end
kubernetes do
add_plugin :rails_app do
tls_enabled false
database do
user 'kubyapp'
password 'password'
end
end
provider :bare_metal
end
end
end
EOF
cat <<'EOF' > config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: localhost
development:
<<: *default
database: kubyapp_development
production:
<<: *default
database: kubyapp_production
EOF
cat <<'EOF' > config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
end
EOF
cat <<'EOF' > app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
end
end
EOF
mkdir app/views/home/
touch app/views/home/index.html.erb
# start docker registry
docker run -d -p 5000:5000 --name registry registry:2
# build and push
GLI_DEBUG=true bundle exec kuby -e production build -a PREBUNDLER_ACCESS_KEY_ID=${PREBUNDLER_ACCESS_KEY_ID} -a PREBUNDLER_SECRET_ACCESS_KEY=${PREBUNDLER_SECRET_ACCESS_KEY}
GLI_DEBUG=true bundle exec kuby -e production push
# setup cluster
GLI_DEBUG=true bundle exec kuby -e production setup
# force nginx ingress to be a nodeport since we don't have any load balancers
kubectl -n ingress-nginx patch svc ingress-nginx -p '{"spec":{"type":"NodePort"}}'
# deploy!
GLI_DEBUG=true bundle exec kuby -e production deploy || true
while [[ "$(kubectl -n kubyapp-production get po kubyapp-web-mysql-0 -o json | jq -r .status.phase)" != "Running" ]]; do
echo "Waiting for MySQL pod to start..."
sleep 5
done
# Do this three times in case the db doesn't start in time and the deploy fails.
# This can happen even after waiting for the pod to start above, not sure why.
GLI_DEBUG=true bundle exec kuby -e production deploy ||
GLI_DEBUG=true bundle exec kuby -e production deploy ||
GLI_DEBUG=true bundle exec kuby -e production deploy
# get ingress IP from kubectl; attempt to hit the app
ingress_ip=$(kubectl -n ingress-nginx get svc ingress-nginx -o json | jq -r .spec.clusterIP)
curl -vvv $ingress_ip:80 \
-H "Host: localhost"\
--fail \
--connect-timeout 5 \
--max-time 10 \
--retry 5 \
--retry-max-time 40 || exit $?
# execute remote command
GLI_DEBUG=true bundle exec kuby -e production remote exec "bundle exec rails runner 'puts \"Hello from Kuby\"'" | grep "Hello from Kuby"