Skip to content

Commit

Permalink
Merge pull request #48 from 45Drives/dev-josh
Browse files Browse the repository at this point in the history
Features/Fixes for File Sharing 3.2.4
  • Loading branch information
joshuaboud authored Aug 18, 2022
2 parents b44c9f8 + 9e9d09b commit bf91a52
Show file tree
Hide file tree
Showing 11 changed files with 384 additions and 81 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
## Cockpit File Sharing 3.2.3-1
## Cockpit File Sharing 3.2.4-1

* Fixed issue saving NFS exports file when /etc/exports.d DNE
* Add settings menu for configuring smb.conf and exports file locations
* Fix parsing "valid users" field for Samba shares
180 changes: 180 additions & 0 deletions file-sharing/src/components/Config.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<!--
Copyright (C) 2022 Josh Boudreau <jboudreau@45drives.com>

This file is part of Cockpit File Sharing.

Cockpit File Sharing is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Cockpit File Sharing is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Cockpit File Sharing.
If not, see <https://www.gnu.org/licenses/>.
-->

<template>
<button
type="button"
@click="show = true"
>
<CogIcon class="size-icon icon-default" />
</button>
<ModalPopup
:showModal="show"
headerText="File Sharing Settings"
cancelText="Close"
@apply="writeConfig"
@cancel="hide"
:disableContinue="noChanges"
>
<div class="flex flex-col items-stretch gap-content">
<div class="text-header">Samba</div>
<div>
<label class="text-label block">
Configuration Path
</label>
<input
v-model="configTmp.samba.confPath"
type="text"
class="input-textlike w-full block"
placeholder="default: /etc/samba/smb.conf"
/>
</div>
<div class="text-header">NFS</div>
<div>
<label class="text-label block">
Configuration Path
</label>
<input
v-model="configTmp.nfs.confPath"
type="text"
class="input-textlike w-full block"
placeholder="default: /etc/exports.d/cockpit-file-sharing.exports"
/>
</div>
</div>
</ModalPopup>
</template>

<script lang="ts">
import { reactive, ref, defineComponent, watch, computed } from 'vue';
import { CogIcon } from '@heroicons/vue/solid';
import ModalPopup from './ModalPopup.vue';

declare global {
var cockpit: any = {};
}

interface FileSharingConfig {
/**
* Samba-specific settings
*/
samba: {
/**
* Path to smb.conf
*/
confPath: string;
}
/**
* NFS-specific settings
*/
nfs: {
/**
* Path to cockpit-file-sharing.exports or equivalent
*/
confPath: string;
}
}

function deepCopy<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
}

const assignConfig = (target: any, source: FileSharingConfig, defaults: FileSharingConfig): FileSharingConfig => {
Object.assign(target, {
samba: {
confPath: source?.samba?.confPath || defaults.samba.confPath,
},
nfs: {
confPath: source?.nfs?.confPath || defaults.nfs.confPath,
}
});
return target as FileSharingConfig;
}

const configPath = "/etc/cockpit-file-sharing.conf.json";

const configFile = cockpit.file(configPath, {
superuser: 'try',
syntax: {
parse: (str: string) => JSON.parse(str),
stringify: (obj: any) => JSON.stringify(obj, null, 2),
}
});

const configDefaults: FileSharingConfig = {
samba: {
confPath: "/etc/samba/smb.conf",
},
nfs: {
confPath: "/etc/exports.d/cockpit-file-sharing.exports"
}
};

const config: FileSharingConfig = reactive(deepCopy(configDefaults));

const loadConfig = (onDiskConfig: FileSharingConfig | null) => {
console.log(onDiskConfig);
if (onDiskConfig === null) {
console.log('file DNE');
} else {
console.log('has content');
assignConfig(config, onDiskConfig, configDefaults);
}
}

configFile.watch(loadConfig);

export function useConfig() {
return config;
}

export default defineComponent({
setup() {
const show = ref(false);
const noChanges = computed(() => configTmp.nfs.confPath === config.nfs.confPath && configTmp.samba.confPath === config.samba.confPath);

const configTmp: FileSharingConfig = reactive(deepCopy(configDefaults));

const writeConfig = () => {
assignConfig(config, configTmp, configDefaults);
configFile.replace(config);
}

const hide = () => {
show.value = false;
configFile.read(); // trigger watch to reset fields
}

watch(config, () => {
assignConfig(configTmp, config, configDefaults);
});

return {
show,
noChanges,
configTmp,
hide,
writeConfig,
config,
}
},
components: {
ModalPopup,
CogIcon,
}
})
</script>
10 changes: 6 additions & 4 deletions file-sharing/src/components/FilePermissions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ If not, see <https://www.gnu.org/licenses/>.
</template>

<script>
import { watch, ref, inject } from 'vue';
import { watch, ref, inject, onMounted } from 'vue';
import ModalPopup from "./ModalPopup.vue";
import FileModeMatrix from "./FileModeMatrix.vue";
import { useSpawn, errorString, canonicalPath } from "@45drives/cockpit-helpers";
Expand Down Expand Up @@ -118,9 +118,11 @@ export default {
emit('hide');
}

watch(() => props.show, (show, lastShow) => {
if (show || lastShow === undefined) getPermissions();
}, { immediate: true });
onMounted(() => {
watch(() => props.show, (show, lastShow) => {
if (show) getPermissions();
}, { immediate: true });
});

return {
mode,
Expand Down
46 changes: 35 additions & 11 deletions file-sharing/src/components/HoustonHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,41 @@ If not, see <https://www.gnu.org/licenses/>.
</h1>
</div>
<slot />
<LoadingSpinner v-if="showSpinner" class="size-icon self-center" />
<LoadingSpinner
v-if="showSpinner"
class="size-icon self-center"
/>
</div>
<h1
class="text-red-800 dark:text-white text-base sm:text-2xl cursor-pointer grow-0 text-center"
@click="home"
>{{ moduleName }}</h1>
<div class="flex basis-32 justify-end items-center grow shrink-0 gap-buttons">
<div
:class="[infoButtonInHeader ? '' : 'md:fixed md:right-2 md:bottom-2 md:z-50 flex flex-row items-stretch']"
>
<button @click="showInfo = true">
<QuestionMarkCircleIcon class="size-icon icon-default" />
</button>
:class="[infoButtonInHeader ? '' : 'md:fixed md:right-2 md:bottom-2 md:z-50 flex flex-row items-stretch']">
<div class="inline-button-group-row">
<Config />
<button @click="showInfo = true">
<QuestionMarkCircleIcon class="size-icon icon-default" />
</button>
</div>
<div
class="overflow-y-auto"
:style="{ 'scrollbar-gutter': infoNudgeScrollbar ? 'stable' : 'auto' }"
></div>
</div>
<button @click="darkMode = !darkMode" @click.right.prevent="vape">
<SunIcon v-if="darkMode" class="size-icon-lg icon-default" />
<MoonIcon v-else class="size-icon-lg icon-default" />
<button
@click="darkMode = !darkMode"
@click.right.prevent="vape"
>
<SunIcon
v-if="darkMode"
class="size-icon-lg icon-default"
/>
<MoonIcon
v-else
class="size-icon-lg icon-default"
/>
</button>
</div>
</div>
Expand All @@ -73,8 +87,16 @@ If not, see <https://www.gnu.org/licenses/>.
target="_blank"
>45Drives</a> for Houston UI (Cockpit)
</span>
<a class="text-link" :href="sourceURL" target="_blank">Source Code</a>
<a class="text-link" :href="issuesURL" target="_blank">Issue Tracker</a>
<a
class="text-link"
:href="sourceURL"
target="_blank"
>Source Code</a>
<a
class="text-link"
:href="issuesURL"
target="_blank"
>Issue Tracker</a>
</div>
</ModalPopup>
</template>
Expand All @@ -87,6 +109,7 @@ import { SunIcon, MoonIcon, QuestionMarkCircleIcon } from "@heroicons/vue/solid"
import { ref, watch, inject } from "vue";
import LoadingSpinner from "./LoadingSpinner.vue";
import ModalPopup from './ModalPopup.vue';
import Config from "./Config.vue";

export default {
props: {
Expand Down Expand Up @@ -167,6 +190,7 @@ export default {
LoadingSpinner,
ModalPopup,
QuestionMarkCircleIcon,
Config,
}
};
</script>
Loading

0 comments on commit bf91a52

Please sign in to comment.