go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/prjmanager/prjpb/storage.proto (about)

     1  // Copyright 2021 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  syntax = "proto3";
    16  
    17  package cv.internal.prjmanager.prjpb;
    18  
    19  option go_package = "go.chromium.org/luci/cv/internal/prjmanager/prjpb;prjpb";
    20  
    21  import "google/protobuf/timestamp.proto";
    22  
    23  import "go.chromium.org/luci/cv/internal/changelist/storage.proto";
    24  import "go.chromium.org/luci/cv/internal/gerrit/storage.proto";
    25  import "go.chromium.org/luci/cv/internal/run/storage.proto";
    26  
    27  // This file keeps serializable state of PM (Project Manager).
    28  //
    29  // For clarity in Project Manager's code itself, a few message names start with
    30  // "P", e.g. "PCL" instead of "CL".
    31  //
    32  // It's mutated in ../impl/state package and ultimately stored as Project's
    33  // datastore entity. Logically, this proto is part of the impl of the
    34  // ../impl/state, but it's a separate package to resolve import cycle
    35  // because ../impl/state is importing prjmanager/ package.
    36  
    37  // PState is the PM state of a specific LUCI project.
    38  //
    39  // Semantically, it's a collection of CLs somehow grouped into components (see
    40  // Component message below), each of which may have several active (a.k.a.
    41  // Incomplete) Runs valid at a specific project's config version.
    42  //
    43  // Most CLs are watched by the LUCI project, but to assist with error reporting,
    44  // it also tracks unwatched CLs if they are dependencies of some actually
    45  // watched CLs.
    46  message PState {
    47  
    48    // Name of LUCI project.
    49    string luci_project = 1;
    50    // Status of the Project.
    51    Status status = 2;
    52    // Config hash pins specific project config version.
    53    string config_hash = 3;
    54    // Config group names intern the names referenced in PCL entities to reduce
    55    // memory and at-rest footprint.
    56    //
    57    // See also https://en.wikipedia.org/wiki/String_interning.
    58    repeated string config_group_names = 4;
    59  
    60    // PCLs are currently tracked CLs.
    61    //
    62    // Includes deps which are of not yet known kind (because CL doesn't yet have
    63    // a snapshot) or unwatched.
    64    //
    65    // Sorted by CL ID.
    66    repeated PCL pcls = 11;
    67    // Components are a partition of CLs in the list above.
    68    //
    69    // An active CL (watched or used to be watched and still member of a Run) may
    70    // belong to at most 1 component, while unwatched dep may be referenced by
    71    // several.
    72    repeated Component components = 12;
    73    // PurgingCLs are CLs currently being purged.
    74    //
    75    // They are tracked in PState to avoid creating Runs with such CLs.
    76    //
    77    // A CL being purged does not necessarily have a corresponding PCL.
    78    // A PurgingCL is kept in PState until purging process stops, regardless of
    79    // whether purging was successful or failed.
    80    //
    81    // See more in PurgingCL doc.
    82    //
    83    // Sorted by CL ID.
    84    repeated PurgingCL purging_cls = 13;
    85  
    86    // TriggeringCLDeps are the CLs of which deps are being triggered.
    87    //
    88    // They are tracked in PState to avoid creating duplicate triggering tasks.
    89    //
    90    // Sorted by the origin ID.
    91    repeated TriggeringCLDeps triggering_cl_deps = 15;
    92  
    93    // If true, components partition must be redone as soon as possible.
    94    bool repartition_required = 21;
    95    // PRuns which can't yet be added to any component but should be. Sorted by
    96    // Run ID.
    97    //
    98    // In response to OnRunCreated event, PM may append to this list new Runs if
    99    // either:
   100    //   * not all Run's CLs are already known to PM;
   101    //   * Run's CLs are currently partitioned into different components.
   102    //
   103    // Thus,
   104    //   * CLs referenced by these PRuns may not be tracked;
   105    //   * If this field is not empty, re-partioning may be required.
   106    repeated PRun created_pruns = 22;
   107    // If set, establishes when components should be re-evaluated.
   108    google.protobuf.Timestamp next_eval_time = 23;
   109  }
   110  
   111  enum Status {
   112    STATUS_UNSPECIFIED = 0;
   113    STARTED = 1;
   114    STOPPING = 2;
   115    STOPPED = 3;
   116  }
   117  
   118  // LogReason records why a change to the project state was logged.
   119  //
   120  // See ProjectLog entity.
   121  enum LogReason {
   122    LOG_REASON_UNSPECIFIED = 0;
   123  
   124    // Due to passage of time or number of versions.
   125    FYI_PERIODIC = 1;
   126    STATUS_CHANGED = 2;
   127    CONFIG_CHANGED = 3;
   128    // On-demand save for debugging reasons, e.g. on caught panic.
   129    DEBUG = 4;
   130  }
   131  
   132  message LogReasons {
   133    repeated LogReason reasons = 1;
   134  }
   135  
   136  // PCL is a tracked CL.
   137  message PCL {
   138    // next tag: 18
   139  
   140    reserved 12; // Trigger (single), replaced by Triggers.
   141    reserved 14;
   142  
   143    int64 clid = 1;
   144    int64 eversion = 2;
   145  
   146    enum Status {
   147      option allow_alias = true;
   148      PCL_STATUS_UNSPECIFIED = 0;
   149      // OK means CL metadata below is correct and CL is watched by this project.
   150      //
   151      // Value 0 is chosen such that it's not serialized, since this is the most
   152      // common state.
   153      OK = 0;
   154      // UNKNOWN means Datastore CL entity doesn't have the info yet.
   155      UNKNOWN = 1;
   156      // UNWATCHED means CL isn't watched by this LUCI project.
   157      UNWATCHED = 2;
   158      // DELETED means CL's Datastore entity got deleted.
   159      //
   160      // This is used to temporary mark a PCL before deleting it entirely from
   161      // PState to avoid dangling references from components.
   162      DELETED = 3;
   163    }
   164    Status status = 3;
   165  
   166    // Indexes in PState.config_group_names identifying ConfigGroup which watches
   167    // this CL.
   168    //
   169    // Normally, contains exactly 1 index.
   170    // May have > 1 index, which means 2+ non-fallback config groups watch this
   171    // CL, which is not allowed and will be signalled to CV users.
   172    // TODO(tandrii): move >1 index case to be tracked via `errors` field.
   173    repeated int32 config_group_indexes = 4;
   174  
   175    // Deps refers to CLs in PState.PCLs which are dependencies of the PCL.
   176    repeated changelist.Dep deps = 11;
   177  
   178    // Triggers are the triggers currently active on the CL.
   179    //
   180    // Note that due to NewPatchsetRuns, CLs can be associated with more than one
   181    // Run at any given time, for this reason, it is required that a PCL be able
   182    // to track multiple triggers.
   183    //
   184    // It may be empty if CL is not triggered but nevertheless tracked as either:
   185    //  * a dependency of another CL.
   186    //  * previously triggered member of an incomplete Run, which is probably
   187    //    being finalized right now by its Run Manager.
   188    //
   189    // Doesn't store email nor Gerrit account ID.
   190    cv.internal.run.Triggers triggers = 16;
   191  
   192    // Submitted means CV isn't going to work on a CL, but CL is still tracked as
   193    // a dep of another CL or as a member of an incomplete Run (though the other
   194    // Run will probably finish soon).
   195    bool submitted = 13;
   196  
   197    // Deprecated in favor of purge_reasons.
   198    repeated cv.internal.changelist.CLError errors = 15 [deprecated=true];
   199  
   200    // If set, describes problems that require that some or all of the PCL's
   201    // triggers be purged.
   202    repeated PurgeReason purge_reasons = 17;
   203  
   204    // Outdated if set means Snapshot must be considered likely outdated due to
   205    // recent CV mutations.
   206    //
   207    // In particular, Project Manager does not act on the CLs with .Outdated set.
   208    cv.internal.changelist.Snapshot.Outdated outdated = 18;
   209  }
   210  
   211  // PRun is an incomplete Run on which CV is currently working.
   212  //
   213  // It is referenced by at most 1 component.
   214  message PRun {
   215    // CV's Run ID.
   216    string id = 1;
   217  
   218    // IDs of CLs involved. Sorted.
   219    //
   220    // Actual Run may orders its CLs in a different way.
   221    repeated int64 clids = 2;
   222  
   223    // The mode of the Run referenced by this message.
   224    //
   225    // It uses the string value of run.Mode.
   226    string mode = 3;
   227  	// ID of the root CL that triggers this Run in the combined mode.
   228  	//
   229  	// It is the same as `run.root_cl`.
   230    int64 root_clid = 4;
   231  }
   232  
   233  // Component is a set of CLs related to each other.
   234  message Component {
   235    // CL IDs of the tracked CLs in this component. Sorted.
   236    //
   237    // Each referenced CL must be in PState.PCLs list.
   238    // Each referenced CL may have deps not in this list if they are either
   239    // PCL.Status.UNKNOWN or PCL.Status.UNWATCHED.
   240    //
   241    // A referenced CL is normally watched by this LUCI project. In rare cases,
   242    // referenced CL is no longer watched by this LUCI project but is still kept
   243    // in a component because the CL is still a member of an incomplete Run in
   244    // this component. In this case, the CL's deps are no longer tracked.
   245    repeated int64 clids = 1;
   246  
   247    // Decision time is the earliest time when this component should be
   248    // re-evaluated.
   249    //
   250    // Can be set to far future meaning no need for re-evaluation without an
   251    // external event (e.g., CLUpdated or RunFinished).
   252    google.protobuf.Timestamp decision_time = 2;
   253  
   254    // Incomplete Runs working on CLs from this component.
   255    //
   256    // Sorted by Run's ID.
   257    repeated PRun pruns = 3;
   258  
   259    // If true, this component must be triaged as soon as possible.
   260    bool triage_required = 11;
   261  }
   262  
   263  // PurgingCL represents purging of a CL due to some problem.
   264  //
   265  // The purging process is initiated during PM state mutation while atomically
   266  // adding a TQ task to perform the actual purge.
   267  //
   268  // Purging itself constitutes removing whatever triggered CV on a CL as well as
   269  // posting the reason for purging to the user.
   270  //
   271  // Individual CLs are purged independently, even if CLs are related.
   272  //
   273  // Trying to purge multiple triggers of the same type on the same CL will
   274  // result in only purging one of them. This is not possible today, but may have
   275  // an unexpected effect on future features.
   276  //
   277  // Upon TQ task completion, the task handler notifies PM back via an
   278  // PurgeCompleted event. For fail-safe reasons, there is a deadline to
   279  // perform the purge. PM keeps the PurgingCL in PState until either deadline is
   280  // reached OR PurgeCompleted event is received.
   281  message PurgingCL {
   282    // CL ID which is being purged.
   283    int64 clid = 1;
   284    // Operation ID is a unique within a project identifier of a purge operation
   285    // to use in PurgeCompleted events.
   286    string operation_id = 2;
   287    // Deadline is obeyed by the purging TQ task.
   288    //
   289    // TQ task SHOULD not modify a CL (e.g. via Gerrit RPCs) beyond this point.
   290    // This is merely best effort, as an RPC to external system initiated before
   291    // this deadline may still complete after it.
   292    //
   293    // If PM doesn't receive PurgeCompleted event before this deadline + some grace
   294    // period, PM will consider purge operation expired and it'll be removed from
   295    // PState.
   296    google.protobuf.Timestamp deadline = 3;
   297    // What trigger(s) are being purged.
   298    oneof apply_to {
   299      cv.internal.run.Triggers triggers = 4;
   300      bool all_active_triggers = 5;
   301    }
   302    message Notification {
   303      // Whom value(s) to set in Notify of the SetReview request.
   304      //
   305      // If omitted, no one will receive a notification.
   306      repeated gerrit.Whom notify = 1;
   307      // Whom value(s) to set in AddToAttentionSet of the SetReview request.
   308      //
   309      // If omitted, no one will be added into the attention set.
   310      repeated gerrit.Whom attention = 2;
   311    }
   312    // If specified, the Gerrit request will be sent with the notify and
   313    // attention.
   314    Notification notification = 6;
   315  }
   316  
   317  // TriggeringCLDeps propagates the trigger to the deps of a given CL.
   318  message TriggeringCLDeps {
   319    // Origin CL of which dep CLs are to propagate the trigger to.
   320    int64 origin_clid = 1;
   321    // Dep CLs to propagate the trigger to.
   322    repeated int64 dep_clids = 2;
   323    // Operation ID uniquely identifies this op within the project.
   324    string operation_id = 3;
   325    // Deadline is obeyed by the TQ task handler.
   326    //
   327    // TQ task SHOULD NOT modify a CL (e.g., via Gerrit RPCs) beyond this point.
   328    // If PM doesn't receive TriggerCLDepsCompleted event before
   329    // this deadline + grace period, PM will consider the task expired and
   330    // the task will be removed from PState, so that the deps will be re-triaged
   331    // and PM may schedule another TQ task for the triggering operation
   332    // for the CL.
   333    google.protobuf.Timestamp deadline = 4;
   334    // Trigger to propagate.
   335    cv.internal.run.Trigger trigger = 5;
   336    // Name of the config group watching the origin CL.
   337    string config_group_name = 6;
   338  }
   339  
   340  // PurgeReason represent a list of errors with the CL that would require that
   341  // the given trigger (or the whole CL if no trigger is given) be purged.
   342  //
   343  // Trying to purge multiple triggers of the same type on the same CL will
   344  // result in only purging one of them. This is not possible today, but may have
   345  // an unexpected effect on future features.
   346  message PurgeReason {
   347    // ClErrors are a list of errors associated with Trigger below, or with the
   348    // a whole CL if Trigger is not given.
   349    cv.internal.changelist.CLError cl_error = 1;
   350  
   351    // What trigger(s) the error above applies to.
   352    oneof apply_to {
   353      cv.internal.run.Triggers triggers = 2;
   354      bool all_active_triggers = 3;
   355    }
   356  }