nixin-web/components/ConfigForm.vue

296 lines
8 KiB
Vue
Raw Normal View History

2024-10-09 11:05:41 +00:00
<script setup>
import NixCode from "./NixCode.vue"
import NixForm from "./NixForm.vue"
import { provide, ref } from 'vue'
import { listTz, clientTz } from 'timezone-select-js';
const availableLanguages = {
'en_US.UTF-8': 'English',
'fr_FR.UTF-8': 'Francais'
}
const availableTimezones = listTz()
let nixin = {
netconf: 'autoconfig',
networkingHostname: '',
networkingDomain: 'nixin.local',
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'
]
2024-10-09 11:05:41 +00:00
},
{
"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"
}],
bundles: [],
services: [],
timezone: 'Europe/Belfast', // default to UTC but could be found with clientTz(),
locale: 'en_US.UTF-8',
operatingUser: 'operator',
operatingUserPassword: '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 = 'nixin.local'
} 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>
<template>
<h2>Networking</h2>
<div class="form-cell">
<strong>Choose your network configuration</strong>
<div>
<label>
<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
for me (ipv6 only)</label>
</div>
<div>
<label>
<input type="radio" v-model="nixin.netconf" value="publicip" @click="netconfHasBeenChanged">My server
has a public ip that I can provide
</label>
</div>
<div>
<label>
<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
</label>
</div>
<div>
<label>
<input type="radio" v-model="nixin.netconf" value="wireguard" @click="netconfHasBeenChanged">My server can use a wireguard server i can configure
</label>
</div>
</div>
<div class="form-row">
<div class="form-cell">
<label>Machine network name</label>
<input required type="text" v-model="nixin.networkingHostname"
placeholder="Give your machine a name without spaces, ponctuation or accents" />
</div>
</div>
<input v-if="nixin.netconf === 'autoconfig'" type="hidden" value="distrilab.fr" />
<div class="form-row" v-if="nixin.netconf !== 'autoconfig'">
<div class="form-cell">
<label>Domain name</label>
<input required type="text" v-model="nixin.networkingDomain" placeholder="ex: distrilab.fr" />
</div>
</div>
<h2>Usage bundles</h2>
<div class="form-row">
<div class="form-cell">
<strong>Choose your usage bundles (multiple choices possible if your machine can handle it)</strong>
<div v-for="bundle in nixin.availableBundles" :key="bundle">
<label>
<input type="checkbox" v-model="nixin.bundles" :id="bundle.id" :value="bundle.id"
@change="selectServices(bundle.id, bundle.services)" />
{{ bundle.name }}
</label>
</div>
</div>
</div>
<h2>Services</h2>
<div v-if="nixin.bundles.length === 0">👆 Choose any upper bundle to make associated services appear.</div>
<div v-for="service in nixin.availableServices" :key="service">
<div v-if="service.inBundle && service.inBundle.some(ai => nixin.bundles.includes(ai))">
<NixForm :service="service" />
</div>
</div>
<h2>Other configuration</h2>
<div class="form-row">
<div class="form-cell">
<label>Operating UNIX user name</label>
<input required type="text" v-model="nixin.operatingUser" />
</div>
</div>
<div class="form-row">
<div class="form-cell">
<label>Operating UNIX user password</label>
<input required type="text" v-model="nixin.operatingUserPassword" />
</div>
</div>
<div class="form-row">
<div class="form-cell">
<label>Timezone</label>
<select v-model="nixin.timezone">
<option v-for="tz in availableTimezones" :selected="nixin.timezone === tz.value" v-bind:value="tz.value">{{ tz.label }}</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-cell">
<label>Locale</label>
<select v-model="nixin.locale">
<option v-for="(lang, k) in availableLanguages" :selected="nixin.locale === k" v-bind:value="k">{{ lang }}</option>
</select>
</div>
</div>
<h2>Auto-generated configuration.nix file</h2>
<pre class="nix-code">
<code>
{ pkgs, ... }:
{
networking.hosts = {
"127.0.0.1" = [ "{{ nixin.networkingHostname }}.{{nixin.networkingDomain}}" ];
};
networking.hostName = "{{ nixin.networkingHostname }}";
networking.domain = "{{ nixin.networkingDomain }}";
networking.firewall = {
allowedTCPPorts = [
80
443
];
};
time.timeZone = "{{ nixin.timezone }}";
i18n.defaultLocale = "{{ nixin.locale }}";
<div v-for="(service) in nixin.services" :key="service">
<NixCode :service="service"/>
</div>
users.users.{{ nixin.operatingUser }} = {
isNormalUser = true;
extraGroups = [ "wheel" ];
initialPassword = "{{ nixin.operatingUserPassword }}";
};
security.sudo.extraRules= [
{
users = [ "{{ nixin.operatingUser }}" ];
commands = [
{
command = "ALL" ;
options= [ "NOPASSWD" ]; # "SETENV" # Adding the following could be a good idea
}
];
}
];
security.acme.defaults.email = "contact@nixin.local";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
# Use recommended settings
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
# Only allow PFS-enabled ciphers with AES256
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
virtualHosts."hedgedoc.nixin.local" = {
forceSSL = true;
enableACME = true;
root = "/var/www/hedgedoc";
locations."/".proxyPass = "http://127.0.0.1:8001";
locations."/socket.io/" = {
proxyPass = "http://127.0.0.1:8001";
proxyWebsockets = true;
extraConfig = "proxy_ssl_server_name on;";
};
};
};
environment.systemPackages = with pkgs; [
git
wget
tmux
mosh
htop
];
system.stateVersion = "24.05";
}
</code>
</pre>
</template>