Compare commits
	
		
			13 Commits
		
	
	
		
			docs-reshu
			...
			local-qemu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f5c079ffc2 | |||
| 0e5dfe6bde | |||
| 2adbb8d94c | |||
| 8446d11720 | |||
| a580b04659 | |||
| 2e6894ad14 | |||
| 2e6c6517f3 | |||
| be6c1b38b7 | |||
| aa8e129913 | |||
| 71e09807a7 | |||
| 4816170c03 | |||
| 6af241e8be | |||
| c8ec53f207 | 
							
								
								
									
										14
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | --- | ||||||
|  | kind: pipeline | ||||||
|  | name: publish docker image | ||||||
|  | steps: | ||||||
|  |   - name: build and publish | ||||||
|  |     image: plugins/docker | ||||||
|  |     settings: | ||||||
|  |       username: | ||||||
|  |         from_secret: docker_reg_username_3wc | ||||||
|  |       password: | ||||||
|  |         from_secret: docker_reg_passwd_3wc | ||||||
|  |       repo: 3wordchant/capsul-flask | ||||||
|  |       tags: latest | ||||||
|  |  | ||||||
							
								
								
									
										48
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | FROM python:3.8-alpine as build | ||||||
|  |  | ||||||
|  | RUN apk add --no-cache \ | ||||||
|  |     build-base \ | ||||||
|  |     gcc \ | ||||||
|  |     gettext \ | ||||||
|  |     git \ | ||||||
|  |     jpeg-dev \ | ||||||
|  |     libffi-dev \ | ||||||
|  |     libjpeg \ | ||||||
|  |     musl-dev \ | ||||||
|  |     postgresql-dev \ | ||||||
|  |     python3-dev \ | ||||||
|  |     zlib-dev | ||||||
|  |  | ||||||
|  | RUN mkdir -p /app/{code,venv} | ||||||
|  | WORKDIR /app/code | ||||||
|  | COPY Pipfile Pipfile.lock /app/code/ | ||||||
|  |  | ||||||
|  | RUN python3 -m venv /app/venv | ||||||
|  | RUN pip install pipenv setuptools | ||||||
|  | ENV PATH="/app/venv/bin:$PATH" VIRTUAL_ENV="/app/venv" | ||||||
|  | RUN pip install wheel cppy | ||||||
|  | # Install dependencies into the virtual environment with Pipenv | ||||||
|  | RUN pipenv install --deploy --verbose | ||||||
|  |  | ||||||
|  | FROM python:3.8-alpine | ||||||
|  |  | ||||||
|  | RUN apk add --no-cache \ | ||||||
|  |     cloud-utils \ | ||||||
|  |     libjpeg \ | ||||||
|  |     libpq \ | ||||||
|  |     libstdc++ \ | ||||||
|  |     libvirt-client \ | ||||||
|  |     openssh-client \ | ||||||
|  |     virt-install | ||||||
|  |  | ||||||
|  | COPY . /app/code/ | ||||||
|  | WORKDIR /app/code | ||||||
|  |  | ||||||
|  | COPY --from=build /app/venv /app/venv | ||||||
|  | ENV PATH="/app/venv/bin:$PATH" VIRTUAL_ENV="/app/venv" | ||||||
|  |  | ||||||
|  | CMD ["gunicorn", "--bind", "0.0.0.0:5000", "-k", "gevent", "--worker-connections", "1000", "app:app"] | ||||||
|  |  | ||||||
|  | VOLUME /app/code | ||||||
|  |  | ||||||
|  | EXPOSE 5000 | ||||||
| @ -26,8 +26,24 @@ class StdoutMockFlaskMail: | |||||||
|     def send(self, message: Message): |     def send(self, message: Message): | ||||||
|       current_app.logger.info(f"Email would have been sent if configured:\n\nto: {','.join(message.recipients)}\nsubject: {message.subject}\nbody:\n\n{message.body}\n\n") |       current_app.logger.info(f"Email would have been sent if configured:\n\nto: {','.join(message.recipients)}\nsubject: {message.subject}\nbody:\n\n{message.body}\n\n") | ||||||
|  |  | ||||||
|  |  | ||||||
| load_dotenv(find_dotenv()) | load_dotenv(find_dotenv()) | ||||||
|  |  | ||||||
|  | for var_name in [ | ||||||
|  |   "SPOKE_HOST_TOKEN", "HUB_TOKEN", "STRIPE_SECRET_KEY", | ||||||
|  |   "BTCPAY_PRIVATE_KEY", "MAIL_PASSWORD" | ||||||
|  | ]: | ||||||
|  |   var = os.environ.get(f"{var_name}_FILE") | ||||||
|  |   if not var: | ||||||
|  |     continue | ||||||
|  |  | ||||||
|  |   if not os.path.isfile(var): | ||||||
|  |     continue | ||||||
|  |  | ||||||
|  |   with open(var) as secret_file: | ||||||
|  |     os.environ[var_name] = secret_file.read().rstrip('\n') | ||||||
|  |   del os.environ[f"{var_name}_FILE"] | ||||||
|  |  | ||||||
| app = Flask(__name__) | app = Flask(__name__) | ||||||
|  |  | ||||||
| app.config.from_mapping( | app.config.from_mapping( | ||||||
|  | |||||||
| @ -215,11 +215,12 @@ class CapsulFlaskHub(VirtualizationInterface): | |||||||
|         # no need to do anything here since if it cant be parsed then generic_operation will handle it. |         # no need to do anything here since if it cant be parsed then generic_operation will handle it. | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|  |     if error_message != "": | ||||||
|  |       raise ValueError(f"create capsul operation {operation_id} on {assigned_hosts} failed with {error_message}") | ||||||
|  |        | ||||||
|     if number_of_assigned != 1: |     if number_of_assigned != 1: | ||||||
|       assigned_hosts_string = ", ".join(assigned_hosts) |       assigned_hosts_string = ", ".join(assigned_hosts) | ||||||
|       raise ValueError(f"expected create capsul operation {operation_id} to be assigned to one host, it was assigned to {number_of_assigned} ({assigned_hosts_string})") |       raise ValueError(f"expected create capsul operation {operation_id} to be assigned to one host, it was assigned to {number_of_assigned} ({assigned_hosts_string})") | ||||||
|     if error_message != "": |  | ||||||
|       raise ValueError(f"create capsul operation {operation_id} on {assigned_hosts_string} failed with {error_message}") |  | ||||||
|        |        | ||||||
|  |  | ||||||
|   def destroy(self, email: str, id: str): |   def destroy(self, email: str, id: str): | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| # check available RAM and IPv4s | # check available RAM and IPv4s | ||||||
|  |  | ||||||
| ram_bytes_to_allocate="$1" | ram_bytes_to_allocate="$1" | ||||||
| ram_bytes_available=$(grep -E "^(size|memory_available_bytes)" /proc/spl/kstat/zfs/arcstats | awk '{sum+=$3} END {printf "%.0f", sum}') | ram_bytes_available="$(($(grep Available /proc/meminfo | grep -o '[0-9]*') * 1024))" | ||||||
| ram_bytes_remainder="$((ram_bytes_available - ram_bytes_to_allocate))" | ram_bytes_remainder="$((ram_bytes_available - ram_bytes_to_allocate))" | ||||||
|  |  | ||||||
| if echo "$ram_bytes_to_allocate" | grep -vqE "^[0-9]+$"; then | if echo "$ram_bytes_to_allocate" | grep -vqE "^[0-9]+$"; then | ||||||
| @ -11,8 +11,8 @@ if echo "$ram_bytes_to_allocate" | grep -vqE "^[0-9]+$"; then | |||||||
|   exit 1 |   exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # 20GB | # 0.25GB | ||||||
| if [ "$ram_bytes_remainder" -le $((20 * 1024 * 1024 * 1024)) ]; then | if [ "$ram_bytes_remainder" -le $((1 * 1024 * 1024 * 1024 / 4)) ]; then | ||||||
|   echo "VM is requesting more RAM than $(hostname -f) has available." |   echo "VM is requesting more RAM than $(hostname -f) has available." | ||||||
|   echo "Bytes requested: $ram_bytes_to_allocate" |   echo "Bytes requested: $ram_bytes_to_allocate" | ||||||
|   echo "Bytes available: $ram_bytes_available" |   echo "Bytes available: $ram_bytes_available" | ||||||
|  | |||||||
| @ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| vmname="$1" | vmname="$1" | ||||||
| template_file="/tank/img/$2" | template_file="/tank/img/$2" | ||||||
|  | qemu_tank_dir="/tank" | ||||||
| vcpus="$3" | vcpus="$3" | ||||||
| memory="$4" | memory="$4" | ||||||
| pubkeys="$5" | pubkeys="$5" | ||||||
| @ -50,40 +51,40 @@ if echo "$public_ipv4" | grep -vqE "^[0-9.]+$"; then | |||||||
|   exit 1 |   exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| disk="/tank/vm/$vmname.qcow2" | disk="$vmname.qcow2" | ||||||
| cdrom="/tank/vm/$vmname.iso" | cdrom="$vmname.iso" | ||||||
| xml="/tank/vm/$vmname.xml" | xml="$vmname.xml" | ||||||
|  |  | ||||||
| if [ -f /tank/vm/$vmname.qcow2 ]; then | if [ -f /tank/vm/$vmname.qcow2 ]; then | ||||||
|     echo "Randomly generated name matched an existing VM! Odds are like one in a billion. Buy a lotto ticket." |     echo "Randomly generated name matched an existing VM! Odds are like one in a billion. Buy a lotto ticket." | ||||||
|     exit 1 |     exit 1 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| cp "$template_file" "$disk" | cp "$template_file" "/tank/vm/$disk" | ||||||
| cp /tank/config/cyberia-cloudinit.yml /tmp/cloudinit.yml | cp /tank/config/cyberia-cloudinit.yml /tmp/cloudinit.yml | ||||||
| echo "$pubkeys" | while IFS= read -r line; do | echo "$pubkeys" | while IFS= read -r line; do | ||||||
|   echo "      - $line" >> /tmp/cloudinit.yml |   echo "      - $line" >> /tmp/cloudinit.yml | ||||||
| done | done | ||||||
|  |  | ||||||
| cloud-localds "$cdrom" /tmp/cloudinit.yml | cloud-localds "/tank/vm/$cdrom" /tmp/cloudinit.yml | ||||||
|  |  | ||||||
| qemu-img resize "$disk" "$root_volume_size" | qemu-img resize "/tank/vm/$disk" "$root_volume_size" | ||||||
| virt-install \ | virt-install \ | ||||||
|     --memory "$memory" \ |     --memory "$memory" \ | ||||||
|     --vcpus "$vcpus" \ |     --vcpus "$vcpus" \ | ||||||
|     --name "$vmname" \ |     --name "$vmname" \ | ||||||
|     --disk "$disk",bus=virtio \ |     --disk "$qemu_tank_dir/vm/$disk",bus=virtio \ | ||||||
|     --disk "$cdrom",device=cdrom \ |     --disk "$qemu_tank_dir/vm/$cdrom",device=cdrom \ | ||||||
|     --os-type Linux \ |     --os-type Linux \ | ||||||
|     --os-variant generic \ |     --os-variant generic \ | ||||||
|     --virt-type kvm \ |     --virt-type kvm \ | ||||||
|     --graphics vnc,listen=127.0.0.1 \ |     --graphics vnc,listen=127.0.0.1 \ | ||||||
|     --network network=$network_name,filterref=clean-traffic,model=virtio \ |     --network network=$network_name,model=virtio \ | ||||||
|     --import \ |     --import \ | ||||||
|     --print-xml > "$xml" |     --print-xml > "/tank/vm/$xml" | ||||||
|  |  | ||||||
| chmod 0600 "$xml" "$disk" "$cdrom" | chmod 0600 "/tank/vm/$xml" "/tank/vm/$disk" "/tank/vm/$cdrom" | ||||||
| virsh define "$xml" | virsh define "/tank/vm/$xml" | ||||||
| virsh start "$vmname" | virsh start "$vmname" | ||||||
|  |  | ||||||
| echo "success" | echo "success" | ||||||
|  | |||||||
							
								
								
									
										38
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | --- | ||||||
|  | version: "3.8" | ||||||
|  |  | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     image: 3wordchant/capsul-flask:latest | ||||||
|  |     build: . | ||||||
|  |     volumes: | ||||||
|  |       - "./:/app/code" | ||||||
|  |       - "../tank:/tank" | ||||||
|  |       - "/var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock" | ||||||
|  |     depends_on: | ||||||
|  |       - db | ||||||
|  |     ports: | ||||||
|  |       - "5000:5000" | ||||||
|  |     environment: | ||||||
|  |       - "POSTGRES_CONNECTION_PARAMETERS=host=db port=5432 user=capsul password=capsul dbname=capsul" | ||||||
|  |       - SPOKE_MODEL=shell-scripts | ||||||
|  |         #- FLASK_DEBUG=1 | ||||||
|  |       - BASE_URL=http://localhost:5000 | ||||||
|  |       - ADMIN_PANEL_ALLOW_EMAIL_ADDRESSES=3wc.capsul@doesthisthing.work | ||||||
|  |       - VIRSH_DEFAULT_CONNECT_URI=qemu:///system | ||||||
|  |     # The image uses gunicorn by default, let's override it with Flask's | ||||||
|  |     # built-in development server | ||||||
|  |     command: ["flask", "run", "-h", "0.0.0.0", "-p", "5000"] | ||||||
|  |     devices: | ||||||
|  |       - "/dev/kvm:/dev/kvm" | ||||||
|  |   db: | ||||||
|  |     image: "postgres:9.6.5-alpine" | ||||||
|  |     volumes: | ||||||
|  |       - "postgres:/var/lib/postgresql/data" | ||||||
|  |     environment: | ||||||
|  |       POSTGRES_USER: capsul | ||||||
|  |       POSTGRES_PASSWORD: capsul | ||||||
|  |       POSTGRES_DB: capsul | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   postgres: | ||||||
		Reference in New Issue
	
	Block a user
	