refacto(services): per service form components

This commit is contained in:
Florian Schmitt 2024-10-10 13:45:58 +03:00
parent 1adbb1cd04
commit fb8296c081
12 changed files with 217 additions and 144 deletions

View file

@ -1,113 +1,110 @@
<script setup> <script setup>
import NixCode from "./NixCode.vue" import NixCode from "./NixCode.vue"
import NixForm from "./NixForm.vue" import NixForm from "./NixForm.vue"
import { provide, ref } from 'vue'
</script> let nixin = {
netconf: 'autoconfig',
<script> networkingHostname: '',
export default { networkingDomain: 'distrilab.eu',
beforeMount() { availableBundles: [
this.availableServices.forEach((s) => { {
s.inBundle = [] "id": "writeCollectively",
}) "name": "Write collectively : pads",
this.availableBundles.forEach((b) => { "services": [
b.services.forEach((s) => { 'hedgedoc', 'nextcloud'
this.availableServices.find(item => item.id === s).inBundle.push(b.id); ]
})
})
},
data() {
return {
netconf: 'autoconfig',
networkingHostname: '',
networkingDomain: 'distrilab.eu',
availableBundles: [{
"id": "writeCollectively",
"name": "Write collectively : pads",
"services": [
'hedgedoc', 'nextcloud'
]
},
{
"id": "forge",
"name": "Forge : git repo, CI/CD workers, and NixiN",
"services": [
'forgejo', 'forgejorunner', 'nixin'
]
},
{
"id": "socialMedia",
"name": "Social media: hosted social medias in activitypub web-apps",
"services": [
'gotosocial', 'peertube', 'lemmy'
]
}],
availableServices: [{
"id": "hedgedoc",
"name": "Hedgedoc : realtime collaborative markdown editor"
},
{
"id": "forgejo",
"name": "Forgejo : git hosting"
},
{
"id": "forgejorunner",
"name": "Forgejo runner : CD/CI runner for Forgejo"
},
{
"id": "gotosocial",
"name": "Gotosocial : personal light activityPub social media"
},
{
"id": "peertube",
"name": "Peertube : video hosting platform with activityPub"
},
{
"id": "lemmy",
"name": "Lemmy : reddit alternative with activityPub"
},
{
"id": "nextcloud",
"name": "Nextcloud : personnal cloud"
},
{
"id": "nixin",
"name": "NixiN : web ui for configurations"
}],
nixinBundles: [],
nixinServices: [],
timezone: 'Etc/UTC',
locale: 'en_US.UTF-8',
user: 'operator',
userPassword: 'CHANGE ME !!!',
}
},
methods: {
netconfHasBeenChanged(val = '') {
if (val === 'autoconfig') {
this.networkingDomain = 'distrilab.org'
} else {
this.networkingDomain = ''
}
}, },
selectServices(bundleId, services) { {
if (this.nixinBundles.includes(bundleId)) { "id": "forge",
services.forEach((s) => { "name": "Forge : git repo, CI/CD workers, and NixiN",
if (this.nixinServices.indexOf(s) === -1) { "services": [
this.nixinServices.push(s) 'forgejo', 'forgejorunner', 'nixin'
} ]
})
} else { },
services.forEach((s) => { {
const index = this.nixinServices.indexOf(s); "id": "socialMedia",
if (index > -1) { "name": "Social media: hosted social medias in activitypub web-apps",
this.nixinServices.splice(index, 1); "services": [
} 'gotosocial', 'peertube', 'lemmy'
}) ]
}],
availableServices: [
{
"id": "hedgedoc",
"name": "Hedgedoc : realtime collaborative markdown editor"
},
{
"id": "forgejo",
"name": "Forgejo : git hosting"
},
{
"id": "forgejorunner",
"name": "Forgejo runner : CD/CI runner for Forgejo"
},
{
"id": "gotosocial",
"name": "Gotosocial : personal light activityPub social media"
},
{
"id": "peertube",
"name": "Peertube : video hosting platform with activityPub"
},
{
"id": "lemmy",
"name": "Lemmy : reddit alternative with activityPub"
},
{
"id": "nextcloud",
"name": "Nextcloud : personnal cloud"
},
{
"id": "nixin",
"name": "NixiN : web ui for configurations"
}],
bundles: [],
services: [],
timezone: 'Etc/UTC',
locale: 'en_US.UTF-8',
user: 'operator',
userPassword: 'CHANGE ME !!!',
}
nixin.availableServices.forEach((s) => {
s.inBundle = []
})
nixin.availableBundles.forEach((b) => {
b.services.forEach((s) => {
nixin.availableServices.find(item => item.id === s).inBundle.push(b.id);
})
})
nixin=ref(nixin)
provide('nixin', nixin)
function netconfHasBeenChanged(val = '') {
if (val === 'autoconfig') {
nixin.networkingDomain = 'distrilab.org'
} else {
nixin.networkingDomain = ''
}
}
function selectServices(bundleId, services) {
if (nixin.value.bundles.includes(bundleId)) {
services.forEach((s) => {
if (nixin.value.services.indexOf(s) === -1) {
nixin.value.services.push(s)
} }
} })
} else {
services.forEach((s) => {
const index = nixin.value.services.indexOf(s);
if (index > -1) {
nixin.value.services.splice(index, 1);
}
})
} }
} }
</script> </script>
@ -117,34 +114,34 @@ export default {
<div class="form-cell"> <div class="form-cell">
<strong>Choose your network configuration</strong> <strong>Choose your network configuration</strong>
<label> <label>
<input type="radio" v-model="netconf" name="netconf" value="autoconfig" <input type="radio" v-model="nixin.netconf" value="autoconfig"
@click="netconfHasBeenChanged('autoconfig')">I'm a noob in network config, I trust you to provide networking @click="netconfHasBeenChanged('autoconfig')">I'm a noob in network config, I trust you to provide networking
for me (ipv6 only)</label> for me (ipv6 only)</label>
<label> <label>
<input type="radio" v-model="netconf" name="netconf" value="publicip" @click="netconfHasBeenChanged">My server <input type="radio" v-model="nixin.netconf" value="publicip" @click="netconfHasBeenChanged">My server
has a public ip that I can provide has a public ip that I can provide
</label> </label>
<label> <label>
<input type="radio" v-model="netconf" name="netconf" value="localnetwork" @click="netconfHasBeenChanged">My <input type="radio" v-model="nixin.netconf" value="localnetwork" @click="netconfHasBeenChanged">My
router is set so that my local machine is accessible on the public network router is set so that my local machine is accessible on the public network
</label> </label>
<label> <label>
<input type="radio" v-model="netconf" name="netconf" value="wireguard" @click="netconfHasBeenChanged">My server can use a wireguard server i can configure <input type="radio" v-model="nixin.netconf" value="wireguard" @click="netconfHasBeenChanged">My server can use a wireguard server i can configure
</label> </label>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-cell"> <div class="form-cell">
<label>Machine network name</label> <label>Machine network name</label>
<input required type="text" v-model="networkingHostname" <input required type="text" v-model="nixin.networkingHostname"
placeholder="Give your machine a name without spaces, ponctuation or accents" /> placeholder="Give your machine a name without spaces, ponctuation or accents" />
</div> </div>
</div> </div>
<input v-if="netconf === 'autoconfig'" type="hidden" value="distrilab.fr" /> <input v-if="nixin.netconf === 'autoconfig'" type="hidden" value="distrilab.fr" />
<div class="form-row" v-if="netconf !== 'autoconfig'"> <div class="form-row" v-if="nixin.netconf !== 'autoconfig'">
<div class="form-cell"> <div class="form-cell">
<label>Domain name</label> <label>Domain name</label>
<input required type="text" v-model="networkingDomain" placeholder="ex: distrilab.fr" /> <input required type="text" v-model="nixin.networkingDomain" placeholder="ex: distrilab.fr" />
</div> </div>
</div> </div>
@ -152,9 +149,9 @@ export default {
<div class="form-row"> <div class="form-row">
<div class="form-cell"> <div class="form-cell">
<strong>Choose your usage bundles (multiple choices possible if your machine can handle it)</strong> <strong>Choose your usage bundles (multiple choices possible if your machine can handle it)</strong>
<div v-for="bundle in availableBundles" :key="bundle"> <div v-for="bundle in nixin.availableBundles" :key="bundle">
<label> <label>
<input type="checkbox" v-model="nixinBundles" :id="bundle.id" :value="bundle.id" <input type="checkbox" v-model="nixin.bundles" :id="bundle.id" :value="bundle.id"
@change="selectServices(bundle.id, bundle.services)" /> @change="selectServices(bundle.id, bundle.services)" />
{{ bundle.name }} {{ bundle.name }}
</label> </label>
@ -163,13 +160,11 @@ export default {
</div> </div>
<h2>Services</h2> <h2>Services</h2>
<div v-if="nixinBundles.length === 0">👆 Choose any upper bundle to make associated services appear.</div> <div v-if="nixin.bundles.length === 0">👆 Choose any upper bundle to make associated services appear.</div>
<div v-for="service in availableServices" :key="service"> <div v-for="service in nixin.availableServices" :key="service">
<label v-if="service.inBundle && service.inBundle.some(ai => nixinBundles.includes(ai))"> <div v-if="service.inBundle && service.inBundle.some(ai => nixin.bundles.includes(ai))">
<NixForm :service="service.id" /> <NixForm :service="service" />
<input type="checkbox" v-model="nixinServices" :id="service.id" :value="service.id" /> </div>
{{ service.name }}
</label>
</div> </div>
<h2>Other configuration</h2> <h2>Other configuration</h2>
@ -189,8 +184,8 @@ export default {
]; ];
networking = { networking = {
hostName = "{{ networkingHostname }}"; hostName = "{{ nixin.networkingHostname }}";
domain = "{{ networkingDomain }}"; domain = "{{ nixin.networkingDomain }}";
nameservers = ["80.67.169.12" "2001:910:800::12" "80.67.169.40" "2001:910:800::40"]; nameservers = ["80.67.169.12" "2001:910:800::12" "80.67.169.40" "2001:910:800::40"];
wg-quick.interfaces = { wg-quick.interfaces = {
wg0 = { wg0 = {
@ -210,10 +205,10 @@ export default {
}; };
}; };
users.users.{{ user }} = { users.users.{{ nixin.user }} = {
isNormalUser = true; isNormalUser = true;
extraGroups = [ "wheel" ]; extraGroups = [ "wheel" ];
initialPassword = "{{ userPassword }}"; initialPassword = "{{ nixin.userPassword }}";
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBBM+2TwkopAQF7splTWjORQoxjcp67VhodwzvTMlL8g florian@florian-LinuxMint-MBP" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBBM+2TwkopAQF7splTWjORQoxjcp67VhodwzvTMlL8g florian@florian-LinuxMint-MBP"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILRG0CyeeMMrrjTTm/PHgRXD/I4lH/bBPBCGUiL+cBdq douzeb@tux-12" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILRG0CyeeMMrrjTTm/PHgRXD/I4lH/bBPBCGUiL+cBdq douzeb@tux-12"
@ -222,7 +217,7 @@ export default {
security.sudo.extraRules= [ security.sudo.extraRules= [
{ {
users = [ "{{ user }}" ]; users = [ "{{ nixin.user }}" ];
commands = [ commands = [
{ command = "ALL" ; { command = "ALL" ;
options= [ "NOPASSWD" ]; # "SETENV" # Adding the following could be a good idea options= [ "NOPASSWD" ]; # "SETENV" # Adding the following could be a good idea
@ -232,12 +227,12 @@ export default {
]; ];
time.timeZone = "{{ timezone }}"; time.timeZone = "{{ nixin.timezone }}";
i18n.defaultLocale = "{{ locale }}"; i18n.defaultLocale = "{{ nixin.locale }}";
<div v-for="(service) in nixinServices" :key="service"> <div v-for="(service) in nixin.services" :key="service">
<NixCode :service-name="service" /> <NixCode :service-name="service" />
</div> </div>
<div v-if="nixinServices.includes('gotosocial')"> <div v-if="nixin.services.includes('gotosocial')">
{ {
services.gotosocial = { services.gotosocial = {
enable = true; enable = true;
@ -274,7 +269,7 @@ export default {
</div> </div>
<div v-if="nixinServices.includes('peertube')"> <div v-if="nixin.services.includes('peertube')">
networking.extraHosts = '' networking.extraHosts = ''
127.0.0.1 peertube.local 127.0.0.1 peertube.local
''; '';
@ -334,7 +329,7 @@ export default {
}; };
</div> </div>
<div v-if="nixinServices.includes('lemmy')"> <div v-if="nixin.services.includes('lemmy')">
let let
# add nginx reverse proxy and ACME web certificate # add nginx reverse proxy and ACME web certificate
@ -573,7 +568,7 @@ export default {
} }
</div> </div>
<div v-if="nixinServices.includes('nextcloud')"> <div v-if="nixin.services.includes('nextcloud')">
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
hostName = "nextcloud.tld"; hostName = "nextcloud.tld";
@ -587,7 +582,7 @@ export default {
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];
</div> </div>
<div v-if="nixinServices.includes('hedgedoc')"> <div v-if="nixin.services.includes('hedgedoc')">
networking.firewall = { networking.firewall = {
allowedTCPPorts = [ 8001 ]; allowedTCPPorts = [ 8001 ];
}; };
@ -604,7 +599,7 @@ export default {
}; };
</div> </div>
<div v-if="nixinServices.includes('forgejorunner')"> <div v-if="nixin.services.includes('forgejorunner')">
virtualisation.containers.enable = true; virtualisation.containers.enable = true;
virtualisation.podman = { virtualisation.podman = {
enable = true; enable = true;
@ -638,7 +633,7 @@ export default {
}; };
</div> </div>
<div v-if="nixinServices.includes('forgejo')"> <div v-if="nixin.services.includes('forgejo')">
services.nginx = { services.nginx = {
virtualHosts.${cfg.settings.server.DOMAIN} = { virtualHosts.${cfg.settings.server.DOMAIN} = {
forceSSL = true; forceSSL = true;

View file

@ -4,7 +4,6 @@
<script> <script>
import * as components from './all' import * as components from './all'
console.log(components)
export default { export default {
components: { components: {
@ -12,7 +11,7 @@ console.log(components)
}, },
props: { props: {
type: { type: String, required: true } type: { type: String, required: true },
}, },
} }
</script> </script>

View file

@ -1,3 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template> <template>
forgejo <label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template> </template>

View file

@ -1,3 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template> <template>
forgejo runner <label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template> </template>

View file

@ -0,0 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template>
<label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template>

View file

@ -1,3 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template> <template>
hedgedoc form <label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template> </template>

View file

@ -0,0 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template>
<label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template>

View file

@ -1,3 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template> <template>
nextcloud form <label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template> </template>

View file

@ -1,3 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template> <template>
nixin <label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template> </template>

View file

@ -0,0 +1,11 @@
<script setup>
import { inject } from 'vue'
let nixin = inject('nixin')
const service = inject('service')
</script>
<template>
<label>
<input type="checkbox" v-model="nixin.services" :value="service.id" />
{{service.name}}
</label>
</template>

View file

@ -1,8 +1,11 @@
<script setup> <script setup>
import {provide} from 'vue';
import DynamicComponent from "./DynamicComponent.vue" import DynamicComponent from "./DynamicComponent.vue"
const props = defineProps(['service']) const props = defineProps(['service'])
let serviceComponent = 'NixForm'+props.service let serviceComponent = 'NixForm'+props.service.id
provide('service', props.service)
</script> </script>
<template> <template>

View file

@ -1,3 +1,6 @@
export { default as NixFormgotosocial } from './NixForm-gotosocial.vue'
export { default as NixFormpeertube } from './NixForm-peertube.vue'
export { default as NixFormlemmy } from './NixForm-lemmy.vue'
export { default as NixFormnextcloud } from './NixForm-nextcloud.vue' export { default as NixFormnextcloud } from './NixForm-nextcloud.vue'
export { default as NixFormhedgedoc } from './NixForm-hedgedoc.vue' export { default as NixFormhedgedoc } from './NixForm-hedgedoc.vue'
export { default as NixFormforgejo } from './NixForm-forgejo.vue' export { default as NixFormforgejo } from './NixForm-forgejo.vue'