feat(proto): report per-repository sync errors, drop the reason from mirror_failed and tidy mirror docs
6 files · +57 -67
M docs/services.md +2 -2
| @@ -34,7 +34,7 @@ No new token scope is introduced. | |||
| 34 | 34 | | `SetRepoMirrorExcluded` | `repo:admin` on the repository. Opts out of or into the global template; a URL override wins over exclusion | | |
| 35 | 35 | | `GetMirrorStatus` | Read access to the repository. Error `detail` is returned only with `repo:admin` | | |
| 36 | 36 | | `ListMirrorStatus` | Owner rights | | |
| 37 | - | | `SyncMirror` | `repo:admin` for `repo`, or owner rights for `all=true` (with empty `repo`). Returns per-repository results, including queued and no-op indicators | | |
| 37 | + | | `SyncMirror` | `repo:admin` for `repo`, or owner rights for `all=true` (with empty `repo`). Returns per-repository results, including queued and no-op indicators and a per-repository `error`; `all=true` continues past failing repositories and skips disabled ones | | |
| 38 | 38 | ||
| 39 | 39 | Cron expressions have five fields, run in UTC and must be at least five minutes | |
| 40 | 40 | apart. Mirrors push the default branch (or every branch with `all_branches`) and | |
| @@ -49,4 +49,4 @@ starts failing (ok or disabled to failing or paused, once per incident), and `mi | |||
| 49 | 49 | (field 24, `MirrorRecovered`) when a failing or paused mirror succeeds again. | |
| 50 | 50 | These are transition events, not events for every attempt. They are delivered on | |
| 51 | 51 | `repo:<name>` and `home`, subject to repository visibility. Neither event carries | |
| 52 | - | a URL or error detail. | |
| 52 | + | a URL, reason or error detail (`MirrorFailed` field 4, `reason`, was removed). | |
| @@ -34,7 +34,7 @@ No new token scope is introduced. | |||||
| 34 | | `SetRepoMirrorExcluded` | `repo:admin` on the repository. Opts out of or into the global template; a URL override wins over exclusion | | 34 | | `SetRepoMirrorExcluded` | `repo:admin` on the repository. Opts out of or into the global template; a URL override wins over exclusion | | ||
| 35 | | `GetMirrorStatus` | Read access to the repository. Error `detail` is returned only with `repo:admin` | | 35 | | `GetMirrorStatus` | Read access to the repository. Error `detail` is returned only with `repo:admin` | | ||
| 36 | | `ListMirrorStatus` | Owner rights | | 36 | | `ListMirrorStatus` | Owner rights | | ||
| 37 | - | | `SyncMirror` | `repo:admin` for `repo`, or owner rights for `all=true` (with empty `repo`). Returns per-repository results, including queued and no-op indicators | | 37 | + | | `SyncMirror` | `repo:admin` for `repo`, or owner rights for `all=true` (with empty `repo`). Returns per-repository results, including queued and no-op indicators and a per-repository `error`; `all=true` continues past failing repositories and skips disabled ones | |
| 38 | 38 | ||||
| 39 | Cron expressions have five fields, run in UTC and must be at least five minutes | 39 | Cron expressions have five fields, run in UTC and must be at least five minutes | ||
| 40 | apart. Mirrors push the default branch (or every branch with `all_branches`) and | 40 | apart. Mirrors push the default branch (or every branch with `all_branches`) and | ||
| @@ -49,4 +49,4 @@ starts failing (ok or disabled to failing or paused, once per incident), and `mi | |||||
| 49 | (field 24, `MirrorRecovered`) when a failing or paused mirror succeeds again. | 49 | (field 24, `MirrorRecovered`) when a failing or paused mirror succeeds again. | ||
| 50 | These are transition events, not events for every attempt. They are delivered on | 50 | These are transition events, not events for every attempt. They are delivered on | ||
| 51 | `repo:<name>` and `home`, subject to repository visibility. Neither event carries | 51 | `repo:<name>` and `home`, subject to repository visibility. Neither event carries | ||
| 52 | - | a URL or error detail. | 52 | + | a URL, reason or error detail (`MirrorFailed` field 4, `reason`, was removed). |
M gen/ermite/event.pb.go +6 -16 generated file: collapsed
M gen/ermite/mirror.pb.go +27 -21
| @@ -28,16 +28,14 @@ const ( | |||
| 28 | 28 | type MirrorSource int32 | |
| 29 | 29 | ||
| 30 | 30 | const ( | |
| 31 | - | // Unspecified. | |
| 31 | + | // MIRROR_SOURCE_DISABLED: nothing applies; MIRROR_SOURCE_GLOBAL: the global | |
| 32 | + | // template; MIRROR_SOURCE_OVERRIDE: a per-repository URL; | |
| 33 | + | // MIRROR_SOURCE_EXCLUDED: opted out of the global template. | |
| 32 | 34 | MirrorSource_MIRROR_SOURCE_UNSPECIFIED MirrorSource = 0 | |
| 33 | - | // Disabled. | |
| 34 | - | MirrorSource_MIRROR_SOURCE_DISABLED MirrorSource = 1 | |
| 35 | - | // Global. | |
| 36 | - | MirrorSource_MIRROR_SOURCE_GLOBAL MirrorSource = 2 | |
| 37 | - | // Override. | |
| 38 | - | MirrorSource_MIRROR_SOURCE_OVERRIDE MirrorSource = 3 | |
| 39 | - | // Excluded. | |
| 40 | - | MirrorSource_MIRROR_SOURCE_EXCLUDED MirrorSource = 4 | |
| 35 | + | MirrorSource_MIRROR_SOURCE_DISABLED MirrorSource = 1 | |
| 36 | + | MirrorSource_MIRROR_SOURCE_GLOBAL MirrorSource = 2 | |
| 37 | + | MirrorSource_MIRROR_SOURCE_OVERRIDE MirrorSource = 3 | |
| 38 | + | MirrorSource_MIRROR_SOURCE_EXCLUDED MirrorSource = 4 | |
| 41 | 39 | ) | |
| 42 | 40 | ||
| 43 | 41 | // Enum value maps for MirrorSource. | |
| @@ -89,16 +87,13 @@ func (MirrorSource) EnumDescriptor() ([]byte, []int) { | |||
| 89 | 87 | type MirrorState int32 | |
| 90 | 88 | ||
| 91 | 89 | const ( | |
| 92 | - | // Unspecified. | |
| 90 | + | // MIRROR_STATE_OK: last sync succeeded; MIRROR_STATE_FAILING: retrying with | |
| 91 | + | // backoff; MIRROR_STATE_PAUSED: stopped until a forced sync or a config change. | |
| 93 | 92 | MirrorState_MIRROR_STATE_UNSPECIFIED MirrorState = 0 | |
| 94 | - | // Disabled. | |
| 95 | - | MirrorState_MIRROR_STATE_DISABLED MirrorState = 1 | |
| 96 | - | // Ok. | |
| 97 | - | MirrorState_MIRROR_STATE_OK MirrorState = 2 | |
| 98 | - | // Failing. | |
| 99 | - | MirrorState_MIRROR_STATE_FAILING MirrorState = 3 | |
| 100 | - | // Paused. | |
| 101 | - | MirrorState_MIRROR_STATE_PAUSED MirrorState = 4 | |
| 93 | + | MirrorState_MIRROR_STATE_DISABLED MirrorState = 1 | |
| 94 | + | MirrorState_MIRROR_STATE_OK MirrorState = 2 | |
| 95 | + | MirrorState_MIRROR_STATE_FAILING MirrorState = 3 | |
| 96 | + | MirrorState_MIRROR_STATE_PAUSED MirrorState = 4 | |
| 102 | 97 | ) | |
| 103 | 98 | ||
| 104 | 99 | // Enum value maps for MirrorState. | |
| @@ -1465,7 +1460,10 @@ type SyncMirrorResult struct { | |||
| 1465 | 1460 | // NoOp says the refs already matched the last successful snapshot. | |
| 1466 | 1461 | NoOp bool `protobuf:"varint,3,opt,name=no_op,json=noOp,proto3" json:"no_op,omitempty"` | |
| 1467 | 1462 | // Status is the current mirror status. | |
| 1468 | - | Status *MirrorStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` | |
| 1463 | + | Status *MirrorStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` | |
| 1464 | + | // Error is a human-readable failure of this repository's sync, empty on | |
| 1465 | + | // success. It never contains the mirror URL. | |
| 1466 | + | Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` | |
| 1469 | 1467 | unknownFields protoimpl.UnknownFields | |
| 1470 | 1468 | sizeCache protoimpl.SizeCache | |
| 1471 | 1469 | } | |
| @@ -1528,6 +1526,13 @@ func (x *SyncMirrorResult) GetStatus() *MirrorStatus { | |||
| 1528 | 1526 | return nil | |
| 1529 | 1527 | } | |
| 1530 | 1528 | ||
| 1529 | + | func (x *SyncMirrorResult) GetError() string { | |
| 1530 | + | if x != nil { | |
| 1531 | + | return x.Error | |
| 1532 | + | } | |
| 1533 | + | return "" | |
| 1534 | + | } | |
| 1535 | + | ||
| 1531 | 1536 | // SyncMirrorResponse holds the result of SyncMirror. | |
| 1532 | 1537 | type SyncMirrorResponse struct { | |
| 1533 | 1538 | state protoimpl.MessageState `protogen:"open.v1"` | |
| @@ -1659,12 +1664,13 @@ const file_ermite_mirror_proto_rawDesc = "" + | |||
| 1659 | 1664 | "\x11SyncMirrorRequest\x12\x12\n" + | |
| 1660 | 1665 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x10\n" + | |
| 1661 | 1666 | "\x03all\x18\x02 \x01(\bR\x03all\x12\x14\n" + | |
| 1662 | - | "\x05force\x18\x03 \x01(\bR\x05force\"\x81\x01\n" + | |
| 1667 | + | "\x05force\x18\x03 \x01(\bR\x05force\"\x97\x01\n" + | |
| 1663 | 1668 | "\x10SyncMirrorResult\x12\x12\n" + | |
| 1664 | 1669 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x16\n" + | |
| 1665 | 1670 | "\x06queued\x18\x02 \x01(\bR\x06queued\x12\x13\n" + | |
| 1666 | 1671 | "\x05no_op\x18\x03 \x01(\bR\x04noOp\x12,\n" + | |
| 1667 | - | "\x06status\x18\x04 \x01(\v2\x14.ermite.MirrorStatusR\x06status\"H\n" + | |
| 1672 | + | "\x06status\x18\x04 \x01(\v2\x14.ermite.MirrorStatusR\x06status\x12\x14\n" + | |
| 1673 | + | "\x05error\x18\x05 \x01(\tR\x05error\"H\n" + | |
| 1668 | 1674 | "\x12SyncMirrorResponse\x122\n" + | |
| 1669 | 1675 | "\aresults\x18\x01 \x03(\v2\x18.ermite.SyncMirrorResultR\aresults*\x9b\x01\n" + | |
| 1670 | 1676 | "\fMirrorSource\x12\x1d\n" + | |
| @@ -28,16 +28,14 @@ const ( | |||||
| 28 | type MirrorSource int32 | 28 | type MirrorSource int32 | ||
| 29 | 29 | ||||
| 30 | const ( | 30 | const ( | ||
| 31 | - | // Unspecified. | 31 | + | // MIRROR_SOURCE_DISABLED: nothing applies; MIRROR_SOURCE_GLOBAL: the global |
| 32 | + | // template; MIRROR_SOURCE_OVERRIDE: a per-repository URL; | |||
| 33 | + | // MIRROR_SOURCE_EXCLUDED: opted out of the global template. | |||
| 32 | MirrorSource_MIRROR_SOURCE_UNSPECIFIED MirrorSource = 0 | 34 | MirrorSource_MIRROR_SOURCE_UNSPECIFIED MirrorSource = 0 | ||
| 33 | - | // Disabled. | 35 | + | MirrorSource_MIRROR_SOURCE_DISABLED MirrorSource = 1 |
| 34 | - | MirrorSource_MIRROR_SOURCE_DISABLED MirrorSource = 1 | 36 | + | MirrorSource_MIRROR_SOURCE_GLOBAL MirrorSource = 2 |
| 35 | - | // Global. | 37 | + | MirrorSource_MIRROR_SOURCE_OVERRIDE MirrorSource = 3 |
| 36 | - | MirrorSource_MIRROR_SOURCE_GLOBAL MirrorSource = 2 | 38 | + | MirrorSource_MIRROR_SOURCE_EXCLUDED MirrorSource = 4 |
| 37 | - | // Override. | |||
| 38 | - | MirrorSource_MIRROR_SOURCE_OVERRIDE MirrorSource = 3 | |||
| 39 | - | // Excluded. | |||
| 40 | - | MirrorSource_MIRROR_SOURCE_EXCLUDED MirrorSource = 4 | |||
| 41 | ) | 39 | ) | ||
| 42 | 40 | ||||
| 43 | // Enum value maps for MirrorSource. | 41 | // Enum value maps for MirrorSource. | ||
| @@ -89,16 +87,13 @@ func (MirrorSource) EnumDescriptor() ([]byte, []int) { | |||||
| 89 | type MirrorState int32 | 87 | type MirrorState int32 | ||
| 90 | 88 | ||||
| 91 | const ( | 89 | const ( | ||
| 92 | - | // Unspecified. | 90 | + | // MIRROR_STATE_OK: last sync succeeded; MIRROR_STATE_FAILING: retrying with |
| 91 | + | // backoff; MIRROR_STATE_PAUSED: stopped until a forced sync or a config change. | |||
| 93 | MirrorState_MIRROR_STATE_UNSPECIFIED MirrorState = 0 | 92 | MirrorState_MIRROR_STATE_UNSPECIFIED MirrorState = 0 | ||
| 94 | - | // Disabled. | 93 | + | MirrorState_MIRROR_STATE_DISABLED MirrorState = 1 |
| 95 | - | MirrorState_MIRROR_STATE_DISABLED MirrorState = 1 | 94 | + | MirrorState_MIRROR_STATE_OK MirrorState = 2 |
| 96 | - | // Ok. | 95 | + | MirrorState_MIRROR_STATE_FAILING MirrorState = 3 |
| 97 | - | MirrorState_MIRROR_STATE_OK MirrorState = 2 | 96 | + | MirrorState_MIRROR_STATE_PAUSED MirrorState = 4 |
| 98 | - | // Failing. | |||
| 99 | - | MirrorState_MIRROR_STATE_FAILING MirrorState = 3 | |||
| 100 | - | // Paused. | |||
| 101 | - | MirrorState_MIRROR_STATE_PAUSED MirrorState = 4 | |||
| 102 | ) | 97 | ) | ||
| 103 | 98 | ||||
| 104 | // Enum value maps for MirrorState. | 99 | // Enum value maps for MirrorState. | ||
| @@ -1465,7 +1460,10 @@ type SyncMirrorResult struct { | |||||
| 1465 | // NoOp says the refs already matched the last successful snapshot. | 1460 | // NoOp says the refs already matched the last successful snapshot. | ||
| 1466 | NoOp bool `protobuf:"varint,3,opt,name=no_op,json=noOp,proto3" json:"no_op,omitempty"` | 1461 | NoOp bool `protobuf:"varint,3,opt,name=no_op,json=noOp,proto3" json:"no_op,omitempty"` | ||
| 1467 | // Status is the current mirror status. | 1462 | // Status is the current mirror status. | ||
| 1468 | - | Status *MirrorStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` | 1463 | + | Status *MirrorStatus `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` |
| 1464 | + | // Error is a human-readable failure of this repository's sync, empty on | |||
| 1465 | + | // success. It never contains the mirror URL. | |||
| 1466 | + | Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` | |||
| 1469 | unknownFields protoimpl.UnknownFields | 1467 | unknownFields protoimpl.UnknownFields | ||
| 1470 | sizeCache protoimpl.SizeCache | 1468 | sizeCache protoimpl.SizeCache | ||
| 1471 | } | 1469 | } | ||
| @@ -1528,6 +1526,13 @@ func (x *SyncMirrorResult) GetStatus() *MirrorStatus { | |||||
| 1528 | return nil | 1526 | return nil | ||
| 1529 | } | 1527 | } | ||
| 1530 | 1528 | ||||
| 1529 | + | func (x *SyncMirrorResult) GetError() string { | |||
| 1530 | + | if x != nil { | |||
| 1531 | + | return x.Error | |||
| 1532 | + | } | |||
| 1533 | + | return "" | |||
| 1534 | + | } | |||
| 1535 | + | ||||
| 1531 | // SyncMirrorResponse holds the result of SyncMirror. | 1536 | // SyncMirrorResponse holds the result of SyncMirror. | ||
| 1532 | type SyncMirrorResponse struct { | 1537 | type SyncMirrorResponse struct { | ||
| 1533 | state protoimpl.MessageState `protogen:"open.v1"` | 1538 | state protoimpl.MessageState `protogen:"open.v1"` | ||
| @@ -1659,12 +1664,13 @@ const file_ermite_mirror_proto_rawDesc = "" + | |||||
| 1659 | "\x11SyncMirrorRequest\x12\x12\n" + | 1664 | "\x11SyncMirrorRequest\x12\x12\n" + | ||
| 1660 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x10\n" + | 1665 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x10\n" + | ||
| 1661 | "\x03all\x18\x02 \x01(\bR\x03all\x12\x14\n" + | 1666 | "\x03all\x18\x02 \x01(\bR\x03all\x12\x14\n" + | ||
| 1662 | - | "\x05force\x18\x03 \x01(\bR\x05force\"\x81\x01\n" + | 1667 | + | "\x05force\x18\x03 \x01(\bR\x05force\"\x97\x01\n" + |
| 1663 | "\x10SyncMirrorResult\x12\x12\n" + | 1668 | "\x10SyncMirrorResult\x12\x12\n" + | ||
| 1664 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x16\n" + | 1669 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12\x16\n" + | ||
| 1665 | "\x06queued\x18\x02 \x01(\bR\x06queued\x12\x13\n" + | 1670 | "\x06queued\x18\x02 \x01(\bR\x06queued\x12\x13\n" + | ||
| 1666 | "\x05no_op\x18\x03 \x01(\bR\x04noOp\x12,\n" + | 1671 | "\x05no_op\x18\x03 \x01(\bR\x04noOp\x12,\n" + | ||
| 1667 | - | "\x06status\x18\x04 \x01(\v2\x14.ermite.MirrorStatusR\x06status\"H\n" + | 1672 | + | "\x06status\x18\x04 \x01(\v2\x14.ermite.MirrorStatusR\x06status\x12\x14\n" + |
| 1673 | + | "\x05error\x18\x05 \x01(\tR\x05error\"H\n" + | |||
| 1668 | "\x12SyncMirrorResponse\x122\n" + | 1674 | "\x12SyncMirrorResponse\x122\n" + | ||
| 1669 | "\aresults\x18\x01 \x03(\v2\x18.ermite.SyncMirrorResultR\aresults*\x9b\x01\n" + | 1675 | "\aresults\x18\x01 \x03(\v2\x18.ermite.SyncMirrorResultR\aresults*\x9b\x01\n" + | ||
| 1670 | "\fMirrorSource\x12\x1d\n" + | 1676 | "\fMirrorSource\x12\x1d\n" + | ||
M gen_test.go +1 -1
| @@ -598,7 +598,7 @@ func TestMirrorWire(t *testing.T) { | |||
| 598 | 598 | for _, in := range []proto.Message{ | |
| 599 | 599 | &ermite.SetMirrorConfigRequest{Enabled: proto.Bool(false), UrlTemplate: proto.String(""), Cron: proto.String(""), AllBranches: proto.Bool(false)}, | |
| 600 | 600 | &ermite.SetRepoMirrorRequest{Repo: "repo", AllBranches: proto.Bool(false)}, | |
| 601 | - | &ermite.Event{Kind: &ermite.Event_MirrorFailed{MirrorFailed: &ermite.MirrorFailed{Repo: "repo", State: ermite.MirrorState_MIRROR_STATE_PAUSED, FailureClass: "diverged", Reason: "remote diverged"}}}, | |
| 601 | + | &ermite.Event{Kind: &ermite.Event_MirrorFailed{MirrorFailed: &ermite.MirrorFailed{Repo: "repo", State: ermite.MirrorState_MIRROR_STATE_PAUSED, FailureClass: "diverged"}}}, | |
| 602 | 602 | &ermite.Event{Kind: &ermite.Event_MirrorRecovered{MirrorRecovered: &ermite.MirrorRecovered{Repo: "repo"}}}, | |
| 603 | 603 | } { | |
| 604 | 604 | b, err := proto.Marshal(in) | |
| @@ -598,7 +598,7 @@ func TestMirrorWire(t *testing.T) { | |||||
| 598 | for _, in := range []proto.Message{ | 598 | for _, in := range []proto.Message{ | ||
| 599 | &ermite.SetMirrorConfigRequest{Enabled: proto.Bool(false), UrlTemplate: proto.String(""), Cron: proto.String(""), AllBranches: proto.Bool(false)}, | 599 | &ermite.SetMirrorConfigRequest{Enabled: proto.Bool(false), UrlTemplate: proto.String(""), Cron: proto.String(""), AllBranches: proto.Bool(false)}, | ||
| 600 | &ermite.SetRepoMirrorRequest{Repo: "repo", AllBranches: proto.Bool(false)}, | 600 | &ermite.SetRepoMirrorRequest{Repo: "repo", AllBranches: proto.Bool(false)}, | ||
| 601 | - | &ermite.Event{Kind: &ermite.Event_MirrorFailed{MirrorFailed: &ermite.MirrorFailed{Repo: "repo", State: ermite.MirrorState_MIRROR_STATE_PAUSED, FailureClass: "diverged", Reason: "remote diverged"}}}, | 601 | + | &ermite.Event{Kind: &ermite.Event_MirrorFailed{MirrorFailed: &ermite.MirrorFailed{Repo: "repo", State: ermite.MirrorState_MIRROR_STATE_PAUSED, FailureClass: "diverged"}}}, |
| 602 | &ermite.Event{Kind: &ermite.Event_MirrorRecovered{MirrorRecovered: &ermite.MirrorRecovered{Repo: "repo"}}}, | 602 | &ermite.Event{Kind: &ermite.Event_MirrorRecovered{MirrorRecovered: &ermite.MirrorRecovered{Repo: "repo"}}}, | ||
| 603 | } { | 603 | } { | ||
| 604 | b, err := proto.Marshal(in) | 604 | b, err := proto.Marshal(in) | ||
M proto/ermite/event.proto +6 -5
| @@ -314,9 +314,9 @@ message JobUpdated { | |||
| 314 | 314 | ||
| 315 | 315 | // MirrorFailed reports the start of a failure incident: a transition from ok | |
| 316 | 316 | // or disabled into failing or paused. It is sent once per incident, not for | |
| 317 | - | // each failed attempt nor for failing to paused. Servers with feature "mirror" deliver it | |
| 318 | - | // on "repo:<name>" and "home", subject to repository visibility. It carries no | |
| 319 | - | // URL or error detail. | |
| 317 | + | // each failed attempt nor for failing to paused. Servers with feature "mirror" | |
| 318 | + | // deliver it on "repo:<name>" and "home", subject to repository visibility. It | |
| 319 | + | // carries no URL, reason or error detail; read the status for those. | |
| 320 | 320 | message MirrorFailed { | |
| 321 | 321 | // Repo is the repository name. | |
| 322 | 322 | string repo = 1; | |
| @@ -324,8 +324,9 @@ message MirrorFailed { | |||
| 324 | 324 | MirrorState state = 2; | |
| 325 | 325 | // FailureClass is the failure category. | |
| 326 | 326 | string failure_class = 3; | |
| 327 | - | // Reason explains the failure without a URL or error detail. | |
| 328 | - | string reason = 4; | |
| 327 | + | ||
| 328 | + | reserved 4; | |
| 329 | + | reserved "reason"; | |
| 329 | 330 | } | |
| 330 | 331 | ||
| 331 | 332 | // MirrorRecovered reports a successful sync after failing or paused. Delivery | |
| @@ -314,9 +314,9 @@ message JobUpdated { | |||||
| 314 | 314 | ||||
| 315 | // MirrorFailed reports the start of a failure incident: a transition from ok | 315 | // MirrorFailed reports the start of a failure incident: a transition from ok | ||
| 316 | // or disabled into failing or paused. It is sent once per incident, not for | 316 | // or disabled into failing or paused. It is sent once per incident, not for | ||
| 317 | - | // each failed attempt nor for failing to paused. Servers with feature "mirror" deliver it | 317 | + | // each failed attempt nor for failing to paused. Servers with feature "mirror" |
| 318 | - | // on "repo:<name>" and "home", subject to repository visibility. It carries no | 318 | + | // deliver it on "repo:<name>" and "home", subject to repository visibility. It |
| 319 | - | // URL or error detail. | 319 | + | // carries no URL, reason or error detail; read the status for those. |
| 320 | message MirrorFailed { | 320 | message MirrorFailed { | ||
| 321 | // Repo is the repository name. | 321 | // Repo is the repository name. | ||
| 322 | string repo = 1; | 322 | string repo = 1; | ||
| @@ -324,8 +324,9 @@ message MirrorFailed { | |||||
| 324 | MirrorState state = 2; | 324 | MirrorState state = 2; | ||
| 325 | // FailureClass is the failure category. | 325 | // FailureClass is the failure category. | ||
| 326 | string failure_class = 3; | 326 | string failure_class = 3; | ||
| 327 | - | // Reason explains the failure without a URL or error detail. | 327 | + | |
| 328 | - | string reason = 4; | 328 | + | reserved 4; |
| 329 | + | reserved "reason"; | |||
| 329 | } | 330 | } | ||
| 330 | 331 | ||||
| 331 | // MirrorRecovered reports a successful sync after failing or paused. Delivery | 332 | // MirrorRecovered reports a successful sync after failing or paused. Delivery | ||
M proto/ermite/mirror.proto +15 -22
| @@ -6,18 +6,13 @@ package ermite; | |||
| 6 | 6 | ||
| 7 | 7 | import "google/protobuf/timestamp.proto"; | |
| 8 | 8 | ||
| 9 | - | // MirrorService configures the push mirrors of the server. Global settings | |
| 10 | - | // and key | |
| 11 | - | // rotation need the admin token or a token with every scope and no repository | |
| 12 | - | // or | |
| 13 | - | // branch limits; per-repository settings and SyncMirror need repo:admin on | |
| 14 | - | // the | |
| 15 | - | // repository; status needs read access. GetMirrorKey needs a non-anonymous | |
| 16 | - | // caller. | |
| 17 | - | // ListMirrorStatus and SyncMirror with All need owner rights. No new token | |
| 18 | - | // scope | |
| 19 | - | // is required. Servers implementing this service list "mirror" in | |
| 20 | - | // GetVersionResponse.features. | |
| 9 | + | // MirrorService configures the push mirrors of the server. Global settings and | |
| 10 | + | // key rotation need the admin token or a token with every scope and no | |
| 11 | + | // repository or branch limits; per-repository settings and SyncMirror need | |
| 12 | + | // repo:admin on the repository; status needs read access. GetMirrorKey needs a | |
| 13 | + | // non-anonymous caller. ListMirrorStatus and SyncMirror with All need owner | |
| 14 | + | // rights. No new token scope is required. Servers implementing this service | |
| 15 | + | // list "mirror" in GetVersionResponse.features. | |
| 21 | 16 | service MirrorService { | |
| 22 | 17 | // GetMirrorKey returns the public mirror key, generating it on first use. | |
| 23 | 18 | // Needs a non-anonymous caller. Fails with failed_precondition without | |
| @@ -127,15 +122,13 @@ message SetMirrorConfigResponse { | |||
| 127 | 122 | ||
| 128 | 123 | // MirrorSource says which configuration applies to a repository. | |
| 129 | 124 | enum MirrorSource { | |
| 130 | - | // Unspecified. | |
| 125 | + | // MIRROR_SOURCE_DISABLED: nothing applies; MIRROR_SOURCE_GLOBAL: the global | |
| 126 | + | // template; MIRROR_SOURCE_OVERRIDE: a per-repository URL; | |
| 127 | + | // MIRROR_SOURCE_EXCLUDED: opted out of the global template. | |
| 131 | 128 | MIRROR_SOURCE_UNSPECIFIED = 0; | |
| 132 | - | // Disabled. | |
| 133 | 129 | MIRROR_SOURCE_DISABLED = 1; | |
| 134 | - | // Global. | |
| 135 | 130 | MIRROR_SOURCE_GLOBAL = 2; | |
| 136 | - | // Override. | |
| 137 | 131 | MIRROR_SOURCE_OVERRIDE = 3; | |
| 138 | - | // Excluded. | |
| 139 | 132 | MIRROR_SOURCE_EXCLUDED = 4; | |
| 140 | 133 | } | |
| 141 | 134 | ||
| @@ -203,15 +196,12 @@ message SetRepoMirrorExcludedResponse { | |||
| 203 | 196 | ||
| 204 | 197 | // MirrorState is the current state of a push mirror. | |
| 205 | 198 | enum MirrorState { | |
| 206 | - | // Unspecified. | |
| 199 | + | // MIRROR_STATE_OK: last sync succeeded; MIRROR_STATE_FAILING: retrying with | |
| 200 | + | // backoff; MIRROR_STATE_PAUSED: stopped until a forced sync or a config change. | |
| 207 | 201 | MIRROR_STATE_UNSPECIFIED = 0; | |
| 208 | - | // Disabled. | |
| 209 | 202 | MIRROR_STATE_DISABLED = 1; | |
| 210 | - | // Ok. | |
| 211 | 203 | MIRROR_STATE_OK = 2; | |
| 212 | - | // Failing. | |
| 213 | 204 | MIRROR_STATE_FAILING = 3; | |
| 214 | - | // Paused. | |
| 215 | 205 | MIRROR_STATE_PAUSED = 4; | |
| 216 | 206 | } | |
| 217 | 207 | ||
| @@ -287,6 +277,9 @@ message SyncMirrorResult { | |||
| 287 | 277 | bool no_op = 3; | |
| 288 | 278 | // Status is the current mirror status. | |
| 289 | 279 | MirrorStatus status = 4; | |
| 280 | + | // Error is a human-readable failure of this repository's sync, empty on | |
| 281 | + | // success. It never contains the mirror URL. | |
| 282 | + | string error = 5; | |
| 290 | 283 | } | |
| 291 | 284 | ||
| 292 | 285 | // SyncMirrorResponse holds the result of SyncMirror. | |
| @@ -6,18 +6,13 @@ package ermite; | |||||
| 6 | 6 | ||||
| 7 | import "google/protobuf/timestamp.proto"; | 7 | import "google/protobuf/timestamp.proto"; | ||
| 8 | 8 | ||||
| 9 | - | // MirrorService configures the push mirrors of the server. Global settings | 9 | + | // MirrorService configures the push mirrors of the server. Global settings and |
| 10 | - | // and key | 10 | + | // key rotation need the admin token or a token with every scope and no |
| 11 | - | // rotation need the admin token or a token with every scope and no repository | 11 | + | // repository or branch limits; per-repository settings and SyncMirror need |
| 12 | - | // or | 12 | + | // repo:admin on the repository; status needs read access. GetMirrorKey needs a |
| 13 | - | // branch limits; per-repository settings and SyncMirror need repo:admin on | 13 | + | // non-anonymous caller. ListMirrorStatus and SyncMirror with All need owner |
| 14 | - | // the | 14 | + | // rights. No new token scope is required. Servers implementing this service |
| 15 | - | // repository; status needs read access. GetMirrorKey needs a non-anonymous | 15 | + | // list "mirror" in GetVersionResponse.features. |
| 16 | - | // caller. | |||
| 17 | - | // ListMirrorStatus and SyncMirror with All need owner rights. No new token | |||
| 18 | - | // scope | |||
| 19 | - | // is required. Servers implementing this service list "mirror" in | |||
| 20 | - | // GetVersionResponse.features. | |||
| 21 | service MirrorService { | 16 | service MirrorService { | ||
| 22 | // GetMirrorKey returns the public mirror key, generating it on first use. | 17 | // GetMirrorKey returns the public mirror key, generating it on first use. | ||
| 23 | // Needs a non-anonymous caller. Fails with failed_precondition without | 18 | // Needs a non-anonymous caller. Fails with failed_precondition without | ||
| @@ -127,15 +122,13 @@ message SetMirrorConfigResponse { | |||||
| 127 | 122 | ||||
| 128 | // MirrorSource says which configuration applies to a repository. | 123 | // MirrorSource says which configuration applies to a repository. | ||
| 129 | enum MirrorSource { | 124 | enum MirrorSource { | ||
| 130 | - | // Unspecified. | 125 | + | // MIRROR_SOURCE_DISABLED: nothing applies; MIRROR_SOURCE_GLOBAL: the global |
| 126 | + | // template; MIRROR_SOURCE_OVERRIDE: a per-repository URL; | |||
| 127 | + | // MIRROR_SOURCE_EXCLUDED: opted out of the global template. | |||
| 131 | MIRROR_SOURCE_UNSPECIFIED = 0; | 128 | MIRROR_SOURCE_UNSPECIFIED = 0; | ||
| 132 | - | // Disabled. | |||
| 133 | MIRROR_SOURCE_DISABLED = 1; | 129 | MIRROR_SOURCE_DISABLED = 1; | ||
| 134 | - | // Global. | |||
| 135 | MIRROR_SOURCE_GLOBAL = 2; | 130 | MIRROR_SOURCE_GLOBAL = 2; | ||
| 136 | - | // Override. | |||
| 137 | MIRROR_SOURCE_OVERRIDE = 3; | 131 | MIRROR_SOURCE_OVERRIDE = 3; | ||
| 138 | - | // Excluded. | |||
| 139 | MIRROR_SOURCE_EXCLUDED = 4; | 132 | MIRROR_SOURCE_EXCLUDED = 4; | ||
| 140 | } | 133 | } | ||
| 141 | 134 | ||||
| @@ -203,15 +196,12 @@ message SetRepoMirrorExcludedResponse { | |||||
| 203 | 196 | ||||
| 204 | // MirrorState is the current state of a push mirror. | 197 | // MirrorState is the current state of a push mirror. | ||
| 205 | enum MirrorState { | 198 | enum MirrorState { | ||
| 206 | - | // Unspecified. | 199 | + | // MIRROR_STATE_OK: last sync succeeded; MIRROR_STATE_FAILING: retrying with |
| 200 | + | // backoff; MIRROR_STATE_PAUSED: stopped until a forced sync or a config change. | |||
| 207 | MIRROR_STATE_UNSPECIFIED = 0; | 201 | MIRROR_STATE_UNSPECIFIED = 0; | ||
| 208 | - | // Disabled. | |||
| 209 | MIRROR_STATE_DISABLED = 1; | 202 | MIRROR_STATE_DISABLED = 1; | ||
| 210 | - | // Ok. | |||
| 211 | MIRROR_STATE_OK = 2; | 203 | MIRROR_STATE_OK = 2; | ||
| 212 | - | // Failing. | |||
| 213 | MIRROR_STATE_FAILING = 3; | 204 | MIRROR_STATE_FAILING = 3; | ||
| 214 | - | // Paused. | |||
| 215 | MIRROR_STATE_PAUSED = 4; | 205 | MIRROR_STATE_PAUSED = 4; | ||
| 216 | } | 206 | } | ||
| 217 | 207 | ||||
| @@ -287,6 +277,9 @@ message SyncMirrorResult { | |||||
| 287 | bool no_op = 3; | 277 | bool no_op = 3; | ||
| 288 | // Status is the current mirror status. | 278 | // Status is the current mirror status. | ||
| 289 | MirrorStatus status = 4; | 279 | MirrorStatus status = 4; | ||
| 280 | + | // Error is a human-readable failure of this repository's sync, empty on | |||
| 281 | + | // success. It never contains the mirror URL. | |||
| 282 | + | string error = 5; | |||
| 290 | } | 283 | } | ||
| 291 | 284 | ||||
| 292 | // SyncMirrorResponse holds the result of SyncMirror. | 285 | // SyncMirrorResponse holds the result of SyncMirror. | ||