Last updated
Was this helpful?
Last updated
Was this helpful?
The Custom Versioning Schema (CVS) is a way for Snyk to understand your company’s container image tag versioning schema. It enables Snyk to give more accurate base image upgrade recommendations.
CVS is part of the Snyk Container Custom Base Images feature. For more information, see .
If your container image's tags follow a versioning schema other than (SemVer), it is highly recommended that you select the Custom Versioning Schema for your image repositories.
CVS is essentially a regular expression that groups the different parts of an image’s tag into comparable sections.
As an example, consider the following image tags:
Because this repository’s image tags do not follow the semantic versioning standard, it is necessary to describe the tags using a custom versioning schema.
The snyk/example
tag schema is defined by the following elements, in this order:
A number whose value has the highest significance (MAJOR part)
A period
Another number, whose significance is less than the first number number (MINOR part)
An underscore followed by the letter "V" (version)
A number whose value is the least significant.
For Snyk to understand the different parts and their role, it is necessary to define a schema. In this regular expression, named groups represent the significant variables.
The schema below is a translated version of the above example and its elements.
Instead of naming a group "SIGNIFICANT", the name is changed to the letter "C" followed by a number. "C" stands for "compare", and the number represents the significance of that group, where 0 is the most significant.
Snyk then:
Parses all of the tags in a repository using this expression.
Compares the values in order of significance.
Generates a set of images ordered by their tags.
Snyk can then use this ordered set to give better recommendations.
The example below expands on the repository in the previous example and includes a small modification to add a slim version of each image.
The schema below ensures that you receive only recommendations for the flavor you are currently using.
This includes a new group M0, where "M" stands for "match." Snyk then uses this group to filter out possible image recommendations where the MATCH group's value is not equal.
The number following "M" differentiates the multiple categories that your tag can have. In this case, there is only one category of things to match against, so there is only one MATCH group.
For example, recommendations for snyk/example:1.2_V3-slim
do not include images whose M0 group does not equal "slim".
The example below shows how to develop the expression for this registry.
Start with defining the simple SemVer element:
This groups the major, minor, and patch parts of the tag.
Next, there is a section that indicates the underlying OS distribution. Here, there are two options:
If the OS that the base image is using is not a concern, and only the version's magnitude is a concern, "ignore" this section by not grouping it in the regex: _.*_
.
To avoid a mismatch between distributions, add a MATCH group: (?<M0>deb\d+)
Now, the expression looks like this:
Next is the date element. Sometimes dates are there only to provide more information and need not be taken into consideration when comparing versions. In this case, skip over it.
If the date element is important, decide how significant each date element is relative to the SemVer. For example, is the year more significant than a major version?
To keep the significance order, use the regex:
Since the date is ordered in such a way that the number produced by concatenating the year, month, day, and hour can be compared to another concatenated date correctly, the long regex above can be replaced with a simpler one:
Now the regex looks like this:
The optional flavor is last. Add another MATCH group here and make it optional:
This avoids getting slim
recommended if it is not in use and only gets slim
recommended if it is being used.
The complete custom versioning schema expression looks like this:
In cases where a repository does not have a consistent tagging format, you can use non-capture groups.
The above repository contains an inconsistent number of capture groups. To handle this, use the following expression:
In part (?:\.(?<C2>\d+))?
, the expression optionally includes a COMPARE group.
When there is an inconsistent number of COMPARE groups, Snyk filters out tags that do not contain enough information to compare them accurately. That is, to get a recommendation for snyk/example:1.2.4
, Snyk does not consider snyk/example:1.2
to be a newer version because it is not possible to know whether 1.2
is the same as 1.2.0
or whether it is a rolling tag that points to 1.2.8
. However, 1.3
, and 1.3.5
are both higher than 1.2.4
and are taken into account as a possible recommendation.
Since 1.3
and 1.3.5
have the same issue as 1.2
and 1.2.4
, the recommendation is either 1.3
or 1.3.5
. At this point, the specific version that is recommended depends on undefined internal factors. However, Snyk aims to improve this logic.
Note that the regular expression string is parsed as an ECMAScript regex and then internally converted to RE2 syntax. For example, use the (?<name>re)
syntax for grouping. (?P<name>re)
will not parse correctly.
The maximum length of the expression is 1,000 characters, with up to 100 COMPARE groups and 100 MATCH groups.
All named groups must start with either the letter "C" or the letter "M", followed by an index.
There must be at least one COMPARE group.
If an unnamed group is required, it must be explicitly marked as non-capturing.
If a compare group is an unsigned integer, compare its numeric value. Else, it will be treated as a string.
MATCH groups are case-sensitive.
If a MATCH group exists on one tag and not the other, due to the use of optional groups, the tags are considered not matching.
Use of unsupported or invalid regex syntax
This error can happen if an expression that does not conform to ECMAScript syntax is passed.
An example is using Python’s named capture group syntax (?P<C0>.*)
.
In the example, change the capture group syntax from (?P<C0>.*)
to (?<C0>.*)
.
Use of an unsupported regex feature
This error can happen if an expression is passed that contains unsupported regex features such as lookahead assertions and backreferences.
For example (?<thing>.+)_\\k<thing>/
.
There is no simple fix. The expression must be redesigned to work without such features.
Group name format is incorrect
Custom Versioning Schema uses named groups that follow a specific naming format.
This error can happen if a named group exists that does not follow the format of either a C
or an M
, followed by a positive number, such as C2
or M51.
Change the group name to fit the format. If you need only a group, you can use non-capture groups.
Operator index is too big
This error can happen if the number in your named group is larger than 100, such as (?<C101>.*)
.
Use a number between 0 and 100.
Take into consideration that each character does not require its own separate group. If it makes logical sense, bunch the characters together to end up with fewer groups.
If you still require more than 100 groups, CVS might not be a great fit.
Group is missing a name
This error can happen if a group other than a named group or non-capture group is used.
For example (debian)|(ubuntu)
.
Often the solution is to explicitly define a non-capture group.
The example (debian)|(ubuntu)
becomes (?:debian)|(?:ubuntu)
.
No groups were found
CVS uses named groups to categorize the parts of the tag into comparable sections.
This error can happen if no named groups are found, in which case Snyk cannot compare different image tags to each other.
Expression length is not supported
As with every user input, a maximum length must be set. In this case, the limit is 1,000 characters.
If your expression string is longer than 1,000 characters, Snyk is not able to parse it.
If you still require more than 1,000 characters to describe your tags, CVS might not be a great fit.
CVS uses a subset of the ECMAScript regex. See the .
Backreferences and lookahead assertions are not supported. Internally, Snyk uses the RE2 library. For a full list of unsupported features, see .
In the list of , take into consideration only the feature, not the syntax.
Comparison of non-numeric characters is done by comparing their sequences of UTF-16 code unit values. For more information, see .
For information on the regex syntax, see .
See .
See the to better understand how Snyk compares and filters out tags.
Shorten the string by using and instead of specific characters.
For information on other options, contact .