| // Copyright 2021 The LUCI Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| syntax = "proto3"; |
| |
| package cv.internal.prjmanager.prjpb; |
| |
| option go_package = "go.chromium.org/luci/cv/internal/prjmanager/prjpb;prjpb"; |
| |
| import "google/protobuf/timestamp.proto"; |
| |
| import "go.chromium.org/luci/cv/internal/changelist/storage.proto"; |
| import "go.chromium.org/luci/cv/internal/run/storage.proto"; |
| |
| |
| // This file keeps serializable state of PM (Project Manager). |
| // |
| // For clarity in Project Manager's code itself, a few message names start with |
| // "P", e.g. "PCL" instead of "CL". |
| // |
| // It's mutated in ../impl/state package and ultimately stored as Project's |
| // datastore entity. Logically, this proto is part of the impl of the |
| // ../impl/state, but it's a separate package to resolve import cycle |
| // because ../impl/state is importing prjmanager/ package. |
| |
| // PState is the PM state of a specific LUCI project. |
| // |
| // Semantically, it's a collection of CLs somehow grouped into components (see |
| // Component message below), each of which may have several active (a.k.a. |
| // Incomplete) Runs valid at a specific project's config version. |
| // |
| // Most CLs are watched by the LUCI project, but to assist with error reporting, |
| // it also tracks unwatched CLs if they are dependencies of some actually |
| // watched CLs. |
| message PState { |
| |
| // Name of LUCI project. |
| string luci_project = 1; |
| // Status of the Project. |
| Status status = 2; |
| // Config hash pins specific project config version. |
| string config_hash = 3; |
| // Config group names intern the names referenced in PCL entities to reduce |
| // memory and at-rest footprint. |
| // |
| // See also https://en.wikipedia.org/wiki/String_interning. |
| repeated string config_group_names = 4; |
| |
| // PCLs are currently tracked CLs. |
| // |
| // Includes deps which are of not yet known kind (because CL doesn't yet have |
| // a snapshot) or unwatched. |
| // |
| // Sorted by CL ID. |
| repeated PCL pcls = 11; |
| // Components are a partition of CLs in the list above. |
| // |
| // An active CL (watched or used to be watched and still member of a Run) may |
| // belong to at most 1 component, while unwatched dep may be referenced by |
| // several. |
| repeated Component components = 12; |
| // PurgingCLs are CLs currently being purged. |
| // |
| // They are tracked in PState to avoid creating Runs with such CLs. |
| // |
| // A CL being purged does not necessarily have a corresponding PCL. |
| // A PurgingCL is kept in PState until purging process stops, regardless of |
| // whether purging was successful or failed. |
| // |
| // See more in PurgingCL doc. |
| // |
| // Sorted by CL ID. |
| repeated PurgingCL purging_cls = 13; |
| |
| // If true, components partition must be redone as soon as possible. |
| bool repartition_required = 21; |
| // PRuns which can't yet be added to any component but should be. Sorted by |
| // Run ID. |
| // |
| // In response to OnRunCreated event, PM may append to this list new Runs if |
| // either: |
| // * not all Run's CLs are already known to PM; |
| // * Run's CLs are currently partitioned into different components. |
| // |
| // Thus, |
| // * CLs referenced by these PRuns may not be tracked; |
| // * If this field is not empty, re-partioning may be required. |
| repeated PRun created_pruns = 22; |
| // If set, establishes when components should be re-evaluated. |
| google.protobuf.Timestamp next_eval_time = 23; |
| } |
| |
| enum Status { |
| STATUS_UNSPECIFIED = 0; |
| STARTED = 1; |
| STOPPING = 2; |
| STOPPED = 3; |
| } |
| |
| // LogReason records why a change to the project state was logged. |
| // |
| // See ProjectLog entity. |
| enum LogReason { |
| LOG_REASON_UNSPECIFIED = 0; |
| |
| // Due to passage of time or number of versions. |
| FYI_PERIODIC = 1; |
| STATUS_CHANGED = 2; |
| CONFIG_CHANGED = 3; |
| // On-demand save for debugging reasons, e.g. on caught panic. |
| DEBUG = 4; |
| } |
| |
| message LogReasons { |
| repeated LogReason reasons = 1; |
| } |
| |
| // PCL is a tracked CL. |
| message PCL { |
| // next tag: 18 |
| |
| reserved 12; // Trigger (single), replaced by Triggers. |
| reserved 14; |
| |
| int64 clid = 1; |
| int64 eversion = 2; |
| |
| enum Status { |
| option allow_alias = true; |
| PCL_STATUS_UNSPECIFIED = 0; |
| // OK means CL metadata below is correct and CL is watched by this project. |
| // |
| // Value 0 is chosen such that it's not serialized, since this is the most |
| // common state. |
| OK = 0; |
| // UNKNOWN means Datastore CL entity doesn't have the info yet. |
| UNKNOWN = 1; |
| // UNWATCHED means CL isn't watched by this LUCI project. |
| UNWATCHED = 2; |
| // DELETED means CL's Datastore entity got deleted. |
| // |
| // This is used to temporary mark a PCL before deleting it entirely from |
| // PState to avoid dangling references from components. |
| DELETED = 3; |
| } |
| Status status = 3; |
| |
| // Indexes in PState.config_group_names identifying ConfigGroup which watches |
| // this CL. |
| // |
| // Normally, contains exactly 1 index. |
| // May have > 1 index, which means 2+ non-fallback config groups watch this |
| // CL, which is not allowed and will be signalled to CV users. |
| // TODO(tandrii): move >1 index case to be tracked via `errors` field. |
| repeated int32 config_group_indexes = 4; |
| |
| // Deps refers to CLs in PState.PCLs which are dependencies of the PCL. |
| repeated changelist.Dep deps = 11; |
| |
| // Triggers are the triggers currently active on the CL. |
| // |
| // Note that due to NewPatchsetRuns, CLs can be associated with more than one |
| // Run at any given time, for this reason, it is required that a PCL be able |
| // to track multiple triggers. |
| // |
| // It may be empty if CL is not triggered but nevertheless tracked as either: |
| // * a dependency of another CL. |
| // * previously triggered member of an incomplete Run, which is probably |
| // being finalized right now by its Run Manager. |
| // |
| // Doesn't store email nor Gerrit account ID. |
| cv.internal.run.Triggers triggers = 16; |
| |
| // Submitted means CV isn't going to work on a CL, but CL is still tracked as |
| // a dep of another CL or as a member of an incomplete Run (though the other |
| // Run will probably finish soon). |
| bool submitted = 13; |
| |
| // Deprecated in favor of purge_reasons. |
| repeated cv.internal.changelist.CLError errors = 15 [deprecated=true]; |
| |
| // If set, describes problems that require that some or all of the PCL's |
| // triggers be purged. |
| repeated PurgeReason purge_reasons = 17; |
| } |
| |
| // PRun is an incomplete Run on which CV is currently working. |
| // |
| // It is referenced by at most 1 component. |
| message PRun { |
| // CV's Run ID. |
| string id = 1; |
| |
| // IDs of CLs involved. Sorted. |
| // |
| // Actual Run may orders its CLs in a different way. |
| repeated int64 clids = 2; |
| |
| // The mode of the Run referenced by this message. |
| // |
| // It uses the string value of run.Mode. |
| string mode = 3; |
| } |
| |
| // Component is a set of CLs related to each other. |
| message Component { |
| // CL IDs of the tracked CLs in this component. Sorted. |
| // |
| // Each referenced CL must be in PState.PCLs list. |
| // Each referenced CL may have deps not in this list if they are either |
| // PCL.Status.UNKNOWN or PCL.Status.UNWATCHED. |
| // |
| // A referenced CL is normally watched by this LUCI project. In rare cases, |
| // referenced CL is no longer watched by this LUCI project but is still kept |
| // in a component because the CL is still a member of an incomplete Run in |
| // this component. In this case, the CL's deps are no longer tracked. |
| repeated int64 clids = 1; |
| |
| // Decision time is the earliest time when this component should be |
| // re-evaluated. |
| // |
| // Can be set to far future meaning no need for re-evaluation without an |
| // external event (e.g., CLUpdated or RunFinished). |
| google.protobuf.Timestamp decision_time = 2; |
| |
| // Incomplete Runs working on CLs from this component. |
| // |
| // Sorted by Run's ID. |
| repeated PRun pruns = 3; |
| |
| // If true, this component must be triaged as soon as possible. |
| bool triage_required = 11; |
| } |
| |
| // PurgingCL represents purging of a CL due to some problem. |
| // |
| // The purging process is initiated during PM state mutation while atomically |
| // adding a TQ task to perform the actual purge. |
| // |
| // Purging itself constitutes removing whatever triggered CV on a CL as well as |
| // posting the reason for purging to the user. |
| // |
| // Individual CLs are purged independently, even if CLs are related. |
| // |
| // Trying to purge multiple triggers of the same type on the same CL will |
| // result in only purging one of them. This is not possible today, but may have |
| // an unexpected effect on future features. |
| // |
| // Upon TQ task completion, the task handler notifies PM back via an |
| // PurgeCompleted event. For fail-safe reasons, there is a deadline to |
| // perform the purge. PM keeps the PurgingCL in PState until either deadline is |
| // reached OR PurgeCompleted event is received. |
| message PurgingCL { |
| // CL ID which is being purged. |
| int64 clid = 1; |
| // Operation ID is a unique within a project identifier of a purge operation |
| // to use in PurgeCompleted events. |
| string operation_id = 2; |
| // Deadline is obeyed by the purging TQ task. |
| // |
| // TQ task SHOULD not modify a CL (e.g. via Gerrit RPCs) beyond this point. |
| // This is merely best effort, as an RPC to external system initiated before |
| // this deadline may still complete after it. |
| // |
| // If PM doesn't receive PurgeCompleted event before this deadline + some grace |
| // period, PM will consider purge operation expired and it'll be removed from |
| // PState. |
| google.protobuf.Timestamp deadline = 3; |
| // What trigger(s) are being purged. |
| oneof apply_to { |
| cv.internal.run.Triggers triggers = 4; |
| bool all_active_triggers = 5; |
| } |
| } |
| |
| // PurgeReason represent a list of errors with the CL that would require that |
| // the given trigger (or the whole CL if no trigger is given) be purged. |
| // |
| // Trying to purge multiple triggers of the same type on the same CL will |
| // result in only purging one of them. This is not possible today, but may have |
| // an unexpected effect on future features. |
| message PurgeReason { |
| // ClErrors are a list of errors associated with Trigger below, or with the |
| // a whole CL if Trigger is not given. |
| cv.internal.changelist.CLError cl_error = 1; |
| |
| // What trigger(s) the error above applies to. |
| oneof apply_to { |
| cv.internal.run.Triggers triggers = 2; |
| bool all_active_triggers = 3; |
| } |
| } |