Change default repositories for Helm v2 (#8901)

* switch to new repository URLs

Signed-off-by: Matt Butcher <matt.butcher@microsoft.com>

* added warning each time old repository is noticed

Signed-off-by: Matt Butcher <matt.butcher@microsoft.com>
release-2.17
Matt Butcher 4 years ago committed by GitHub
parent d70b260dc8
commit 62d6e4076b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -100,7 +100,7 @@ docker-build-experimental: check-docker docker-binary docker-binary-rudder
.PHONY: test .PHONY: test
test: build test: build
test: TESTFLAGS += -race -v test: TESTFLAGS += -v
test: test-style test: test-style
test: test-unit test: test-unit

@ -36,6 +36,7 @@ import (
helm_env "k8s.io/helm/pkg/helm/environment" helm_env "k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/portforwarder" "k8s.io/helm/pkg/helm/portforwarder"
"k8s.io/helm/pkg/kube" "k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/tlsutil" "k8s.io/helm/pkg/tlsutil"
) )
@ -175,6 +176,52 @@ Environment:
` `
func checkForExpiredRepos(repofile string) {
expiredRepos := []struct {
name string
old string
new string
}{
{
name: "stable",
old: "kubernetes-charts.storage.googleapis.com",
new: "https://charts.helm.sh/stable",
},
{
name: "incubator",
old: "kubernetes-charts-incubator.storage.googleapis.com",
new: "https://charts.helm.sh/incubator",
},
}
// parse repo file.
// Ignore the error because it is okay for a repo file to be unparseable at this
// stage. Later checks will trap the error and respond accordingly.
repoFile, err := repo.LoadRepositoriesFile(repofile)
if err != nil {
return
}
for _, exp := range expiredRepos {
r, ok := repoFile.Get(exp.name)
if !ok {
return
}
if url := r.URL; strings.Contains(url, exp.old) {
fmt.Fprintf(
os.Stderr,
"WARNING: %q is deprecated for %q and will be deleted Nov. 13, 2020.\nWARNING: You should switch to %q\n",
exp.old,
exp.name,
exp.new,
)
}
}
}
func newRootCmd(args []string) *cobra.Command { func newRootCmd(args []string) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "helm", Use: "helm",
@ -182,6 +229,7 @@ func newRootCmd(args []string) *cobra.Command {
Long: globalUsage, Long: globalUsage,
SilenceUsage: true, SilenceUsage: true,
PersistentPreRun: func(*cobra.Command, []string) { PersistentPreRun: func(*cobra.Command, []string) {
checkForExpiredRepos(settings.Home.RepositoryFile())
if settings.TLSCaCertFile == helm_env.DefaultTLSCaCert || settings.TLSCaCertFile == "" { if settings.TLSCaCertFile == helm_env.DefaultTLSCaCert || settings.TLSCaCertFile == "" {
settings.TLSCaCertFile = settings.Home.TLSCaCert() settings.TLSCaCertFile = settings.Home.TLSCaCert()
} else { } else {

@ -59,7 +59,8 @@ To dump a manifest containing the Tiller deployment YAML, combine the
` `
var ( var (
stableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com" stableRepositoryURL = "https://charts.helm.sh/stable"
oldStableRepositoryURL = "https://kubernetes-charts.storage.googleapis.com"
// This is the IPv4 loopback, not localhost, because we have to force IPv4 // This is the IPv4 loopback, not localhost, because we have to force IPv4
// for Dockerized Helm: https://github.com/kubernetes/helm/issues/1410 // for Dockerized Helm: https://github.com/kubernetes/helm/issues/1410
localRepositoryURL = "http://127.0.0.1:8879/charts" localRepositoryURL = "http://127.0.0.1:8879/charts"
@ -72,24 +73,25 @@ var (
) )
type initCmd struct { type initCmd struct {
image string image string
clientOnly bool clientOnly bool
canary bool canary bool
upgrade bool upgrade bool
namespace string namespace string
dryRun bool dryRun bool
forceUpgrade bool forceUpgrade bool
skipRefresh bool skipRefresh bool
skipRepos bool skipRepos bool
out io.Writer out io.Writer
client helm.Interface client helm.Interface
home helmpath.Home home helmpath.Home
opts installer.Options opts installer.Options
kubeClient kubernetes.Interface kubeClient kubernetes.Interface
serviceAccount string serviceAccount string
maxHistory int maxHistory int
replicas int replicas int
wait bool wait bool
useDeprecatedRepo bool
} }
func newInitCmd(out io.Writer) *cobra.Command { func newInitCmd(out io.Writer) *cobra.Command {
@ -122,6 +124,8 @@ func newInitCmd(out io.Writer) *cobra.Command {
f.BoolVar(&i.skipRepos, "skip-repos", false, "Skip adding the stable and local repositories") f.BoolVar(&i.skipRepos, "skip-repos", false, "Skip adding the stable and local repositories")
f.BoolVar(&i.wait, "wait", false, "Block until Tiller is running and ready to receive requests") f.BoolVar(&i.wait, "wait", false, "Block until Tiller is running and ready to receive requests")
f.BoolVar(&i.useDeprecatedRepo, "use-deprecated-stable-repository", false, "Use the old (googleapis) repository URL even though that URL is being shutdown.")
// TODO: replace TLS flags with pkg/helm/environment.AddFlagsTLS() in Helm 3 // TODO: replace TLS flags with pkg/helm/environment.AddFlagsTLS() in Helm 3
// //
// NOTE (bacongobbler): we can't do this in Helm 2 because the flag names differ, and `helm init --tls-ca-cert` // NOTE (bacongobbler): we can't do this in Helm 2 because the flag names differ, and `helm init --tls-ca-cert`
@ -265,6 +269,11 @@ func (i *initCmd) run() error {
return fmt.Errorf("error initializing: %s", err) return fmt.Errorf("error initializing: %s", err)
} }
} else { } else {
// If this is set, override user config, default config, and set it to the old
// URL.
if i.useDeprecatedRepo {
stableRepositoryURL = oldStableRepositoryURL
}
if err := installer.Initialize(i.home, i.out, i.skipRefresh, settings, stableRepositoryURL, localRepositoryURL); err != nil { if err := installer.Initialize(i.home, i.out, i.skipRefresh, settings, stableRepositoryURL, localRepositoryURL); err != nil {
return fmt.Errorf("error initializing: %s", err) return fmt.Errorf("error initializing: %s", err)
} }

@ -32,32 +32,33 @@ helm init [flags]
### Options ### Options
``` ```
--automount-service-account-token Auto-mount the given service account to tiller (default true) --automount-service-account-token Auto-mount the given service account to tiller (default true)
--canary-image Use the canary Tiller image --canary-image Use the canary Tiller image
-c, --client-only If set does not install Tiller -c, --client-only If set does not install Tiller
--dry-run Do not install local or remote --dry-run Do not install local or remote
--force-upgrade Force upgrade of Tiller to the current helm version --force-upgrade Force upgrade of Tiller to the current helm version
-h, --help help for init -h, --help help for init
--history-max int Limit the maximum number of revisions saved per release. Use 0 for no limit. --history-max int Limit the maximum number of revisions saved per release. Use 0 for no limit.
--local-repo-url string URL for local repository (default "http://127.0.0.1:8879/charts") --local-repo-url string URL for local repository (default "http://127.0.0.1:8879/charts")
--net-host Install Tiller with net=host --net-host Install Tiller with net=host
--node-selectors string Labels to specify the node on which Tiller is installed (app=tiller,helm=rocks) --node-selectors string Labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)
-o, --output OutputFormat Skip installation and output Tiller's manifest in specified format (json or yaml) -o, --output OutputFormat Skip installation and output Tiller's manifest in specified format (json or yaml)
--override stringArray Override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2) --override stringArray Override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2)
--replicas int Amount of tiller instances to run on the cluster (default 1) --replicas int Amount of tiller instances to run on the cluster (default 1)
--service-account string Name of service account --service-account string Name of service account
--skip-refresh Do not refresh (download) the local repository cache --skip-refresh Do not refresh (download) the local repository cache
--skip-repos Skip adding the stable and local repositories --skip-repos Skip adding the stable and local repositories
--stable-repo-url string URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com") --stable-repo-url string URL for stable repository (default "https://charts.helm.sh/stable")
-i, --tiller-image string Override Tiller image -i, --tiller-image string Override Tiller image
--tiller-tls Install Tiller with TLS enabled --tiller-tls Install Tiller with TLS enabled
--tiller-tls-cert string Path to TLS certificate file to install with Tiller --tiller-tls-cert string Path to TLS certificate file to install with Tiller
--tiller-tls-hostname string The server name used to verify the hostname on the returned certificates from Tiller --tiller-tls-hostname string The server name used to verify the hostname on the returned certificates from Tiller
--tiller-tls-key string Path to TLS key file to install with Tiller --tiller-tls-key string Path to TLS key file to install with Tiller
--tiller-tls-verify Install Tiller with TLS enabled and to verify remote certificates --tiller-tls-verify Install Tiller with TLS enabled and to verify remote certificates
--tls-ca-cert string Path to CA root certificate --tls-ca-cert string Path to CA root certificate
--upgrade Upgrade if Tiller is already installed --upgrade Upgrade if Tiller is already installed
--wait Block until Tiller is running and ready to receive requests --use-deprecated-stable-repository Use the old (googleapis) repository URL even though that URL is being shutdown.
--wait Block until Tiller is running and ready to receive requests
``` ```
### Options inherited from parent commands ### Options inherited from parent commands
@ -76,4 +77,4 @@ helm init [flags]
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 25-Jun-2020 ###### Auto generated by spf13/cobra on 15-Oct-2020

@ -457,7 +457,7 @@ func (m *Manager) getRepoNames(deps []*chartutil.Dependency) (map[string]string,
if containsNonURL { if containsNonURL {
errorMessage += ` errorMessage += `
Note that repositories must be URLs or aliases. For example, to refer to the stable Note that repositories must be URLs or aliases. For example, to refer to the stable
repository, use "https://kubernetes-charts.storage.googleapis.com/" or "@stable" instead of repository, use "https://charts.helm.sh/stable" or "@stable" instead of
"stable". Don't forget to add the repo, too ('helm repo add').` "stable". Don't forget to add the repo, too ('helm repo add').`
} }
return nil, errors.New(errorMessage) return nil, errors.New(errorMessage)

@ -82,7 +82,7 @@ func TestFindChartURL(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if churl != "https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz" { if churl != "https://charts.helm.sh/stable/alpine-0.1.0.tgz" {
t.Errorf("Unexpected URL %q", churl) t.Errorf("Unexpected URL %q", churl)
} }
if username != "" { if username != "" {

@ -3,7 +3,7 @@ entries:
alpine: alpine:
- name: alpine - name: alpine
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz - https://charts.helm.sh/stable/alpine-0.1.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
home: https://k8s.io/helm home: https://k8s.io/helm
sources: sources:
@ -16,7 +16,7 @@ entries:
icon: "" icon: ""
- name: alpine - name: alpine
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-0.2.0.tgz - https://charts.helm.sh/stable/alpine-0.2.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
home: https://k8s.io/helm home: https://k8s.io/helm
sources: sources:
@ -30,7 +30,7 @@ entries:
mariadb: mariadb:
- name: mariadb - name: mariadb
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/mariadb-0.3.0.tgz - https://charts.helm.sh/stable/mariadb-0.3.0.tgz
checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56 checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56
home: https://mariadb.org home: https://mariadb.org
sources: sources:

@ -17,7 +17,7 @@ entries:
- name: alpine - name: alpine
urls: urls:
- http://example.com/alpine-0.2.0.tgz - http://example.com/alpine-0.2.0.tgz
- https://kubernetes-charts.storage.googleapis.com/alpine-0.2.0.tgz - https://charts.helm.sh/stable/alpine-0.2.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
home: https://k8s.io/helm home: https://k8s.io/helm
sources: sources:

File diff suppressed because it is too large Load Diff

@ -6,7 +6,7 @@ repositories:
certFile: "" certFile: ""
keyFile: "" keyFile: ""
name: stable name: stable
url: https://kubernetes-charts.storage.googleapis.com url: https://charts.helm.sh/stable
- caFile: "" - caFile: ""
cache: repository/cache/local-index.yaml cache: repository/cache/local-index.yaml
certFile: "" certFile: ""

@ -225,7 +225,7 @@ func TestFindChartInRepoURL(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("%s", err) t.Errorf("%s", err)
} }
if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz" { if chartURL != "https://charts.helm.sh/stable/nginx-0.2.0.tgz" {
t.Errorf("%s is not the valid URL", chartURL) t.Errorf("%s is not the valid URL", chartURL)
} }
@ -233,7 +233,7 @@ func TestFindChartInRepoURL(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("%s", err) t.Errorf("%s", err)
} }
if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz" { if chartURL != "https://charts.helm.sh/stable/nginx-0.1.0.tgz" {
t.Errorf("%s is not the valid URL", chartURL) t.Errorf("%s is not the valid URL", chartURL)
} }
} }
@ -303,19 +303,19 @@ func TestResolveReferenceURL(t *testing.T) {
t.Errorf("%s does not contain the query string of the base URL", chartURL) t.Errorf("%s does not contain the query string of the base URL", chartURL)
} }
chartURL, err = ResolveReferenceURL("http://localhost:8123", "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz") chartURL, err = ResolveReferenceURL("http://localhost:8123", "https://charts.helm.sh/stable/nginx-0.2.0.tgz")
if err != nil { if err != nil {
t.Errorf("%s", err) t.Errorf("%s", err)
} }
if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz" { if chartURL != "https://charts.helm.sh/stable/nginx-0.2.0.tgz" {
t.Errorf("%s", chartURL) t.Errorf("%s", chartURL)
} }
chartURL, err = ResolveReferenceURL("http://localhost:8123/?querystring", "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz") chartURL, err = ResolveReferenceURL("http://localhost:8123/?querystring", "https://charts.helm.sh/stable/nginx-0.2.0.tgz")
if err != nil { if err != nil {
t.Errorf("%s", err) t.Errorf("%s", err)
} }
if chartURL != "https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz" { if chartURL != "https://charts.helm.sh/stable/nginx-0.2.0.tgz" {
t.Errorf("%s contains query string from base URL when it shouldn't", chartURL) t.Errorf("%s contains query string from base URL when it shouldn't", chartURL)
} }
} }

@ -109,6 +109,7 @@ func TestLoadIndex(t *testing.T) {
Name: "regular index file", Name: "regular index file",
Filename: testfile, Filename: testfile,
}, },
{ {
Name: "chartmuseum index file", Name: "chartmuseum index file",
Filename: chartmuseumtestfile, Filename: chartmuseumtestfile,
@ -327,7 +328,7 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) {
Home: "https://github.com/something", Home: "https://github.com/something",
}, },
URLs: []string{ URLs: []string{
"https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz", "https://charts.helm.sh/stable/alpine-1.0.0.tgz",
"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz", "http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz",
}, },
Digest: "sha256:1234567890abcdef", Digest: "sha256:1234567890abcdef",
@ -341,7 +342,7 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) {
Home: "https://github.com/something/else", Home: "https://github.com/something/else",
}, },
URLs: []string{ URLs: []string{
"https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz", "https://charts.helm.sh/stable/nginx-0.2.0.tgz",
}, },
Digest: "sha256:1234567890abcdef", Digest: "sha256:1234567890abcdef",
}, },
@ -354,7 +355,7 @@ func verifyLocalIndex(t *testing.T, i *IndexFile) {
Home: "https://github.com/something", Home: "https://github.com/something",
}, },
URLs: []string{ URLs: []string{
"https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz", "https://charts.helm.sh/stable/nginx-0.1.0.tgz",
}, },
Digest: "sha256:1234567890abcdef", Digest: "sha256:1234567890abcdef",
}, },

@ -4,7 +4,7 @@ apiVersion: v1
entries: entries:
nginx: nginx:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz - https://charts.helm.sh/stable/nginx-0.2.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.2.0 version: 0.2.0
@ -15,7 +15,7 @@ entries:
- web server - web server
- proxy - proxy
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz - https://charts.helm.sh/stable/nginx-0.1.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.1.0 version: 0.1.0
@ -27,7 +27,7 @@ entries:
- proxy - proxy
alpine: alpine:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz - https://charts.helm.sh/stable/alpine-1.0.0.tgz
- http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz
name: alpine name: alpine
description: string description: string

@ -2,7 +2,7 @@ apiVersion: v1
entries: entries:
nginx: nginx:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz - https://charts.helm.sh/stable/nginx-0.1.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.1.0 version: 0.1.0
@ -13,7 +13,7 @@ entries:
- web server - web server
- proxy - proxy
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz - https://charts.helm.sh/stable/nginx-0.2.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.2.0 version: 0.2.0
@ -25,7 +25,7 @@ entries:
- proxy - proxy
alpine: alpine:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz - https://charts.helm.sh/stable/alpine-1.0.0.tgz
- http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz
name: alpine name: alpine
description: string description: string

@ -2,7 +2,7 @@ apiVersion: v1
entries: entries:
nginx: nginx:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz - https://charts.helm.sh/stable/nginx-0.2.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.2.0 version: 0.2.0
@ -13,7 +13,7 @@ entries:
- web server - web server
- proxy - proxy
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz - https://charts.helm.sh/stable/nginx-0.1.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.1.0 version: 0.1.0
@ -25,7 +25,7 @@ entries:
- proxy - proxy
alpine: alpine:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz - https://charts.helm.sh/stable/alpine-1.0.0.tgz
- http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz
name: alpine name: alpine
description: string description: string

@ -2,7 +2,7 @@ apiVersion: v1
entries: entries:
nginx: nginx:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz - https://charts.helm.sh/stable/nginx-0.1.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.1.0 version: 0.1.0
@ -13,7 +13,7 @@ entries:
- web server - web server
- proxy - proxy
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz - https://charts.helm.sh/stable/nginx-0.2.0.tgz
name: nginx name: nginx
description: string description: string
version: 0.2.0 version: 0.2.0
@ -25,7 +25,7 @@ entries:
- proxy - proxy
alpine: alpine:
- urls: - urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz - https://charts.helm.sh/stable/alpine-1.0.0.tgz
- http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz
name: alpine name: alpine
description: string description: string

@ -3,7 +3,7 @@ entries:
alpine: alpine:
- name: alpine - name: alpine
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-0.1.0.tgz - https://charts.helm.sh/stable/alpine-0.1.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
home: https://k8s.io/helm home: https://k8s.io/helm
sources: sources:
@ -16,7 +16,7 @@ entries:
icon: "" icon: ""
- name: alpine - name: alpine
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/alpine-0.2.0.tgz - https://charts.helm.sh/stable/alpine-0.2.0.tgz
checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d checksum: 0e6661f193211d7a5206918d42f5c2a9470b737d
home: https://k8s.io/helm home: https://k8s.io/helm
sources: sources:
@ -30,7 +30,7 @@ entries:
mariadb: mariadb:
- name: mariadb - name: mariadb
urls: urls:
- https://kubernetes-charts.storage.googleapis.com/mariadb-0.3.0.tgz - https://charts.helm.sh/stable/mariadb-0.3.0.tgz
checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56 checksum: 65229f6de44a2be9f215d11dbff311673fc8ba56
home: https://mariadb.org home: https://mariadb.org
sources: sources:

Loading…
Cancel
Save