Update API descriptions and messages to be consistent

- Update v1beta2 API descriptions and reconciling messages to be
  consistent.
- Replace 'download' with 'fetch'. Since the status condition for
  download failure is called FetchFailed, using the term 'fetch' makes
  the messaging more consistent.
- Replace `BucketOperationSucceed` with `BucketOperationSucceeded` and
  generate api docs.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
This commit is contained in:
Sunny 2022-02-09 14:19:54 +05:30 committed by Hidde Beydals
parent d997876b07
commit 45df2d76c8
16 changed files with 113 additions and 53 deletions

View File

@ -23,13 +23,17 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
// Artifact represents the output of a source synchronisation. // Artifact represents the output of a Source synchronisation.
type Artifact struct { type Artifact struct {
// Path is the relative file path of this artifact. // Path is the relative file path of this Artifact.
// It can be used to locate the Artifact file in the root of the Artifact
// storage on the local file system of the controller managing the Source.
// +required // +required
Path string `json:"path"` Path string `json:"path"`
// URL is the HTTP address of this artifact. // URL is the HTTP address of this artifact.
// It is used by the consumers of the artifacts to fetch and use the
// artifacts. It is expected to be resolvable from within the cluster.
// +required // +required
URL string `json:"url"` URL string `json:"url"`

View File

@ -69,7 +69,7 @@ type BucketSpec struct {
// +required // +required
Interval metav1.Duration `json:"interval"` Interval metav1.Duration `json:"interval"`
// The timeout for download operations, defaults to 60s. // The timeout for fetch operations, defaults to 60s.
// +kubebuilder:default="60s" // +kubebuilder:default="60s"
// +optional // +optional
Timeout *metav1.Duration `json:"timeout,omitempty"` Timeout *metav1.Duration `json:"timeout,omitempty"`
@ -99,7 +99,7 @@ type BucketStatus struct {
// +optional // +optional
Conditions []metav1.Condition `json:"conditions,omitempty"` Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the download link for the artifact output of the last Bucket sync. // URL is the fetch link for the artifact output of the last Bucket sync.
// +optional // +optional
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`
@ -111,12 +111,12 @@ type BucketStatus struct {
} }
const ( const (
// BucketOperationSucceedReason represents the fact that the bucket listing and // BucketOperationSucceededReason represents the fact that the bucket listing and
// download operations succeeded. // fetch operations succeeded.
BucketOperationSucceedReason string = "BucketOperationSucceed" BucketOperationSucceededReason string = "BucketOperationSucceeded"
// BucketOperationFailedReason represents the fact that the bucket listing or // BucketOperationFailedReason represents the fact that the bucket listing or
// download operations failed. // fetch operations failed.
BucketOperationFailedReason string = "BucketOperationFailed" BucketOperationFailedReason string = "BucketOperationFailed"
) )

View File

@ -168,7 +168,7 @@ type GitRepositoryStatus struct {
// +optional // +optional
Conditions []metav1.Condition `json:"conditions,omitempty"` Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the download link for the artifact output of the last repository sync. // URL is the fetch link for the artifact output of the last repository sync.
// +optional // +optional
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`

View File

@ -127,7 +127,7 @@ type HelmChartStatus struct {
// +optional // +optional
Conditions []metav1.Condition `json:"conditions,omitempty"` Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the download link for the last chart pulled. // URL is the fetch link for the last chart pulled.
// +optional // +optional
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`

View File

@ -61,7 +61,7 @@ type HelmRepositorySpec struct {
// +required // +required
Interval metav1.Duration `json:"interval"` Interval metav1.Duration `json:"interval"`
// The timeout of index downloading, defaults to 60s. // The timeout of index fetching, defaults to 60s.
// +kubebuilder:default:="60s" // +kubebuilder:default:="60s"
// +optional // +optional
Timeout *metav1.Duration `json:"timeout,omitempty"` Timeout *metav1.Duration `json:"timeout,omitempty"`
@ -85,7 +85,7 @@ type HelmRepositoryStatus struct {
// +optional // +optional
Conditions []metav1.Condition `json:"conditions,omitempty"` Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the download link for the last index fetched. // URL is the fetch link for the last index fetched.
// +optional // +optional
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`

View File

@ -356,7 +356,7 @@ spec:
type: boolean type: boolean
timeout: timeout:
default: 60s default: 60s
description: The timeout for download operations, defaults to 60s. description: The timeout for fetch operations, defaults to 60s.
type: string type: string
required: required:
- bucketName - bucketName
@ -381,7 +381,10 @@ spec:
format: date-time format: date-time
type: string type: string
path: path:
description: Path is the relative file path of this artifact. description: Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of the
Artifact storage on the local file system of the controller
managing the Source.
type: string type: string
revision: revision:
description: Revision is a human readable identifier traceable description: Revision is a human readable identifier traceable
@ -389,7 +392,9 @@ spec:
tag, a Helm index timestamp, a Helm chart version, etc. tag, a Helm index timestamp, a Helm chart version, etc.
type: string type: string
url: url:
description: URL is the HTTP address of this artifact. description: URL is the HTTP address of this artifact. It is used
by the consumers of the artifacts to fetch and use the artifacts.
It is expected to be resolvable from within the cluster.
type: string type: string
required: required:
- path - path
@ -475,7 +480,7 @@ spec:
format: int64 format: int64
type: integer type: integer
url: url:
description: URL is the download link for the artifact output of the description: URL is the fetch link for the artifact output of the
last Bucket sync. last Bucket sync.
type: string type: string
type: object type: object

View File

@ -549,7 +549,10 @@ spec:
format: date-time format: date-time
type: string type: string
path: path:
description: Path is the relative file path of this artifact. description: Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of the
Artifact storage on the local file system of the controller
managing the Source.
type: string type: string
revision: revision:
description: Revision is a human readable identifier traceable description: Revision is a human readable identifier traceable
@ -557,7 +560,9 @@ spec:
tag, a Helm index timestamp, a Helm chart version, etc. tag, a Helm index timestamp, a Helm chart version, etc.
type: string type: string
url: url:
description: URL is the HTTP address of this artifact. description: URL is the HTTP address of this artifact. It is used
by the consumers of the artifacts to fetch and use the artifacts.
It is expected to be resolvable from within the cluster.
type: string type: string
required: required:
- path - path
@ -637,7 +642,7 @@ spec:
description: IncludedArtifacts represents the included artifacts from description: IncludedArtifacts represents the included artifacts from
the last successful repository sync. the last successful repository sync.
items: items:
description: Artifact represents the output of a source synchronisation. description: Artifact represents the output of a Source synchronisation.
properties: properties:
checksum: checksum:
description: Checksum is the SHA256 checksum of the artifact. description: Checksum is the SHA256 checksum of the artifact.
@ -648,7 +653,10 @@ spec:
format: date-time format: date-time
type: string type: string
path: path:
description: Path is the relative file path of this artifact. description: Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of
the Artifact storage on the local file system of the controller
managing the Source.
type: string type: string
revision: revision:
description: Revision is a human readable identifier traceable description: Revision is a human readable identifier traceable
@ -656,7 +664,10 @@ spec:
tag, a Helm index timestamp, a Helm chart version, etc. tag, a Helm index timestamp, a Helm chart version, etc.
type: string type: string
url: url:
description: URL is the HTTP address of this artifact. description: URL is the HTTP address of this artifact. It is
used by the consumers of the artifacts to fetch and use the
artifacts. It is expected to be resolvable from within the
cluster.
type: string type: string
required: required:
- path - path
@ -673,7 +684,7 @@ spec:
format: int64 format: int64
type: integer type: integer
url: url:
description: URL is the download link for the artifact output of the description: URL is the fetch link for the artifact output of the
last repository sync. last repository sync.
type: string type: string
type: object type: object

View File

@ -428,7 +428,10 @@ spec:
format: date-time format: date-time
type: string type: string
path: path:
description: Path is the relative file path of this artifact. description: Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of the
Artifact storage on the local file system of the controller
managing the Source.
type: string type: string
revision: revision:
description: Revision is a human readable identifier traceable description: Revision is a human readable identifier traceable
@ -436,7 +439,9 @@ spec:
tag, a Helm index timestamp, a Helm chart version, etc. tag, a Helm index timestamp, a Helm chart version, etc.
type: string type: string
url: url:
description: URL is the HTTP address of this artifact. description: URL is the HTTP address of this artifact. It is used
by the consumers of the artifacts to fetch and use the artifacts.
It is expected to be resolvable from within the cluster.
type: string type: string
required: required:
- path - path
@ -530,7 +535,7 @@ spec:
of the Source reference. of the Source reference.
type: string type: string
url: url:
description: URL is the download link for the last chart pulled. description: URL is the fetch link for the last chart pulled.
type: string type: string
type: object type: object
type: object type: object

View File

@ -326,7 +326,7 @@ spec:
type: boolean type: boolean
timeout: timeout:
default: 60s default: 60s
description: The timeout of index downloading, defaults to 60s. description: The timeout of index fetching, defaults to 60s.
type: string type: string
url: url:
description: The Helm repository URL, a valid URL contains at least description: The Helm repository URL, a valid URL contains at least
@ -354,7 +354,10 @@ spec:
format: date-time format: date-time
type: string type: string
path: path:
description: Path is the relative file path of this artifact. description: Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of the
Artifact storage on the local file system of the controller
managing the Source.
type: string type: string
revision: revision:
description: Revision is a human readable identifier traceable description: Revision is a human readable identifier traceable
@ -362,7 +365,9 @@ spec:
tag, a Helm index timestamp, a Helm chart version, etc. tag, a Helm index timestamp, a Helm chart version, etc.
type: string type: string
url: url:
description: URL is the HTTP address of this artifact. description: URL is the HTTP address of this artifact. It is used
by the consumers of the artifacts to fetch and use the artifacts.
It is expected to be resolvable from within the cluster.
type: string type: string
required: required:
- path - path
@ -448,7 +453,7 @@ spec:
format: int64 format: int64
type: integer type: integer
url: url:
description: URL is the download link for the last index fetched. description: URL is the fetch link for the last index fetched.
type: string type: string
type: object type: object
type: object type: object

View File

@ -196,7 +196,7 @@ func (r *BucketReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
// error. // error.
func (r *BucketReconciler) reconcile(ctx context.Context, obj *sourcev1.Bucket, reconcilers []bucketReconcilerFunc) (sreconcile.Result, error) { func (r *BucketReconciler) reconcile(ctx context.Context, obj *sourcev1.Bucket, reconcilers []bucketReconcilerFunc) (sreconcile.Result, error) {
if obj.Generation != obj.Status.ObservedGeneration { if obj.Generation != obj.Status.ObservedGeneration {
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new generation %d", obj.Generation) conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
} }
var artifact sourcev1.Artifact var artifact sourcev1.Artifact
@ -432,14 +432,14 @@ func (r *BucketReconciler) reconcileMinioSource(ctx context.Context, obj *source
}) })
if err = group.Wait(); err != nil { if err = group.Wait(); err != nil {
e := &serror.Event{ e := &serror.Event{
Err: fmt.Errorf("download from bucket '%s' failed: %w", obj.Spec.BucketName, err), Err: fmt.Errorf("fetch from bucket '%s' failed: %w", obj.Spec.BucketName, err),
Reason: sourcev1.BucketOperationFailedReason, Reason: sourcev1.BucketOperationFailedReason,
} }
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.BucketOperationFailedReason, e.Err.Error()) conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.BucketOperationFailedReason, e.Err.Error())
return sreconcile.ResultEmpty, e return sreconcile.ResultEmpty, e
} }
r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.BucketOperationSucceedReason, r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.BucketOperationSucceededReason,
"downloaded %d files with revision '%s' from '%s'", len(index), revision, obj.Spec.BucketName) "fetched %d files with revision '%s' from '%s'", len(index), revision, obj.Spec.BucketName)
} }
conditions.Delete(obj, sourcev1.FetchFailedCondition) conditions.Delete(obj, sourcev1.FetchFailedCondition)
@ -587,14 +587,14 @@ func (r *BucketReconciler) reconcileGCPSource(ctx context.Context, obj *sourcev1
}) })
if err = group.Wait(); err != nil { if err = group.Wait(); err != nil {
e := &serror.Event{ e := &serror.Event{
Err: fmt.Errorf("download from bucket '%s' failed: %w", obj.Spec.BucketName, err), Err: fmt.Errorf("fetch from bucket '%s' failed: %w", obj.Spec.BucketName, err),
Reason: sourcev1.BucketOperationFailedReason, Reason: sourcev1.BucketOperationFailedReason,
} }
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.BucketOperationFailedReason, e.Err.Error()) conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.BucketOperationFailedReason, e.Err.Error())
return sreconcile.ResultEmpty, e return sreconcile.ResultEmpty, e
} }
r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.BucketOperationSucceedReason, r.eventLogf(ctx, obj, events.EventTypeTrace, sourcev1.BucketOperationSucceededReason,
"downloaded %d files from bucket '%s'", len(index), obj.Spec.BucketName) "fetched %d files from bucket '%s'", len(index), obj.Spec.BucketName)
} }
conditions.Delete(obj, sourcev1.FetchFailedCondition) conditions.Delete(obj, sourcev1.FetchFailedCondition)

View File

@ -204,7 +204,7 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
// error. // error.
func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.GitRepository, reconcilers []gitRepoReconcilerFunc) (sreconcile.Result, error) { func (r *GitRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.GitRepository, reconcilers []gitRepoReconcilerFunc) (sreconcile.Result, error) {
if obj.Generation != obj.Status.ObservedGeneration { if obj.Generation != obj.Status.ObservedGeneration {
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new generation %d", obj.Generation) conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
} }
var artifact sourcev1.Artifact var artifact sourcev1.Artifact

View File

@ -227,7 +227,7 @@ func (r *HelmChartReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
// produces an error. // produces an error.
func (r *HelmChartReconciler) reconcile(ctx context.Context, obj *sourcev1.HelmChart, reconcilers []helmChartReconcilerFunc) (sreconcile.Result, error) { func (r *HelmChartReconciler) reconcile(ctx context.Context, obj *sourcev1.HelmChart, reconcilers []helmChartReconcilerFunc) (sreconcile.Result, error) {
if obj.Generation != obj.Status.ObservedGeneration { if obj.Generation != obj.Status.ObservedGeneration {
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new generation %d", obj.Generation) conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
} }
// Run the sub-reconcilers and build the result of reconciliation. // Run the sub-reconcilers and build the result of reconciliation.

View File

@ -1376,7 +1376,7 @@ func TestHelmChartReconciler_reconcileSubRecs(t *testing.T) {
wantResult: sreconcile.ResultSuccess, wantResult: sreconcile.ResultSuccess,
wantErr: false, wantErr: false,
assertConditions: []metav1.Condition{ assertConditions: []metav1.Condition{
*conditions.TrueCondition(meta.ReconcilingCondition, "NewGeneration", "reconciling new generation 3"), *conditions.TrueCondition(meta.ReconcilingCondition, "NewGeneration", "reconciling new object generation (3)"),
}, },
}, },
{ {

View File

@ -192,7 +192,7 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// result with the shortest requeue period. // result with the shortest requeue period.
func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.HelmRepository, reconcilers []helmRepoReconcilerFunc) (sreconcile.Result, error) { func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.HelmRepository, reconcilers []helmRepoReconcilerFunc) (sreconcile.Result, error) {
if obj.Generation != obj.Status.ObservedGeneration { if obj.Generation != obj.Status.ObservedGeneration {
conditions.MarkReconciling(obj, "NewGeneration", "reconciling new generation %d", obj.Generation) conditions.MarkReconciling(obj, "NewGeneration", "reconciling new object generation (%d)", obj.Generation)
} }
var chartRepo repository.ChartRepository var chartRepo repository.ChartRepository
@ -328,7 +328,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, obj *sou
checksum, err := newChartRepo.CacheIndex() checksum, err := newChartRepo.CacheIndex()
if err != nil { if err != nil {
e := &serror.Event{ e := &serror.Event{
Err: fmt.Errorf("failed to download Helm repository index: %w", err), Err: fmt.Errorf("failed to fetch Helm repository index: %w", err),
Reason: meta.FailedReason, Reason: meta.FailedReason,
} }
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, meta.FailedReason, e.Err.Error()) conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, meta.FailedReason, e.Err.Error())

View File

@ -660,7 +660,7 @@ func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
wantResult: sreconcile.ResultSuccess, wantResult: sreconcile.ResultSuccess,
wantErr: false, wantErr: false,
assertConditions: []metav1.Condition{ assertConditions: []metav1.Condition{
*conditions.TrueCondition(meta.ReconcilingCondition, "NewGeneration", "reconciling new generation 3"), *conditions.TrueCondition(meta.ReconcilingCondition, "NewGeneration", "reconciling new object generation (3)"),
}, },
}, },
{ {

View File

@ -171,7 +171,7 @@ Kubernetes meta/v1.Duration
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>The timeout for download operations, defaults to 60s.</p> <p>The timeout for fetch operations, defaults to 60s.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -797,7 +797,7 @@ Kubernetes meta/v1.Duration
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>The timeout of index downloading, defaults to 60s.</p> <p>The timeout of index fetching, defaults to 60s.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -854,7 +854,7 @@ HelmRepositoryStatus
<a href="#source.toolkit.fluxcd.io/v1beta2.HelmChartStatus">HelmChartStatus</a>, <a href="#source.toolkit.fluxcd.io/v1beta2.HelmChartStatus">HelmChartStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1beta2.HelmRepositoryStatus">HelmRepositoryStatus</a>) <a href="#source.toolkit.fluxcd.io/v1beta2.HelmRepositoryStatus">HelmRepositoryStatus</a>)
</p> </p>
<p>Artifact represents the output of a source synchronisation.</p> <p>Artifact represents the output of a Source synchronisation.</p>
<div class="md-typeset__scrollwrap"> <div class="md-typeset__scrollwrap">
<div class="md-typeset__table"> <div class="md-typeset__table">
<table> <table>
@ -873,7 +873,9 @@ string
</em> </em>
</td> </td>
<td> <td>
<p>Path is the relative file path of this artifact.</p> <p>Path is the relative file path of this Artifact.
It can be used to locate the Artifact file in the root of the Artifact
storage on the local file system of the controller managing the Source.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -884,7 +886,9 @@ string
</em> </em>
</td> </td>
<td> <td>
<p>URL is the HTTP address of this artifact.</p> <p>URL is the HTTP address of this artifact.
It is used by the consumers of the artifacts to fetch and use the
artifacts. It is expected to be resolvable from within the cluster.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1045,7 +1049,7 @@ Kubernetes meta/v1.Duration
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>The timeout for download operations, defaults to 60s.</p> <p>The timeout for fetch operations, defaults to 60s.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1144,7 +1148,7 @@ string
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>URL is the download link for the artifact output of the last Bucket sync.</p> <p>URL is the fetch link for the artifact output of the last Bucket sync.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1543,7 +1547,7 @@ string
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>URL is the download link for the artifact output of the last repository sync.</p> <p>URL is the fetch link for the artifact output of the last repository sync.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1811,6 +1815,32 @@ int64
</tr> </tr>
<tr> <tr>
<td> <td>
<code>observedSourceArtifactRevision</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ObservedSourceArtifactRevision is the last observed Artifact.Revision
of the Source reference.</p>
</td>
</tr>
<tr>
<td>
<code>observedChartName</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ObservedChartName is the last observed chart name as defined by the
resolved chart reference.</p>
</td>
</tr>
<tr>
<td>
<code>conditions</code><br> <code>conditions</code><br>
<em> <em>
<a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Condition"> <a href="https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Condition">
@ -1832,7 +1862,7 @@ string
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>URL is the download link for the last chart pulled.</p> <p>URL is the fetch link for the last chart pulled.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1956,7 +1986,7 @@ Kubernetes meta/v1.Duration
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>The timeout of index downloading, defaults to 60s.</p> <p>The timeout of index fetching, defaults to 60s.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -2041,7 +2071,7 @@ string
</td> </td>
<td> <td>
<em>(Optional)</em> <em>(Optional)</em>
<p>URL is the download link for the last index fetched.</p> <p>URL is the fetch link for the last index fetched.</p>
</td> </td>
</tr> </tr>
<tr> <tr>