diff --git a/.github/workflows/k8s_tests.yml b/.github/workflows/k8s_tests.yml new file mode 100644 index 0000000..ca2cdf8 --- /dev/null +++ b/.github/workflows/k8s_tests.yml @@ -0,0 +1,18 @@ +name: Kubernetes configuration + +on: [push] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: docker pull nekottyo/kustomize-kubeval + - name: render kustomization + run: | + docker run -i -w /working -v $(pwd):/working nekottyo/kustomize-kubeval \ + kustomize build . >> k8s.yml + - name: check kubernetes configuration + run: | + docker run -i -w /working -v $(pwd):/working nekottyo/kustomize-kubeval \ + kubeval k8s.yml --strict diff --git a/Dockerfile b/Dockerfile index 43208c5..354bb24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,9 +33,8 @@ RUN npm run build FROM base as final COPY --from=frontend /app/src/frontend/dist/ /app/static # Setup configs -#ADD docker/uwsgi.ini /etc/uwsgi/lecture2gether.ini +VOLUME /app/config ADD docker/supervisor.conf /etc/supervisor/conf.d/app.conf -RUN mkdir /app/config ADD docker/settings.json /app/config/settings.json RUN ln -sf /app/config/settings.json /app/static/settings.json ADD docker/nginx.conf /etc/nginx/sites-enabled/default diff --git a/README.md b/README.md index 4e80b67..0bf3806 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Lecture2Gether makes it possible to watch online lectures with friends by pasting a link to a [Lecture2Go](https://github.com/lecture2go/portal-6.2-ce-ga6) Video, a YouTube Video or a simple mp4 link. The video streams are synchronized to partially restore the social aspect of campus life. -![Flask CI](https://github.com/TheNerdful8/Lecture2Gether/workflows/Flask%20CI/badge.svg?branch=master)    ![Node.js CI](https://github.com/TheNerdful8/Lecture2Gether/workflows/Node.js%20CI/badge.svg) +![Flask CI](https://github.com/TheNerdful8/Lecture2Gether/workflows/Flask%20CI/badge.svg?branch=master)    ![Node.js CI](https://github.com/TheNerdful8/Lecture2Gether/workflows/Node.js%20CI/badge.svg)    ![Kubernetes configuration](https://github.com/TheNerdful8/Lecture2Gether/workflows/Kubernetes%20configuration/badge.svg) ### Built With diff --git a/docker/nginx.conf b/docker/nginx.conf index a85e687..0eaeabb 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -1,13 +1,24 @@ server { listen 8000; server_name default_server; + gzip on; - try_files $uri /index.html; root /app/static/; + location / { + try_files $uri /index.html?$args; + location ~* \.html$ { + add_header "Cache-Control" "no-cache"; + } + location ~* \.(css|js|woff2) { + add_header "Cache-Control" "max-age=31536000"; + } + } + location /api { proxy_pass http://127.0.0.1:5000; } + location = /socket.io/ { proxy_pass http://127.0.0.1:5000/socket.io/; proxy_http_version 1.1; diff --git a/k8s/deployment.yml b/k8s/deployment.yml index 776b9d4..401fb29 100644 --- a/k8s/deployment.yml +++ b/k8s/deployment.yml @@ -7,12 +7,17 @@ spec: replicas: 1 selector: matchLabels: - app: "NOT_SET" + app: "lecture2gether" template: metadata: labels: - app: "NOT_SET" + app: "lecture2gether" spec: + volumes: + - name: "frontend-config" + configMap: + name: "frontend" + containers: - image: "docker.io/thenerdful8/lecture2gether" name: "main" @@ -21,4 +26,11 @@ spec: containerPort: 8000 - name: "metrics" containerPort: 5000 + envFrom: + - configMapRef: + name: "backend" + volumeMounts: + - name: "frontend-config" + mountPath: "/app/config" + readOnly: true diff --git a/k8s/kustomization.yml b/k8s/kustomization.yml deleted file mode 100644 index cef2f39..0000000 --- a/k8s/kustomization.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -apiVersion: "kustomize.config.k8s.io/v1beta1" -kind: "Kustomization" -namePrefix: "lecture2gether-" -commonLabels: - app: "lecture2gether" -resources: - - "./deployment.yml" - - "./service.yml" diff --git a/kustomization.yml b/kustomization.yml new file mode 100644 index 0000000..4cec3c6 --- /dev/null +++ b/kustomization.yml @@ -0,0 +1,14 @@ +--- +apiVersion: "kustomize.config.k8s.io/v1beta1" +kind: "Kustomization" +namePrefix: "lecture2gether-" +commonLabels: + app: "lecture2gether" +resources: + - "./k8s/deployment.yml" + - "./k8s/service.yml" +configMapGenerator: + - name: "backend" + - name: "frontend" + files: + - "settings.json=./docker/settings.json" diff --git a/lecture2gether-vue/public/index.html b/lecture2gether-vue/public/index.html index e7cea48..d945ec9 100644 --- a/lecture2gether-vue/public/index.html +++ b/lecture2gether-vue/public/index.html @@ -4,6 +4,9 @@ + Lecture2Gether diff --git a/lecture2gether-vue/src/components/Player.vue b/lecture2gether-vue/src/components/Player.vue index ae9efbc..66c4312 100644 --- a/lecture2gether-vue/src/components/Player.vue +++ b/lecture2gether-vue/src/components/Player.vue @@ -64,9 +64,11 @@ export default class L2gPlayer extends Vue { } get playerOptions() { - const sources = []; + let source; + let playbackRates; try { - sources.push(this.getSourceFromURL(this.url)); + source = this.getSourceFromURL(this.url); + playbackRates = this.getPlaybackRatesFromSource(source.type); } catch (e) { console.error(e); // Show error page @@ -77,8 +79,8 @@ export default class L2gPlayer extends Vue { muted: false, language: 'en', fluid: true, - playbackRates: [0.75, 1.0, 1.25, 1.5, 1.75, 2.0], - sources, + playbackRates, + sources: [source], techOrder: ['youtube', 'html5'], youtube: { ytControls: 0, @@ -91,6 +93,15 @@ export default class L2gPlayer extends Vue { return this.$refs.videoPlayer.player; } + getPlaybackRatesFromSource(src: string): Number[] { + if (src === 'video/youtube') { + // YouTube does not support player speed above 2x + return [0.75, 1.0, 1.25, 1.5, 1.75, 2.0]; + } else { + return [0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.5]; + } + } + getSourceFromURL(url: string): {type: string; src: string} { // shared media logic in src/mediaURLs.ts checkURL const res = checkURL(url); @@ -262,4 +273,7 @@ export default class L2gPlayer extends Vue { .video-js .vjs-duration { display: block; } +.vjs-menu-button-popup .vjs-menu .vjs-menu-content { + max-height: 16em; +} diff --git a/lecture2gether-vue/src/components/Toolbar.vue b/lecture2gether-vue/src/components/Toolbar.vue index 922c0cf..55c4ac8 100644 --- a/lecture2gether-vue/src/components/Toolbar.vue +++ b/lecture2gether-vue/src/components/Toolbar.vue @@ -25,7 +25,8 @@ diff --git a/lecture2gether-vue/src/plugins/router/routes.ts b/lecture2gether-vue/src/plugins/router/routes.ts index e781040..73b1d4f 100644 --- a/lecture2gether-vue/src/plugins/router/routes.ts +++ b/lecture2gether-vue/src/plugins/router/routes.ts @@ -1,6 +1,6 @@ import { RouteConfig } from 'vue-router'; import Home from '@/views/Home.vue'; -import Player from '@/views/Room.vue'; +import Room from '@/views/Room.vue'; export default [ { @@ -10,8 +10,8 @@ export default [ }, { path: '/l/:roomId', - name: 'player', - component: Player, + name: 'room', + component: Room, }, { path: '/sync/debug', diff --git a/lecture2gether-vue/src/plugins/vuetify.ts b/lecture2gether-vue/src/plugins/vuetify.ts index 81c3950..63b26de 100644 --- a/lecture2gether-vue/src/plugins/vuetify.ts +++ b/lecture2gether-vue/src/plugins/vuetify.ts @@ -1,5 +1,5 @@ import Vue from 'vue'; -import Vuetify from 'vuetify'; +import Vuetify from 'vuetify/lib'; import 'vuetify/dist/vuetify.min.css'; Vue.use(Vuetify); diff --git a/lecture2gether-vue/src/views/Home.vue b/lecture2gether-vue/src/views/Home.vue index a50d262..bbbcb26 100644 --- a/lecture2gether-vue/src/views/Home.vue +++ b/lecture2gether-vue/src/views/Home.vue @@ -22,7 +22,7 @@ export default class L2gHome extends Vue { async onConnectedChanged() { await this.$store.dispatch('newRoom'); await this.$router.push({ - name: 'player', + name: 'room', params: { roomId: this.$store.state.rooms.roomId, }, diff --git a/lecture2gether-vue/src/views/Room.vue b/lecture2gether-vue/src/views/Room.vue index 26f57d7..7e5656a 100644 --- a/lecture2gether-vue/src/views/Room.vue +++ b/lecture2gether-vue/src/views/Room.vue @@ -3,7 +3,7 @@ - + @@ -21,15 +21,15 @@ // @ is an alias to /src import Vue from 'vue'; import Component from 'vue-class-component'; -import L2gPlayer from '@/components/Player.vue'; +import Player from '@/components/Player.vue'; import { Watch } from 'vue-property-decorator'; import { AuthState } from '@/plugins/store/player'; import PasswordDialog from '@/components/PasswordDialog.vue'; @Component({ - components: { PasswordDialog, L2gPlayer }, + components: { PasswordDialog, Player }, }) -export default class L2gPlayerView extends Vue { +export default class Room extends Vue { roomExists = true; @Watch('$route.params.roomId') diff --git a/lecture2gether-vue/tsconfig.json b/lecture2gether-vue/tsconfig.json index b57578e..8a0cf1a 100644 --- a/lecture2gether-vue/tsconfig.json +++ b/lecture2gether-vue/tsconfig.json @@ -12,7 +12,8 @@ "sourceMap": true, "baseUrl": ".", "types": [ - "webpack-env" + "webpack-env", + "vuetify" ], "paths": { "@/*": [