Compile regex on demand not in init

Every podman command is paying the price for this compile even when they
don't use the Regex, this will speed up start of podman by a little.

[NO NEW TESTS NEEDED] Existing tests should catch issues.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2023-01-11 08:56:16 -05:00
parent 1e451031ff
commit 758f20e20a
5 changed files with 96 additions and 70 deletions

View File

@ -10,6 +10,7 @@ import (
"os" "os"
"regexp" "regexp"
"strings" "strings"
"sync"
) )
const ( const (
@ -22,8 +23,9 @@ const (
var ( var (
whiteSpaces = " \t" whiteSpaces = " \t"
alphaRegexp = regexp.MustCompile(`[a-zA-Z]`) alphaRegexp *regexp.Regexp
domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`) domainRegexp *regexp.Regexp
onceRegex sync.Once
) )
// validateExtraHost validates that the specified string is a valid extrahost and returns it. // validateExtraHost validates that the specified string is a valid extrahost and returns it.
@ -52,6 +54,10 @@ func validateIPAddress(val string) (string, error) {
} }
func ValidateDomain(val string) (string, error) { func ValidateDomain(val string) (string, error) {
onceRegex.Do(func() {
alphaRegexp = regexp.MustCompile(`[a-zA-Z]`)
domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
})
if alphaRegexp.FindString(val) == "" { if alphaRegexp.FindString(val) == "" {
return "", fmt.Errorf("%s is not a valid domain", val) return "", fmt.Errorf("%s is not a valid domain", val)
} }

View File

@ -3,7 +3,6 @@ package define
import ( import (
"bufio" "bufio"
"io" "io"
"regexp"
"github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/types"
) )
@ -20,8 +19,6 @@ var (
NameRegex = types.NameRegex NameRegex = types.NameRegex
// RegexError is thrown in presence of an invalid container/pod name. // RegexError is thrown in presence of an invalid container/pod name.
RegexError = types.RegexError RegexError = types.RegexError
// UmaskRegex is a regular expression to validate Umask.
UmaskRegex = regexp.MustCompile(`^[0-7]{1,4}$`)
) )
const ( const (

View File

@ -6,7 +6,9 @@ import (
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"sync"
"syscall" "syscall"
"github.com/containers/buildah/pkg/parse" "github.com/containers/buildah/pkg/parse"
@ -28,6 +30,11 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var (
umaskRegex *regexp.Regexp
onceRegex sync.Once
)
// WithStorageConfig uses the given configuration to set up container storage. // WithStorageConfig uses the given configuration to set up container storage.
// If this is not specified, the system default configuration will be used // If this is not specified, the system default configuration will be used
// instead. // instead.
@ -1790,11 +1797,14 @@ func WithTimezone(path string) CtrCreateOption {
// WithUmask sets the umask in the container // WithUmask sets the umask in the container
func WithUmask(umask string) CtrCreateOption { func WithUmask(umask string) CtrCreateOption {
onceRegex.Do(func() {
umaskRegex = regexp.MustCompile(`^[0-7]{1,4}$`)
})
return func(ctr *Container) error { return func(ctr *Container) error {
if ctr.valid { if ctr.valid {
return define.ErrCtrFinalized return define.ErrCtrFinalized
} }
if !define.UmaskRegex.MatchString(umask) { if !umaskRegex.MatchString(umask) {
return fmt.Errorf("invalid umask string %s: %w", umask, define.ErrInvalidArg) return fmt.Errorf("invalid umask string %s: %w", umask, define.ErrInvalidArg)
} }
ctr.config.Umask = umask ctr.config.Umask = umask

View File

@ -17,6 +17,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"github.com/containers/buildah/define" "github.com/containers/buildah/define"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
@ -37,11 +38,16 @@ type devino struct {
} }
var ( var (
iidRegex = regexp.MustCompile(`^[0-9a-f]{12}`) iidRegex *regexp.Regexp
onceRegex sync.Once
) )
// Build creates an image using a containerfile reference // Build creates an image using a containerfile reference
func Build(ctx context.Context, containerFiles []string, options entities.BuildOptions) (*entities.BuildReport, error) { func Build(ctx context.Context, containerFiles []string, options entities.BuildOptions) (*entities.BuildReport, error) {
onceRegex.Do(func() {
iidRegex = regexp.MustCompile(`^[0-9a-f]{12}`)
})
if options.CommonBuildOpts == nil { if options.CommonBuildOpts == nil {
options.CommonBuildOpts = new(define.CommonBuildOptions) options.CommonBuildOpts = new(define.CommonBuildOptions)
} }

View File

@ -5,6 +5,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"sync"
"github.com/containers/podman/v4/pkg/systemd/parser" "github.com/containers/podman/v4/pkg/systemd/parser"
) )
@ -29,8 +30,6 @@ const (
XNetworkGroup = "X-Network" XNetworkGroup = "X-Network"
) )
var validPortRange = regexp.MustCompile(`\d+(-\d+)?(/udp|/tcp)?$`)
// All the supported quadlet keys // All the supported quadlet keys
const ( const (
KeyContainerName = "ContainerName" KeyContainerName = "ContainerName"
@ -75,8 +74,12 @@ const (
KeyConfigMap = "ConfigMap" KeyConfigMap = "ConfigMap"
) )
// Supported keys in "Container" group var (
var supportedContainerKeys = map[string]bool{ onceRegex sync.Once
validPortRange *regexp.Regexp
// Supported keys in "Container" group
supportedContainerKeys = map[string]bool{
KeyContainerName: true, KeyContainerName: true,
KeyImage: true, KeyImage: true,
KeyEnvironment: true, KeyEnvironment: true,
@ -106,17 +109,17 @@ var supportedContainerKeys = map[string]bool{
KeySeccompProfile: true, KeySeccompProfile: true,
KeyAddDevice: true, KeyAddDevice: true,
KeyNetwork: true, KeyNetwork: true,
} }
// Supported keys in "Volume" group // Supported keys in "Volume" group
var supportedVolumeKeys = map[string]bool{ supportedVolumeKeys = map[string]bool{
KeyUser: true, KeyUser: true,
KeyGroup: true, KeyGroup: true,
KeyLabel: true, KeyLabel: true,
} }
// Supported keys in "Volume" group // Supported keys in "Volume" group
var supportedNetworkKeys = map[string]bool{ supportedNetworkKeys = map[string]bool{
KeyNetworkDisableDNS: true, KeyNetworkDisableDNS: true,
KeyNetworkDriver: true, KeyNetworkDriver: true,
KeyNetworkGateway: true, KeyNetworkGateway: true,
@ -127,10 +130,10 @@ var supportedNetworkKeys = map[string]bool{
KeyNetworkOptions: true, KeyNetworkOptions: true,
KeyNetworkSubnet: true, KeyNetworkSubnet: true,
KeyLabel: true, KeyLabel: true,
} }
// Supported keys in "Kube" group // Supported keys in "Kube" group
var supportedKubeKeys = map[string]bool{ supportedKubeKeys = map[string]bool{
KeyYaml: true, KeyYaml: true,
KeyRemapUID: true, KeyRemapUID: true,
KeyRemapGID: true, KeyRemapGID: true,
@ -138,7 +141,8 @@ var supportedKubeKeys = map[string]bool{
KeyRemapUIDSize: true, KeyRemapUIDSize: true,
KeyNetwork: true, KeyNetwork: true,
KeyConfigMap: true, KeyConfigMap: true,
} }
)
func replaceExtension(name string, extension string, extraPrefix string, extraSuffix string) string { func replaceExtension(name string, extension string, extraPrefix string, extraSuffix string) string {
baseName := name baseName := name
@ -152,6 +156,9 @@ func replaceExtension(name string, extension string, extraPrefix string, extraSu
} }
func isPortRange(port string) bool { func isPortRange(port string) bool {
onceRegex.Do(func() {
validPortRange = regexp.MustCompile(`\d+(-\d+)?(/udp|/tcp)?$`)
})
return validPortRange.MatchString(port) return validPortRange.MatchString(port)
} }