mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-09-27 18:35:36 +00:00
fix: misc UI and backend bug fixes
This commit is contained in:
@@ -16,7 +16,6 @@ require (
|
||||
go.etcd.io/bbolt v1.3.9
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/sync v0.6.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda
|
||||
@@ -33,5 +32,6 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
|
||||
)
|
||||
|
||||
@@ -58,8 +58,6 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
@@ -71,14 +69,10 @@ golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa h1:Jt1XW5PaLXF1/ePZrznsh/aAUvI7Adfc3LY1dAKlzRs=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:K4kfzHtI0kqWA79gecJarFtDn/Mls+GxQcg3Zox91Ac=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda h1:b6F6WIV4xHHD0FA4oIyzU6mHWg2WI2X1RBehwa5QN38=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda/go.mod h1:AHcE/gZH76Bk/ROZhQphlRoWo5xKDEtz3eVEO1LfA8c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa h1:RBgMaUMP+6soRkik4VoN8ojR2nex2TqZwjSSogic+eo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
||||
|
||||
@@ -230,7 +230,6 @@ func (s *BackrestHandler) GetOperationEvents(ctx context.Context, req *connect.R
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case event := <-events:
|
||||
zap.S().Infof("sending event %v", event)
|
||||
if err := resp.Send(event); err != nil {
|
||||
return fmt.Errorf("failed to write event: %w", err)
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@ func (t *TimeQueue[T]) Dequeue(ctx context.Context) T {
|
||||
select {
|
||||
case <-timer.C:
|
||||
t.mu.Lock()
|
||||
if len(t.heap) == 0 {
|
||||
t.mu.Unlock()
|
||||
continue
|
||||
}
|
||||
val, ok := heap.Pop(&t.heap).(timeQueueEntry[T])
|
||||
if !ok || val.at.After(time.Now()) {
|
||||
t.mu.Unlock()
|
||||
|
||||
@@ -14,6 +14,7 @@ body
|
||||
pre
|
||||
// force text to wrap on overflow even in 'pre' elements.
|
||||
white-space: pre-wrap
|
||||
overflow-x: auto
|
||||
|
||||
.visible-on-hover .hidden-child
|
||||
visibility: hidden
|
||||
|
||||
@@ -487,22 +487,26 @@ const RetentionPolicyView = () => {
|
||||
const form = Form.useFormInstance();
|
||||
const retention = Form.useWatch('retention', { form, preserve: true }) as any;
|
||||
|
||||
if (!retention) {
|
||||
form.setFieldValue("retention", { policyTimeBucketed: { yearly: 0, monthly: 3, weekly: 4, daily: 7, hourly: 24 } });
|
||||
}
|
||||
|
||||
const determineMode = () => {
|
||||
if (!retention) {
|
||||
return 2;
|
||||
return "policyTimeBucketed";
|
||||
} else if (retention.policyKeepLastN) {
|
||||
return 1;
|
||||
return "policyKeepLastN"
|
||||
} else if (retention.policyKeepAll) {
|
||||
return 0;
|
||||
return "policyKeepAll"
|
||||
} else if (retention.policyTimeBucketed) {
|
||||
return 2;
|
||||
return "policyTimeBucketed"
|
||||
}
|
||||
}
|
||||
|
||||
const mode = determineMode();
|
||||
|
||||
let elem: React.ReactNode = null;
|
||||
if (mode === 0) {
|
||||
if (mode === "policyKeepAll") {
|
||||
elem = <>
|
||||
<p>All backups are retained e.g. for append-only repos. Ensure that you manually forget / prune backups elsewhere. Backrest will register forgets performed externally on the next backup.</p>
|
||||
<Form.Item
|
||||
@@ -514,7 +518,7 @@ const RetentionPolicyView = () => {
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
</>
|
||||
} else if (mode === 1) {
|
||||
} else if (mode === "policyKeepLastN") {
|
||||
elem = (
|
||||
<Form.Item
|
||||
name={["retention", "policyKeepLastN"]}
|
||||
@@ -530,7 +534,7 @@ const RetentionPolicyView = () => {
|
||||
<InputNumber addonBefore={<div style={{ width: "5em" }}>Count</div>} type="number" />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (mode === 2) {
|
||||
} else if (mode === "policyTimeBucketed") {
|
||||
elem = (
|
||||
<Row>
|
||||
<Col span={11}>
|
||||
@@ -602,25 +606,25 @@ const RetentionPolicyView = () => {
|
||||
<Row>
|
||||
<Radio.Group value={mode} onChange={e => {
|
||||
const selected = e.target.value;
|
||||
if (selected === 1) {
|
||||
if (selected === "policyKeepLastN") {
|
||||
form.setFieldValue("retention", { policyKeepLastN: 30 });
|
||||
} else if (selected === 2) {
|
||||
form.setFieldValue("retention", { policyTimeBucketed: { keepYearly: 0, keepMonthly: 3, keepWeekly: 4, keepDaily: 7, keepHourly: 24 } });
|
||||
} else if (selected === "policyTimeBucketed") {
|
||||
form.setFieldValue("retention", { policyTimeBucketed: { yearly: 0, monthly: 3, weekly: 4, daily: 7, hourly: 24 } });
|
||||
} else {
|
||||
form.setFieldValue("retention", { policyKeepAll: true });
|
||||
}
|
||||
}}>
|
||||
<Radio.Button value={1}>
|
||||
<Radio.Button value={"policyKeepLastN"}>
|
||||
<Tooltip title="The last N snapshots will be kept by restic. Retention policy is applied to drop older snapshots after each backup run.">
|
||||
By Count
|
||||
</Tooltip>
|
||||
</Radio.Button>
|
||||
<Radio.Button value={2}>
|
||||
<Radio.Button value={"policyTimeBucketed"}>
|
||||
<Tooltip title="Snapshots older than the specified time period will be dropped by restic. Retention policy is applied to drop older snapshots after each backup run." >
|
||||
By Time Period
|
||||
</Tooltip>
|
||||
</Radio.Button>
|
||||
<Radio.Button value={0}>
|
||||
<Radio.Button value={"policyKeepAll"}>
|
||||
<Tooltip title="All backups will be retained. Note that this may result in slow backups if the set of snapshots grows very large.">
|
||||
None
|
||||
</Tooltip>
|
||||
|
||||
Reference in New Issue
Block a user