Initial version
commit
1b52bb2620
|
|
@ -0,0 +1,3 @@
|
|||
ansible/inventory.yml
|
||||
debian10-ssh.img
|
||||
vm.xml
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM golang:latest as gobuild
|
||||
RUN mkdir /app
|
||||
ADD . /app
|
||||
WORKDIR /app
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -ldflags '-w -extldflags "-static"' -o go-backend
|
||||
|
||||
FROM scratch
|
||||
COPY --from=gobuild /app/go-backend /bin/go-backend
|
||||
ENTRYPOINT ["/bin/go-backend"]
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
|||
module immfly/go-backend
|
||||
|
||||
go 1.20
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func clock(w http.ResponseWriter, r *http.Request) {
|
||||
currentTime := float64(time.Now().UnixMicro())/float64(1e6)
|
||||
io.WriteString(w, fmt.Sprintf("%07f", currentTime))
|
||||
}
|
||||
|
||||
func main() {
|
||||
port, ok := os.LookupEnv("BACKEND_PORT")
|
||||
if !ok {
|
||||
//Default value 5050
|
||||
port = "5050"
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.HandleFunc("/clock", clock)
|
||||
|
||||
fmt.Printf("Starting backend server in port %s\n", port)
|
||||
err := http.ListenAndServe(fmt.Sprintf(":%s", port), mux)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to start server: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
|
||||
- name: Copy backend files
|
||||
ansible.builtin.copy:
|
||||
src: go-backend
|
||||
dest: /home/nonroot/
|
||||
owner: nonroot
|
||||
group: nonroot
|
||||
|
||||
- name: Build image with go-backend
|
||||
community.docker.docker_image:
|
||||
build:
|
||||
path: /home/nonroot/go-backend
|
||||
name: go-backend
|
||||
source: build
|
||||
|
||||
- name: Start the docker image to serve the backend
|
||||
community.docker.docker_container:
|
||||
name: backend
|
||||
image: go-backend
|
||||
exposed_ports:
|
||||
- 5050
|
||||
become_user: nonroot
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
# https://docs.docker.com/engine/install/debian/
|
||||
|
||||
- name: Ensure required packages are installed
|
||||
apt:
|
||||
name: [
|
||||
'ca-certificates',
|
||||
'curl',
|
||||
'gnupg',
|
||||
'lsb-release',
|
||||
]
|
||||
state: latest
|
||||
|
||||
- name: We add the docker key to the keyring
|
||||
block:
|
||||
- name: Ensure directory exists
|
||||
file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: '0755'
|
||||
- name: We download the key
|
||||
ansible.builtin.apt_key:
|
||||
url: https://download.docker.com/linux/debian/gpg
|
||||
keyring: /etc/apt/keyrings/docker.gpg
|
||||
|
||||
- name: We add the docker repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"
|
||||
state: present
|
||||
filename: docker
|
||||
|
||||
- name: Docker installation
|
||||
apt:
|
||||
name: [
|
||||
'docker-ce',
|
||||
'docker-ce-cli',
|
||||
'containerd.io',
|
||||
'docker-buildx-plugin',
|
||||
'docker-compose-plugin',
|
||||
]
|
||||
state: latest
|
||||
|
||||
- name: Create a nonroot user to run docker images
|
||||
ansible.builtin.user:
|
||||
name: nonroot
|
||||
shell: /bin/bash
|
||||
groups: docker
|
||||
|
||||
- name: Install python dependencies to use docker community module
|
||||
block:
|
||||
- name: Install python pip
|
||||
apt:
|
||||
name: python3-pip
|
||||
state: latest
|
||||
- name: Install docker pip sdk
|
||||
ansible.builtin.pip:
|
||||
name: docker
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Clocker</title>
|
||||
<style type="text/css">
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #030303;
|
||||
color: #42eef4;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.clock {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
font-family: monospace;
|
||||
text-shadow: 0 0 10px #42eef4;
|
||||
}
|
||||
|
||||
#clockTime {
|
||||
font-size: 8em;
|
||||
}
|
||||
|
||||
#clockDate {
|
||||
font-size: 4em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="clock">
|
||||
<div id="clockTime"></div>
|
||||
<div id="clockDate"></div>
|
||||
</div>
|
||||
<script>
|
||||
((window, document, undefined) =>
|
||||
{
|
||||
'use strict';
|
||||
|
||||
const CLOCK_URL = '/clock';
|
||||
|
||||
const clockTime = document.getElementById('clockTime');
|
||||
const clockDate = document.getElementById('clockDate');
|
||||
|
||||
function fetchEpoch(onFetch)
|
||||
{
|
||||
return fetch(CLOCK_URL)
|
||||
.then(response =>
|
||||
response.text().then(onFetch)
|
||||
);
|
||||
}
|
||||
|
||||
function refreshClock()
|
||||
{
|
||||
return fetchEpoch(setClockEpoch);
|
||||
}
|
||||
|
||||
function setClockEpoch(epoch)
|
||||
{
|
||||
const date = new Date(0);
|
||||
date.setUTCSeconds(epoch);
|
||||
clockTime.textContent = formatTime(date);
|
||||
clockDate.textContent = formatDate(date);
|
||||
}
|
||||
|
||||
function formatDate(date)
|
||||
{
|
||||
return [
|
||||
('0' + date.getDate()).slice(-2),
|
||||
('0' + (date.getMonth() + 1)).slice(-2),
|
||||
date.getFullYear(),
|
||||
].join('/');
|
||||
}
|
||||
|
||||
function formatTime(date)
|
||||
{
|
||||
return [
|
||||
("0" + date.getHours()).slice(-2),
|
||||
("0" + date.getMinutes()).slice(-2),
|
||||
("0" + date.getSeconds()).slice(-2),
|
||||
].join(':');
|
||||
}
|
||||
|
||||
function clockInterval(interval)
|
||||
{
|
||||
return setInterval(refreshClock, interval || 500)
|
||||
}
|
||||
|
||||
clockInterval();
|
||||
|
||||
})(window, document, undefined);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
|
||||
access_log /var/log/nginx/host.access.log main;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /clock {
|
||||
proxy_pass http://backend:5050/clock;
|
||||
}
|
||||
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
#
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
|
||||
- name: Ensure frontend dir exists
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
owner: nonroot
|
||||
group: nonroot
|
||||
state: directory
|
||||
mode: '0755'
|
||||
with_items:
|
||||
- "/home/nonroot/frontend/html"
|
||||
- "/home/nonroot/frontend/config"
|
||||
|
||||
- name: Copy the frontend files
|
||||
copy:
|
||||
src: "{{ item.file }}"
|
||||
dest: "/home/nonroot/frontend/{{ item.dest }}"
|
||||
owner: nonroot
|
||||
group: nonroot
|
||||
with_items:
|
||||
- { file: 'index.html', dest: "html" }
|
||||
- { file: 'nginx.conf', dest: "config" }
|
||||
|
||||
|
||||
- name: Start an nginx image to serve the files
|
||||
community.docker.docker_container:
|
||||
name: frontend
|
||||
image: nginx
|
||||
links:
|
||||
- backend
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- /home/nonroot/frontend/html:/usr/share/nginx/html
|
||||
- /home/nonroot/frontend/config/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
become_user: nonroot
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
# This playbook will install
|
||||
# docker requirements to run the docker machines
|
||||
# backend developed in go and running in a docker machine
|
||||
# frontend serving static page using nginx
|
||||
|
||||
- name: tech-test-infra
|
||||
hosts: immfly_debian10
|
||||
|
||||
roles:
|
||||
- docker
|
||||
- backend
|
||||
- frontend
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Clocker</title>
|
||||
<style type="text/css">
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #030303;
|
||||
color: #42eef4;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.clock {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
font-family: monospace;
|
||||
text-shadow: 0 0 10px #42eef4;
|
||||
}
|
||||
|
||||
#clockTime {
|
||||
font-size: 8em;
|
||||
}
|
||||
|
||||
#clockDate {
|
||||
font-size: 4em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="clock">
|
||||
<div id="clockTime"></div>
|
||||
<div id="clockDate"></div>
|
||||
</div>
|
||||
<script>
|
||||
((window, document, undefined) =>
|
||||
{
|
||||
'use strict';
|
||||
|
||||
const CLOCK_URL = '/clock';
|
||||
|
||||
const clockTime = document.getElementById('clockTime');
|
||||
const clockDate = document.getElementById('clockDate');
|
||||
|
||||
function fetchEpoch(onFetch)
|
||||
{
|
||||
return fetch(CLOCK_URL)
|
||||
.then(response =>
|
||||
response.text().then(onFetch)
|
||||
);
|
||||
}
|
||||
|
||||
function refreshClock()
|
||||
{
|
||||
return fetchEpoch(setClockEpoch);
|
||||
}
|
||||
|
||||
function setClockEpoch(epoch)
|
||||
{
|
||||
const date = new Date(0);
|
||||
date.setUTCSeconds(epoch);
|
||||
clockTime.textContent = formatTime(date);
|
||||
clockDate.textContent = formatDate(date);
|
||||
}
|
||||
|
||||
function formatDate(date)
|
||||
{
|
||||
return [
|
||||
('0' + date.getDate()).slice(-2),
|
||||
('0' + (date.getMonth() + 1)).slice(-2),
|
||||
date.getFullYear(),
|
||||
].join('/');
|
||||
}
|
||||
|
||||
function formatTime(date)
|
||||
{
|
||||
return [
|
||||
("0" + date.getHours()).slice(-2),
|
||||
("0" + date.getMinutes()).slice(-2),
|
||||
("0" + date.getSeconds()).slice(-2),
|
||||
].join(':');
|
||||
}
|
||||
|
||||
function clockInterval(interval)
|
||||
{
|
||||
return setInterval(refreshClock, interval || 500)
|
||||
}
|
||||
|
||||
clockInterval();
|
||||
|
||||
})(window, document, undefined);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
|
||||
all:
|
||||
hosts:
|
||||
immfly_debian10:
|
||||
ansible_host: VM_IP
|
||||
ansible_ssh_private_key_file: ../assets/rsa
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
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
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAuOMkJ8KVP/ws/wFdQSbuJKGYAhYxX+XsrFrIw6coSvjv0YkaQ3aqn2lDrWvSpwonfubSjX2/QEc1ac4yWElq4cxJqhCj6QckbhsqaLi1vUtuWilDpGO0q2iguaYbFH6/9HxrJr7HCJ+zYXX+0bMOXPnz9dyGcVnGo9MiRvFwKWrvEhXjTSApzjUxkeqEcO+qChY+GScufr6oLeZNUqk8MQLGWzMo5YiW1/1Nqj7mhqC5ovrkeIEBpkDdKQuEp0NuOWo6iRRgRLlAVZV4uYXzH4V+KpcaH7KQWj2QJefGCbfmzo8y8JpaOBSfy5iagSHsOGIKDRJcbaZzhjY/HFDhv1M4VojtvVFWBNk6sI8khU5Wwj414atH3qgRp4mgmMaa2+v/NANNuBph5gNHjJyRhfsjKol4UD8PGpkeWou3RPfGBl/Q78pTyTdxGcmF1U+1IqZY8kPCVu00QSGQzIauVNkrHI5Wrn9G3wsAzP6MOLhsUSnDhN2fVMnqXGT9Tm1tYWI8csNXpZoGdXVQcPsUdEkdoLeDSWeYvXo7L73tJ7oAsgviHwRJzizG7qRCIIyVTQ+kzllNTwvRNSGlpu/17SDTPXxDPDIMqwyduM9L9iuZaG8l/Y39Vfc9LNdJW66MegJl+xdwUnJ4ybP3M/wtXV/9J6+5yBUe/0ZhcoM9Mw==
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<domain type='qemu' id='9'>
|
||||
<name>immfly-debian10</name>
|
||||
<uuid>4b68e38d-1bbc-4327-9da1-be6f688b182a</uuid>
|
||||
<memory unit='KiB'>1048576</memory>
|
||||
<currentMemory unit='KiB'>1048576</currentMemory>
|
||||
<vcpu placement='static'>1</vcpu>
|
||||
<resource>
|
||||
<partition>/machine</partition>
|
||||
</resource>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-q35-3.1'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<vmport state='off'/>
|
||||
</features>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='${PATH_TO_VM_DISK_FILE}'/>
|
||||
<backingStore/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
<alias name='virtio-disk0'/>
|
||||
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||
</disk>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:c0:e9:b1'/>
|
||||
<source network='default' bridge='virbr0'/>
|
||||
<target dev='vnet0'/>
|
||||
<model type='virtio'/>
|
||||
<alias name='net0'/>
|
||||
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||
</interface>
|
||||
<video>
|
||||
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
|
||||
<alias name='video0'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
||||
</video>
|
||||
</devices>
|
||||
</domain>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
echo "Downloading and decompressing vm imaage"
|
||||
|
||||
if [ -f debian10-ssh.img ]; then
|
||||
echo " -> Alreday done using cached version"
|
||||
else
|
||||
wget https://immfly-infra-technical-test.s3-eu-west-1.amazonaws.com/debian10-ssh.img.tar.xz
|
||||
tar xf debian10-ssh.img.tar.xz
|
||||
rm -f debian10-ssh.img.tar.xz
|
||||
fi
|
||||
|
||||
#Fix the route in the vm file
|
||||
sed "s+\${PATH_TO_VM_DISK_FILE}+$PWD/debian10-ssh.img+" assets/vm.xml > vm.xml
|
||||
|
||||
echo "Start the VM"
|
||||
virsh create vm.xml
|
||||
|
||||
#We get the ip
|
||||
IP=`virsh domifaddr immfly-debian10 | grep ipv4 | awk '{ print $4 }' | sed 's/\/.*//'`
|
||||
echo "VM ip obtained: $IP"
|
||||
|
||||
#Pequeño hack para asegurar que la conexion ssh se ha levantado
|
||||
until ssh-keyscan $IP ; do sleep 3 ; done
|
||||
|
||||
#Upgrade the ansible inventory
|
||||
sed "s/VM_IP/$IP/" assets/inventory.yml > ansible/inventory.yml
|
||||
|
||||
#Run the playbook
|
||||
cd ansible
|
||||
ansible-playbook -i inventory.yml -v tech-test-infra.yml
|
||||
Loading…
Reference in New Issue