Compare commits
No commits in common. "9671be1ff349586ae0e50d6fecbf4c8f961281d6" and "e31edb55ada6e418468d9d96efe7f628d1cc0d69" have entirely different histories.
9671be1ff3
...
e31edb55ad
15
.gitignore
vendored
15
.gitignore
vendored
@ -3,13 +3,13 @@ msg
|
|||||||
tmp/
|
tmp/
|
||||||
keys/
|
keys/
|
||||||
|
|
||||||
clippable-svc/target/
|
api/target/
|
||||||
clippable-svc/dev/
|
api/dev/
|
||||||
clippable-svc/vids/
|
api/vids/
|
||||||
clippable-svc/static/js/
|
api/static/js/
|
||||||
clippable-svc/static/dist/
|
api/static/dist/
|
||||||
clippable-svc/thumbs/
|
api/thumbs/
|
||||||
clippable-svc/*.db
|
api/*.db
|
||||||
|
|
||||||
build/
|
build/
|
||||||
gitpage/public/
|
gitpage/public/
|
||||||
@ -29,4 +29,3 @@ ts/dist/
|
|||||||
ts/node_modules/
|
ts/node_modules/
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
api/.vscode/settings.json
|
api/.vscode/settings.json
|
||||||
api/.ycm_extra_conf.py
|
|
||||||
|
@ -4,10 +4,6 @@ stages:
|
|||||||
- build-backend
|
- build-backend
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
include:
|
|
||||||
- local: 'ci/cargo.yml'
|
|
||||||
- local: 'ci/docker.yml'
|
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
image: shockrah/website:latest
|
image: shockrah/website:latest
|
||||||
stage: pages
|
stage: pages
|
||||||
@ -26,67 +22,62 @@ pages:
|
|||||||
paths:
|
paths:
|
||||||
- public/
|
- public/
|
||||||
|
|
||||||
# Webpack bundles everything anyway so both admin/non-admin builds have
|
|
||||||
# the same frontend code.
|
|
||||||
build-frontend-js:
|
build-frontend-js:
|
||||||
image: codesignal/typescript:v9.6.0
|
image: codesignal/typescript:v9.6.0
|
||||||
stage: build-frontend
|
stage: build-frontend
|
||||||
|
stage: pages
|
||||||
only:
|
only:
|
||||||
refs:
|
refs:
|
||||||
- master
|
- master
|
||||||
script:
|
script:
|
||||||
- cd ts/
|
- cd ts/
|
||||||
- npm i
|
- npm run setup
|
||||||
- npm run build
|
- npm run build
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- clippable-svc/static/
|
- api/static/
|
||||||
|
|
||||||
build-server-no-admin:
|
# Literally both of these fail 99% of the time so I'm forgoing them completely
|
||||||
extends: .cargo-builder
|
# for now until I find something doesn't suck
|
||||||
|
# Builds out the intended zip package
|
||||||
|
build-server-binaries:
|
||||||
|
image: rustlang/rust:nightly
|
||||||
stage: build-backend
|
stage: build-backend
|
||||||
needs:
|
stage: pages
|
||||||
- build-frontend-js
|
only:
|
||||||
dependencies:
|
refs:
|
||||||
- build-frontend-js
|
- master
|
||||||
script:
|
script:
|
||||||
- cd clippable-svc/
|
- mkdir -p build
|
||||||
|
- cp api/templates/ api/static/ build/ -r
|
||||||
|
- cd api/
|
||||||
- cargo build --release
|
- cargo build --release
|
||||||
- cd ../
|
- cd ../
|
||||||
|
- cp api/target/release/clippable-server build/server
|
||||||
|
- cp ./scripts/ build/ -r
|
||||||
|
- cp readme.md build/
|
||||||
|
- sh ./scripts/default-rocket-toml.sh
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build/
|
||||||
|
|
||||||
build-server-admin-enabled:
|
# Upload built docker image to the local registry
|
||||||
extends: .cargo-builder
|
deploy-docker-image:
|
||||||
stage: build-backend
|
|
||||||
needs:
|
|
||||||
- build-frontend-js
|
|
||||||
dependencies:
|
|
||||||
- build-frontend-js
|
|
||||||
script:
|
|
||||||
- cd clippable-svc/
|
|
||||||
- cargo build --release --features admin
|
|
||||||
- cd ../
|
|
||||||
|
|
||||||
deploy-no-admin-docker:
|
|
||||||
stage: deploy
|
stage: deploy
|
||||||
extends: .docker-deploy
|
image: docker:stable
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- master
|
||||||
needs:
|
needs:
|
||||||
- build-server-no-admin
|
- build-server-binaries
|
||||||
dependencies:
|
dependencies:
|
||||||
- build-server-no-admin
|
- build-server-binaries
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
script:
|
script:
|
||||||
|
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
||||||
- docker build -t registry.gitlab.com/shockrah/clippable .
|
- docker build -t registry.gitlab.com/shockrah/clippable .
|
||||||
- docker push registry.gitlab.com/shockrah/clippable
|
- docker push registry.gitlab.com/shockrah/clippable
|
||||||
|
|
||||||
deploy-admin-docker:
|
|
||||||
stage: deploy
|
|
||||||
extends: .docker-deploy
|
|
||||||
needs:
|
|
||||||
- build-server-admin-enabled
|
|
||||||
dependencies:
|
|
||||||
- build-server-admin-enabled
|
|
||||||
script:
|
|
||||||
- docker build -t registry.gitlab.com/shockrah/clippable:admin .
|
|
||||||
- docker push registry.gitlab.com/shockrah/clippable:admin
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
0
clippable-svc/Cargo.lock → api/Cargo.lock
generated
0
clippable-svc/Cargo.lock → api/Cargo.lock
generated
@ -56,8 +56,6 @@ pub fn get_category_thumbnail(category: &str) -> std::io::Result<String> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a List of categories
|
|
||||||
/// Primarily used on the main page
|
|
||||||
/// WARN: misconfigured servers are just going to get shafted and serve up
|
/// WARN: misconfigured servers are just going to get shafted and serve up
|
||||||
/// a tonne of 500's
|
/// a tonne of 500's
|
||||||
#[get("/categories")]
|
#[get("/categories")]
|
@ -83,18 +83,3 @@ video {
|
|||||||
#video-meta {
|
#video-meta {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-video-li {
|
|
||||||
color: black;
|
|
||||||
text-shadow: none;
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-video-li:hover {
|
|
||||||
color: #0a58ca;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
@ -4,8 +4,6 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||||
<title>Clippable Admin Dashboard</title>
|
<title>Clippable Admin Dashboard</title>
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/favicon.png"/>
|
<link rel="shortcut icon" type="image/png" href="/static/favicon.png"/>
|
||||||
@ -62,10 +60,6 @@
|
|||||||
<button type="button" class="btn btn-primary" id="confirm-upload-btn">Upload</button>
|
<button type="button" class="btn btn-primary" id="confirm-upload-btn">Upload</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="upload-response"></div>
|
<div id="upload-response"></div>
|
||||||
<div class="vids-meta-list">
|
|
||||||
<h1>Videos</h1>
|
|
||||||
<ul class="list-group" id="videos-list"></ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
14
aws/infra/ebs.tf
Normal file
14
aws/infra/ebs.tf
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
resource "aws_ebs_volume" "app_volume" {
|
||||||
|
availability_zone = var.availability_zone
|
||||||
|
size = 20
|
||||||
|
type = "standard"
|
||||||
|
tags = {
|
||||||
|
Name = "APP Video block storage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_volume_attachment" "ebs_att" {
|
||||||
|
device_name = "/dev/sdf"
|
||||||
|
volume_id = aws_ebs_volume.app_volume.id
|
||||||
|
instance_id = aws_instance.app_instance.id
|
||||||
|
}
|
35
aws/infra/ec2.tf
Normal file
35
aws/infra/ec2.tf
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# This here module takes care of setting up the ec2 instances that our
|
||||||
|
# containers will bind to later on
|
||||||
|
|
||||||
|
variable "aws_key" {}
|
||||||
|
variable "aws_secret" {}
|
||||||
|
variable "aws_region" {}
|
||||||
|
variable "ami_id" {}
|
||||||
|
variable "instance_type" {}
|
||||||
|
variable "ssh_key_name" {}
|
||||||
|
variable "public_key_path" {}
|
||||||
|
variable "availability_zone" {}
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
access_key = var.aws_key
|
||||||
|
secret_key = var.aws_secret
|
||||||
|
region = var.aws_region
|
||||||
|
max_retries = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_key_pair" "sshkey" {
|
||||||
|
key_name = var.ssh_key_name
|
||||||
|
public_key = file(var.public_key_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "app_instance" {
|
||||||
|
ami = var.ami_id
|
||||||
|
instance_type = var.instance_type
|
||||||
|
|
||||||
|
key_name = var.ssh_key_name
|
||||||
|
security_groups = [ aws_security_group.app_security_group.id ]
|
||||||
|
subnet_id = aws_subnet.app_public_subnet.id
|
||||||
|
tags = {
|
||||||
|
Name = "Clippable App Instance"
|
||||||
|
}
|
||||||
|
}
|
7
aws/infra/eip.tf
Normal file
7
aws/infra/eip.tf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
resource "aws_eip" "app_eip" {
|
||||||
|
instance = aws_instance.app_instance.id
|
||||||
|
vpc = true
|
||||||
|
tags = {
|
||||||
|
Name = "Clippable EIP"
|
||||||
|
}
|
||||||
|
}
|
6
aws/infra/gateway.tf
Normal file
6
aws/infra/gateway.tf
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
resource "aws_internet_gateway" "app_gateway" {
|
||||||
|
vpc_id = aws_vpc.app_vpc.id
|
||||||
|
tags = {
|
||||||
|
Name = "Clippable app internet gateway"
|
||||||
|
}
|
||||||
|
}
|
12
aws/infra/route-table.tf
Normal file
12
aws/infra/route-table.tf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
resource "aws_route_table" "app_route_table" {
|
||||||
|
vpc_id = aws_vpc.app_vpc.id
|
||||||
|
route {
|
||||||
|
cidr_block = "0.0.0.0/0"
|
||||||
|
gateway_id = aws_internet_gateway.app_gateway.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route_table_association" "app_subnet_assoc" {
|
||||||
|
subnet_id = aws_subnet.app_public_subnet.id
|
||||||
|
route_table_id = aws_route_table.app_route_table.id
|
||||||
|
}
|
32
aws/infra/scripts/server-setup.sh
Normal file
32
aws/infra/scripts/server-setup.sh
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script runs in order to to set things up for so that we don't have to do
|
||||||
|
# much else by ourselves
|
||||||
|
|
||||||
|
# No harm in using sudo even as root its just a little pointless
|
||||||
|
# Doing this with our ami however means we don't have to check if we're root
|
||||||
|
# for privileged operations at provision-time
|
||||||
|
apt="sudo apt"
|
||||||
|
server_name=$1
|
||||||
|
if [ -z "$server_name" ];then
|
||||||
|
echo A servername must be given as an argument
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
$apt update
|
||||||
|
$apt upgrade
|
||||||
|
$apt install -y nginx certbot
|
||||||
|
|
||||||
|
sudo mkdir -p /var/www/clippable
|
||||||
|
# Creating the reverse proxy configuration for nginx
|
||||||
|
# WARN: Also we're assuming that the webserver has the default port
|
||||||
|
# Only this because certbot does the rest
|
||||||
|
cat << EOF > /etc/nginx/sites-available/clippable
|
||||||
|
server {
|
||||||
|
server_name $server_name;
|
||||||
|
location / {
|
||||||
|
proxy_pass http://0.0.0.0:8482;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
39
aws/infra/security-group.tf
Normal file
39
aws/infra/security-group.tf
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
resource "aws_security_group" "app_security_group" {
|
||||||
|
name = "App sec group"
|
||||||
|
description = "Allowing SSH and web traffic"
|
||||||
|
vpc_id = aws_vpc.app_vpc.id
|
||||||
|
|
||||||
|
ingress {
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
from_port = 443
|
||||||
|
to_port = 443
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
from_port = 80
|
||||||
|
to_port = 80
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
from_port = 22
|
||||||
|
to_port = 22
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
|
||||||
|
# These are so that we can update the system regularly using apt and sometimes
|
||||||
|
# with tarballs if we're updating something from source
|
||||||
|
egress {
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
from_port = 443
|
||||||
|
to_port = 443
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
egress {
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
from_port = 80
|
||||||
|
to_port = 80
|
||||||
|
protocol = "tcp"
|
||||||
|
}
|
||||||
|
}
|
5
aws/infra/subnet.tf
Normal file
5
aws/infra/subnet.tf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
resource "aws_subnet" "app_public_subnet" {
|
||||||
|
vpc_id = aws_vpc.app_vpc.id
|
||||||
|
cidr_block = "10.0.0.128/26"
|
||||||
|
availability_zone = var.availability_zone
|
||||||
|
}
|
10
aws/infra/vpc.tf
Normal file
10
aws/infra/vpc.tf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
resource "aws_vpc" "app_vpc" {
|
||||||
|
cidr_block = "10.0.0.128/26"
|
||||||
|
enable_dns_support = true
|
||||||
|
enable_dns_hostnames = true
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
Name = "Clippable APP VPC"
|
||||||
|
}
|
||||||
|
}
|
57
aws/playbooks/README.md
Normal file
57
aws/playbooks/README.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
Role Name
|
||||||
|
=========
|
||||||
|
|
||||||
|
This role is dedicated to making the setup and administration of a clippable
|
||||||
|
server a little bit easier for those intending on running their own instance.
|
||||||
|
|
||||||
|
There are playbooks for maintaining this service both as a container and as a
|
||||||
|
service running on System D.
|
||||||
|
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Vars in: `defaults/main.yml`
|
||||||
|
|
||||||
|
* `remote_user`: Default username to use for regular tasks
|
||||||
|
|
||||||
|
Set to `admin` by default.
|
||||||
|
|
||||||
|
* `remote_app_dir`: Directory to install application files into
|
||||||
|
|
||||||
|
Set to `/home/{{remote_user}}/app` by default
|
||||||
|
|
||||||
|
This includes things like the server binary and HTML template files.
|
||||||
|
You only need to worry about this if you're not going to run this
|
||||||
|
in a container.
|
||||||
|
|
||||||
|
* `main_host`
|
||||||
|
|
||||||
|
Set to `main` by default.
|
||||||
|
|
||||||
|
Host that you intend on targeting.
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
* community.docker
|
||||||
|
|
||||||
|
This is only required if you are planning on using any of the docker playbooks.
|
||||||
|
|
||||||
|
Example Playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
GPL V3
|
||||||
|
|
||||||
|
Author Information
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Author: Shockrah
|
||||||
|
Email: dev@shockrah.xyz
|
4
aws/playbooks/defaults/main.yml
Normal file
4
aws/playbooks/defaults/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
remote_user: admin
|
||||||
|
remote_app_dir: "/home/{{remote_user}}/app"
|
||||||
|
main_host: main
|
2
aws/playbooks/handlers/main.yml
Normal file
2
aws/playbooks/handlers/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
# handlers file for playbooks
|
52
aws/playbooks/meta/main.yml
Normal file
52
aws/playbooks/meta/main.yml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
galaxy_info:
|
||||||
|
author: your name
|
||||||
|
description: your role description
|
||||||
|
company: your company (optional)
|
||||||
|
|
||||||
|
# If the issue tracker for your role is not on github, uncomment the
|
||||||
|
# next line and provide a value
|
||||||
|
# issue_tracker_url: http://example.com/issue/tracker
|
||||||
|
|
||||||
|
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||||
|
# - BSD-3-Clause (default)
|
||||||
|
# - MIT
|
||||||
|
# - GPL-2.0-or-later
|
||||||
|
# - GPL-3.0-only
|
||||||
|
# - Apache-2.0
|
||||||
|
# - CC-BY-4.0
|
||||||
|
license: license (GPL-2.0-or-later, MIT, etc)
|
||||||
|
|
||||||
|
min_ansible_version: 2.1
|
||||||
|
|
||||||
|
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||||
|
# min_ansible_container_version:
|
||||||
|
|
||||||
|
#
|
||||||
|
# Provide a list of supported platforms, and for each platform a list of versions.
|
||||||
|
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
||||||
|
# To view available platforms and versions (or releases), visit:
|
||||||
|
# https://galaxy.ansible.com/api/v1/platforms/
|
||||||
|
#
|
||||||
|
# platforms:
|
||||||
|
# - name: Fedora
|
||||||
|
# versions:
|
||||||
|
# - all
|
||||||
|
# - 25
|
||||||
|
# - name: SomePlatform
|
||||||
|
# versions:
|
||||||
|
# - all
|
||||||
|
# - 1.0
|
||||||
|
# - 7
|
||||||
|
# - 99.99
|
||||||
|
|
||||||
|
galaxy_tags: []
|
||||||
|
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||||
|
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||||
|
# remove the '[]' above, if you add tags to this list.
|
||||||
|
#
|
||||||
|
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||||
|
# Maximum 20 tags per role.
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
|
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||||
|
# if you add dependencies to this list.
|
41
aws/playbooks/tasks/docker/debian.yml
Normal file
41
aws/playbooks/tasks/docker/debian.yml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
tasks:
|
||||||
|
- name: Install docker dependencies
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
apt:
|
||||||
|
name: "{{item}}"
|
||||||
|
update_cache: yes
|
||||||
|
loop:
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- gnupg
|
||||||
|
- software-properties-common
|
||||||
|
- lsb-release
|
||||||
|
|
||||||
|
- name: Install docker GPG key
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
apt_key:
|
||||||
|
url: https://download.docker.com/linux/ubuntu/gpg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add Docker Apt Repo
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
apt_repository:
|
||||||
|
repo: deb https://download.docker.com/linux/ubuntu impish stable
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Docker components
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
apt:
|
||||||
|
name: "{{item}}"
|
||||||
|
update_cache: yes
|
||||||
|
loop:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
|
9
aws/playbooks/tasks/docker/main.yml
Normal file
9
aws/playbooks/tasks/docker/main.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# This playbook is setup to install docker on debian based systems
|
||||||
|
---
|
||||||
|
- hosts: main
|
||||||
|
tasks:
|
||||||
|
- include_tasks: 'debian.yml'
|
||||||
|
when:
|
||||||
|
ansible_distribution: Debian
|
||||||
|
|
||||||
|
|
59
aws/playbooks/tasks/systemd/update-app.yml
Normal file
59
aws/playbooks/tasks/systemd/update-app.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# WHEN TO USE THIS PLAYBOOK:
|
||||||
|
# Use this if you're running clippable under systemd
|
||||||
|
# WHAT THIS PLAYBOOK DOES:
|
||||||
|
# This playbooks basically takes a build/ directory similar to what the Gitlab
|
||||||
|
# pipelines generate and uploads those files to the desired directory
|
||||||
|
---
|
||||||
|
- hosts: {{ main_host }}
|
||||||
|
remote_user: {{ remote_user }}
|
||||||
|
tasks:
|
||||||
|
- name: Build skeleton root directory
|
||||||
|
file:
|
||||||
|
path: '{{remote_app_dir}}'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Build skeleton static directory
|
||||||
|
file:
|
||||||
|
path: '{{remote_app_dir}}/static'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Build skeleton css directory
|
||||||
|
file:
|
||||||
|
path: '{{remote_app_dir}}/static/css'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Build skeleton js directory
|
||||||
|
file:
|
||||||
|
path: '{{remote_app_dir}}/static/js'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Build skeleton templates directory
|
||||||
|
file:
|
||||||
|
path: '{{remote_app_dir}}/templates'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Update Binary installation
|
||||||
|
copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
with_items:
|
||||||
|
- { src: ../../build/static/css/style.css, dest: '{{remote_app_dir}}/static/css/'}
|
||||||
|
|
||||||
|
- { src: ../../build/static/js/index.js, dest: '{{remote_app_dir}}/static/js/'}
|
||||||
|
- { src: ../../build/static/js/category.js, dest: '{{remote_app_dir}}/static//js/'}
|
||||||
|
|
||||||
|
- { src: ../../build/static/cantfindshit.jpg, dest: '{{remote_app_dir}}/static/'}
|
||||||
|
- { src: ../../build/static/favicon.png, dest: '{{remote_app_dir}}/static/'}
|
||||||
|
|
||||||
|
- { src: ../../build/templates/list.html.tera, dest: '{{remote_app_dir}}/templates/list.html.tera'}
|
||||||
|
- { src: ../../build/templates/video.html.tera, dest: '{{remote_app_dir}}/templates/video.html.tera'}
|
||||||
|
|
||||||
|
- { src: ../../build/Rocket.toml, dest: '{{remote_app_dir}}/'}
|
||||||
|
- { src: ../../build/server, dest: '{{remote_app_dir}}/'}
|
||||||
|
|
||||||
|
- name: Restart web service
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
service:
|
||||||
|
name: app
|
||||||
|
state: restarted
|
2
aws/playbooks/tests/inventory
Normal file
2
aws/playbooks/tests/inventory
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
localhost
|
||||||
|
|
5
aws/playbooks/tests/test.yml
Normal file
5
aws/playbooks/tests/test.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
remote_user: root
|
||||||
|
roles:
|
||||||
|
- playbooks
|
2
aws/playbooks/vars/main.yml
Normal file
2
aws/playbooks/vars/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
# vars file for playbooks
|
8
aws/readme.md
Normal file
8
aws/readme.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# AWS Configuration
|
||||||
|
|
||||||
|
For those that would like to deploy a minimal instance to AWS via terraform
|
||||||
|
this directory will basically have everything you need to get a working instance
|
||||||
|
up and running for very cheap with an EC2 instance.
|
||||||
|
|
||||||
|
There is still the question of preparing the EC2 instance itself however the
|
||||||
|
amount of configuration is very light.
|
5
aws/sample.ini
Normal file
5
aws/sample.ini
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# NOTE: sample inventory either use your own inventory file or just
|
||||||
|
# replace the hostname/ip below
|
||||||
|
[main]
|
||||||
|
1.1.1.1
|
||||||
|
|
16
ci/cargo.yml
16
ci/cargo.yml
@ -1,16 +0,0 @@
|
|||||||
.cargo-builder:
|
|
||||||
image: rustlang/rust:nightly
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- master
|
|
||||||
before_script:
|
|
||||||
- mkdir -p build
|
|
||||||
- cp clippable-svc/templates/ clippable-svc/static/ build/ -r
|
|
||||||
after_script:
|
|
||||||
- cp clippable-svc/target/release/clippable-server build/server
|
|
||||||
- cp ./scripts/ build/ -r
|
|
||||||
- cp readme.md build/
|
|
||||||
- sh ./scripts/default-rocket-toml.sh
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- build/
|
|
@ -1,9 +0,0 @@
|
|||||||
.docker-deploy:
|
|
||||||
image: docker:stable
|
|
||||||
services:
|
|
||||||
- docker:dind
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- master
|
|
||||||
before_script:
|
|
||||||
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
|
|
3
clippable-svc/.vscode/settings.json
vendored
3
clippable-svc/.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"rust.all_features": true
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
def Settings(**kwargs):
|
|
||||||
return {
|
|
||||||
'ls': {
|
|
||||||
'cargo': {
|
|
||||||
'features': ['admin'],
|
|
||||||
'noDefaultFeatures': True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,9 +10,9 @@ cargo build --release
|
|||||||
|
|
||||||
mkdir -p build/
|
mkdir -p build/
|
||||||
|
|
||||||
cp target/release/clippable-svc build/server
|
cp target/release/api build/server
|
||||||
cp clippable-svc/templates/ build/ -r
|
cp api/templates/ build/ -r
|
||||||
cp clippable-svc/static/ build -r
|
cp api/static/ build -r
|
||||||
|
|
||||||
bash ./scripts/default-rocket-toml.sh
|
bash ./scripts/default-rocket-toml.sh
|
||||||
docker build -t registry.gitlab.com/shockrah/clippable .
|
docker build -t registry.gitlab.com/shockrah/clippable .
|
||||||
|
26
ts/admin.ts
26
ts/admin.ts
@ -1,8 +1,8 @@
|
|||||||
// This module serves as convenience for admin users to upload/remove videos
|
// This module serves as convenience for admin users to upload/remove videos
|
||||||
// from their clippable instance. There are no fancy tricks as this is meant
|
// from their clippable instance. There are no fancy tricks as this is meant
|
||||||
// purely to be a UX thing.
|
// purely to be a UX thing.
|
||||||
import { fetch_category_videos, VideoMeta } from './category'
|
//import { fetch_category_videos } from './category'
|
||||||
import { fetch_categories } from './index'
|
//import { fetch_categories } from './index'
|
||||||
|
|
||||||
|
|
||||||
let UID: null|string = null
|
let UID: null|string = null
|
||||||
@ -79,6 +79,7 @@ export function populate_meta_form() {
|
|||||||
let file = document.getElementById('video-file') as HTMLInputElement
|
let file = document.getElementById('video-file') as HTMLInputElement
|
||||||
|
|
||||||
// When we remove the file this array becomes 0 so the check is required
|
// When we remove the file this array becomes 0 so the check is required
|
||||||
|
console.log('files found', file.files.length)
|
||||||
if(file.files.length == 0) {
|
if(file.files.length == 0) {
|
||||||
document.getElementById('video-meta').hidden = true
|
document.getElementById('video-meta').hidden = true
|
||||||
} else {
|
} else {
|
||||||
@ -92,24 +93,6 @@ export function populate_meta_form() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function populate_video_list() {
|
|
||||||
const categories = await fetch_categories()
|
|
||||||
let videos: Array<VideoMeta> = []
|
|
||||||
|
|
||||||
for(const cat of categories) {
|
|
||||||
const vids = await fetch_category_videos(cat.name)
|
|
||||||
for(const v of vids) {
|
|
||||||
videos.push(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const list_ref = document.getElementById("videos-list")
|
|
||||||
for(const video of videos) {
|
|
||||||
list_ref.appendChild(video.as_li())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
/*
|
/*
|
||||||
* Setting up hooks required for functionality
|
* Setting up hooks required for functionality
|
||||||
@ -117,7 +100,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
document.getElementById('video-file').onchange = populate_meta_form
|
document.getElementById('video-file').onchange = populate_meta_form
|
||||||
document.getElementById('verify-login-btn').onclick = confirm_auth
|
document.getElementById('verify-login-btn').onclick = confirm_auth
|
||||||
document.getElementById('confirm-upload-btn').onclick = upload_video
|
document.getElementById('confirm-upload-btn').onclick = upload_video
|
||||||
populate_video_list()
|
|
||||||
.then(value => console.log('succesful list population: ', value))
|
|
||||||
.catch(reason => console.log('Failure in populate_video_list', reason))
|
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
export class VideoMeta {
|
class VideoMeta {
|
||||||
name: string|null
|
name: string|null
|
||||||
thumbnail: string|null
|
thumbnail: string|null
|
||||||
category: string
|
category: string
|
||||||
basename: string|null
|
basename: string|null
|
||||||
href: string
|
|
||||||
|
|
||||||
constructor(raw: any) {
|
constructor(raw: any) {
|
||||||
this.name = raw['name']
|
this.name = raw['name']
|
||||||
@ -15,8 +14,6 @@ export class VideoMeta {
|
|||||||
this.basename = this.name ?
|
this.basename = this.name ?
|
||||||
this.name.slice(0, this.name.lastIndexOf('.')) :
|
this.name.slice(0, this.name.lastIndexOf('.')) :
|
||||||
null
|
null
|
||||||
|
|
||||||
this.href = `/clip/${this.category}/${this.basename}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private clean_link(link: string) : string {
|
private clean_link(link: string) : string {
|
||||||
@ -31,7 +28,7 @@ export class VideoMeta {
|
|||||||
let container = document.createElement('h2')
|
let container = document.createElement('h2')
|
||||||
let link = document.createElement('a')
|
let link = document.createElement('a')
|
||||||
if(this.name) {
|
if(this.name) {
|
||||||
link.href = this.href
|
link.href = `/clip/${this.category}/${this.basename}`
|
||||||
link.text = this.clean_link(this.name)
|
link.text = this.clean_link(this.name)
|
||||||
} else {
|
} else {
|
||||||
link.href = '#'
|
link.href = '#'
|
||||||
@ -80,38 +77,10 @@ export class VideoMeta {
|
|||||||
|
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
public as_li() : HTMLElement {
|
|
||||||
const li = document.createElement('li')
|
|
||||||
li.className = 'align-left list-group-item'
|
|
||||||
|
|
||||||
const link = document.createElement('a')
|
|
||||||
link.href = `/clip/${this.category}/${this.name}`
|
|
||||||
link.target = '_blank'
|
|
||||||
link.textContent = this.name
|
|
||||||
link.className = 'admin-video-li btn'
|
|
||||||
li.appendChild(link)
|
|
||||||
|
|
||||||
const thumbnail_link = document.createElement('a')
|
|
||||||
thumbnail_link.href = `/thumbnail/${this.category}/${this.name}.jpg`
|
|
||||||
link.target = '_blank'
|
|
||||||
thumbnail_link.innerHTML = '<i class="fa-solid fa-image"></i>'
|
|
||||||
thumbnail_link.className = 'admin-video-li btn'
|
|
||||||
li.appendChild(thumbnail_link)
|
|
||||||
|
|
||||||
const delete_btn = document.createElement('button')
|
|
||||||
delete_btn.type = 'button'
|
|
||||||
delete_btn.className = 'btn btn-danger'
|
|
||||||
delete_btn.innerHTML = '<i class="fa-solid fa-trash"></i>'
|
|
||||||
li.appendChild(delete_btn)
|
|
||||||
|
|
||||||
return li
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch_category_videos(name?: string) : Promise<Array<VideoMeta>> {
|
export async function fetch_category_videos() : Promise<Array<VideoMeta>> {
|
||||||
const category = name ? name : window.location.pathname
|
const endpoint = window.location.origin + '/api' + window.location.pathname
|
||||||
const endpoint = window.location.origin + `/api/category/${category}`
|
|
||||||
let videos: Array<VideoMeta> = []
|
let videos: Array<VideoMeta> = []
|
||||||
const response = await fetch(endpoint)
|
const response = await fetch(endpoint)
|
||||||
if(response.headers.get('Content-Type') == 'application/json') {
|
if(response.headers.get('Content-Type') == 'application/json') {
|
||||||
|
Loading…
Reference in New Issue
Block a user