Skip to content

Commit

Permalink
fix: improve Windows path handling
Browse files Browse the repository at this point in the history
  • Loading branch information
garethgeorge committed Dec 8, 2023
1 parent 019a0c0 commit 426aad4
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 10 deletions.
8 changes: 8 additions & 0 deletions internal/orchestrator/taskbackup.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,20 @@ func backupHelper(ctx context.Context, orchestrator *Orchestrator, plan *v1.Plan
}

lastSent := time.Now() // debounce progress updates, these can endup being very frequent.
var lastFiles []string
summary, err := repo.Backup(ctx, plan, func(entry *restic.BackupProgressEntry) {
if time.Since(lastSent) < 250*time.Millisecond {
return
}
lastSent = time.Now()

// prevents flickering output when a status entry omits the CurrentFiles property. Largely cosmetic.
if len(entry.CurrentFiles) == 0 {
entry.CurrentFiles = lastFiles
} else {
lastFiles = entry.CurrentFiles
}

backupOp.OperationBackup.LastStatus = protoutil.BackupProgressEntryToProto(entry)
if err := orchestrator.OpLog.Update(op); err != nil {
zap.S().Errorf("failed to update oplog with progress for backup: %v", err)
Expand Down
3 changes: 2 additions & 1 deletion webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "",
"scripts": {
"start": "parcel serve src/index.html",
"build": "RESTICUI_BUILD_VERSION=$(git describe --tags --abbrev=0) parcel build src/index.html",
"build": "RESTICUI_BUILD_VERSION=$(git describe --tags --abbrev=0) UI_OS=unix parcel build src/index.html",
"build-windows": "set UI_OS=windows & set RESTICUI_BUILD_VERSION=$(git describe --tags --abbrev=0) & parcel build src/index.html",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
Expand Down
39 changes: 35 additions & 4 deletions webui/src/components/URIAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { AutoComplete } from "antd";
import React, { useEffect, useState } from "react";
import { ResticUI } from "../../gen/ts/v1/service.pb";
import { StringList } from "../../gen/ts/types/value.pb";
import { isWindows } from "../state/buildcfg";

let timeout: NodeJS.Timeout | undefined = undefined;
const sep = isWindows ? "\\" : "/";

export const URIAutocomplete = (props: React.PropsWithChildren<any>) => {
const [value, setValue] = useState("");
Expand All @@ -17,7 +19,7 @@ export const URIAutocomplete = (props: React.PropsWithChildren<any>) => {
const onChange = (value: string) => {
setValue(value);

const lastSlash = value.lastIndexOf("/");
const lastSlash = value.lastIndexOf(sep);
if (lastSlash !== -1) {
value = value.substring(0, lastSlash);
}
Expand All @@ -27,14 +29,14 @@ export const URIAutocomplete = (props: React.PropsWithChildren<any>) => {
}

timeout = setTimeout(() => {
ResticUI.PathAutocomplete({ value: value + "/" }, { pathPrefix: "/api" })
ResticUI.PathAutocomplete({ value: value + sep }, { pathPrefix: "/api" })
.then((res: StringList) => {
if (!res.values) {
return;
}
const vals = res.values.map((v) => {
return {
value: value + "/" + v,
value: value + sep + v,
};
});
setOptions(vals);
Expand All @@ -45,5 +47,34 @@ export const URIAutocomplete = (props: React.PropsWithChildren<any>) => {
}, 100);
};

return <AutoComplete options={showOptions} onSearch={onChange} {...props} />;
return (
<AutoComplete
options={showOptions}
onSearch={onChange}
rules={[
{
validator: async (_: any, value: string) => {
if (props.globAllowed) {
return Promise.resolve();
}
if (isWindows) {
if (value.match(/^[a-zA-Z]:\\$/)) {
return Promise.reject(
new Error("Path must start with a drive letter e.g. C:\\")
);
} else if (value.includes("/")) {
return Promise.reject(
new Error(
"Path must use backslashes e.g. C:\\Users\\MyUsers\\Documents"
)
);
}
}
return Promise.resolve();
},
},
]}
{...props}
/>
);
};
5 changes: 5 additions & 0 deletions webui/src/state/buildcfg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const uios = (process.env.UI_OS || "").trim().toLowerCase();
export const isWindows = uios === "windows";
export const uiBuildVersion = (
process.env.RESTICUI_BUILD_VERSION || "dev"
).trim();
1 change: 1 addition & 0 deletions webui/src/views/AddPlanModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ export const AddPlanModal = ({
<URIAutocomplete
style={{ width: "90%" }}
onBlur={() => form.validateFields()}
globAllowed={true}
/>
</Form.Item>
<MinusCircleOutlined
Expand Down
9 changes: 4 additions & 5 deletions webui/src/views/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import {
import type { MenuProps } from "antd";
import { Button, Layout, Menu, Spin, theme } from "antd";
import { configState, fetchConfig } from "../state/config";
import { useRecoilState, useRecoilValue } from "recoil";
import { useRecoilState } from "recoil";
import { Config } from "../../gen/ts/v1/config.pb";
import { useAlertApi } from "../components/Alerts";
import { useShowModal } from "../components/ModalManager";
import { MainContentArea, useSetContent } from "./MainContentArea";
import { AddPlanModal } from "./AddPlanModal";
import { uiBuildVersion } from "../state/buildcfg";

const { Header, Content, Sider } = Layout;
const { Header, Sider } = Layout;

export const App: React.FC = () => {
const {
Expand Down Expand Up @@ -58,9 +59,7 @@ export const App: React.FC = () => {
BackRest<span style={{ color: "grey" }}>ic</span>{" "}
</a>
<small style={{ color: "rgba(255,255,255,0.3)", fontSize: "0.6em" }}>
{process.env.RESTICUI_BUILD_VERSION
? process.env.RESTICUI_BUILD_VERSION
: ""}
{uiBuildVersion}
</small>
</h1>
</Header>
Expand Down

0 comments on commit 426aad4

Please sign in to comment.