From f78a28395d57d6d5d3e955ff89b80e685b809c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= <torkel@grafana.org> Date: Mon, 20 Mar 2017 14:10:44 +0100 Subject: [PATCH 1/3] s3: support for alternative s3 bucket url syntax, closes #7871 --- pkg/components/imguploader/imguploader.go | 54 ++++++++++----- .../imguploader/imguploader_test.go | 65 +++++++++++++++---- 2 files changed, 90 insertions(+), 29 deletions(-) diff --git a/pkg/components/imguploader/imguploader.go b/pkg/components/imguploader/imguploader.go index 94cde098297..ae5c89a0049 100644 --- a/pkg/components/imguploader/imguploader.go +++ b/pkg/components/imguploader/imguploader.go @@ -27,25 +27,15 @@ func NewImageUploader() (ImageUploader, error) { return nil, err } - bucket := s3sec.Key("bucket_url").MustString("") + bucketUrl := s3sec.Key("bucket_url").MustString("") accessKey := s3sec.Key("access_key").MustString("") secretKey := s3sec.Key("secret_key").MustString("") - - region := "" - rBucket := regexp.MustCompile(`https?:\/\/(.*)\.s3(-([^.]+))?\.amazonaws\.com\/?`) - matches := rBucket.FindStringSubmatch(bucket) - if len(matches) == 0 { - return nil, fmt.Errorf("Could not find bucket setting for image.uploader.s3") - } else { - bucket = matches[1] - if matches[3] != "" { - region = matches[3] - } else { - region = "us-east-1" - } + info, err := getRegionAndBucketFromUrl(bucketUrl) + if err != nil { + return nil, err } - return NewS3Uploader(region, bucket, "public-read", accessKey, secretKey), nil + return NewS3Uploader(info.region, info.bucket, "public-read", accessKey, secretKey), nil case "webdav": webdavSec, err := setting.Cfg.GetSection("external_image_storage.webdav") if err != nil { @@ -65,3 +55,37 @@ func NewImageUploader() (ImageUploader, error) { return NopImageUploader{}, nil } + +type s3Info struct { + region string + bucket string +} + +func getRegionAndBucketFromUrl(url string) (*s3Info, error) { + info := &s3Info{} + urlRegex := regexp.MustCompile(`https?:\/\/(.*)\.s3(-([^.]+))?\.amazonaws\.com\/?`) + matches := urlRegex.FindStringSubmatch(url) + if len(matches) > 0 { + info.bucket = matches[1] + if matches[3] != "" { + info.region = matches[3] + } else { + info.region = "us-east-1" + } + return info, nil + } + + urlRegex2 := regexp.MustCompile(`https?:\/\/s3(-([^.]+))?\.amazonaws\.com\/(.*)?`) + matches2 := urlRegex2.FindStringSubmatch(url) + if len(matches2) > 0 { + info.bucket = matches2[3] + if matches2[2] != "" { + info.region = matches2[2] + } else { + info.region = "us-east-1" + } + return info, nil + } + + return nil, fmt.Errorf("Could not find bucket setting for image.uploader.s3") +} diff --git a/pkg/components/imguploader/imguploader_test.go b/pkg/components/imguploader/imguploader_test.go index b871aa55a64..4faaa6415f0 100644 --- a/pkg/components/imguploader/imguploader_test.go +++ b/pkg/components/imguploader/imguploader_test.go @@ -10,29 +10,66 @@ import ( func TestImageUploaderFactory(t *testing.T) { Convey("Can create image uploader for ", t, func() { - Convey("S3ImageUploader", func() { - var err error + Convey("S3ImageUploader config", func() { setting.NewConfigContext(&setting.CommandLineArgs{ HomePath: "../../../", }) setting.ImageUploadProvider = "s3" - s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") - s3sec.NewKey("bucket_url", "https://foo.bar.baz.s3-us-east-2.amazonaws.com") - s3sec.NewKey("access_key", "access_key") - s3sec.NewKey("secret_key", "secret_key") + Convey("with bucket url https://foo.bar.baz.s3-us-east-2.amazonaws.com", func() { + s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec.NewKey("bucket_url", "https://foo.bar.baz.s3-us-east-2.amazonaws.com") + s3sec.NewKey("access_key", "access_key") + s3sec.NewKey("secret_key", "secret_key") - uploader, err := NewImageUploader() + uploader, err := NewImageUploader() - So(err, ShouldBeNil) - original, ok := uploader.(*S3Uploader) + So(err, ShouldBeNil) + original, ok := uploader.(*S3Uploader) - So(ok, ShouldBeTrue) - So(original.region, ShouldEqual, "us-east-2") - So(original.bucket, ShouldEqual, "foo.bar.baz") - So(original.accessKey, ShouldEqual, "access_key") - So(original.secretKey, ShouldEqual, "secret_key") + So(ok, ShouldBeTrue) + So(original.region, ShouldEqual, "us-east-2") + So(original.bucket, ShouldEqual, "foo.bar.baz") + So(original.accessKey, ShouldEqual, "access_key") + So(original.secretKey, ShouldEqual, "secret_key") + }) + + Convey("with bucket url https://s3.amazonaws.com/mybucket", func() { + s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec.NewKey("bucket_url", "https://s3.amazonaws.com/my.bucket.com") + s3sec.NewKey("access_key", "access_key") + s3sec.NewKey("secret_key", "secret_key") + + uploader, err := NewImageUploader() + + So(err, ShouldBeNil) + original, ok := uploader.(*S3Uploader) + + So(ok, ShouldBeTrue) + So(original.region, ShouldEqual, "us-east-1") + So(original.bucket, ShouldEqual, "my.bucket.com") + So(original.accessKey, ShouldEqual, "access_key") + So(original.secretKey, ShouldEqual, "secret_key") + }) + + Convey("with bucket url https://s3-us-west-2.amazonaws.com/mybucket", func() { + s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec.NewKey("bucket_url", "https://s3-us-west-2.amazonaws.com/my.bucket.com") + s3sec.NewKey("access_key", "access_key") + s3sec.NewKey("secret_key", "secret_key") + + uploader, err := NewImageUploader() + + So(err, ShouldBeNil) + original, ok := uploader.(*S3Uploader) + + So(ok, ShouldBeTrue) + So(original.region, ShouldEqual, "us-west-2") + So(original.bucket, ShouldEqual, "my.bucket.com") + So(original.accessKey, ShouldEqual, "access_key") + So(original.secretKey, ShouldEqual, "secret_key") + }) }) Convey("Webdav uploader", func() { From 5ecc8a171f6503cde295087653769e8a682495d8 Mon Sep 17 00:00:00 2001 From: Daniel Lee <dan.limerick@gmail.com> Date: Mon, 20 Mar 2017 22:51:55 +0100 Subject: [PATCH 2/3] template: fix validation for required selects Since upgrading to Angular 1.6.1, selects with a default empty option no longer show a popup with an error on submit. This fix adds an empty option that is then removed with ng-if. Having the default option set to null or undefined seems to be the cause of the bug. The list of changes in 1.6 is here but could not find any obvious cause for this bug: https://docs.angularjs.org/guide/migration#migrating-from-1-5-to-1-6 --- public/app/features/templating/partials/editor.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/public/app/features/templating/partials/editor.html b/public/app/features/templating/partials/editor.html index 2d514060cb7..a0683debc5c 100644 --- a/public/app/features/templating/partials/editor.html +++ b/public/app/features/templating/partials/editor.html @@ -159,7 +159,9 @@ <div class="gf-form max-width-21"> <span class="gf-form-label width-7">Data source</span> <div class="gf-form-select-wrapper max-width-14"> - <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required></select> + <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required> + <option value="" ng-if="false"></option> + </select> </div> </div> <div class="gf-form max-width-21"> @@ -230,7 +232,9 @@ <div class="gf-form max-width-21"> <span class="gf-form-label width-8">Data source</span> <div class="gf-form-select-wrapper max-width-14"> - <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required ng-change="validate()"></select> + <select class="gf-form-input" ng-model="current.datasource" ng-options="f.value as f.name for f in datasources" required ng-change="validate()"> + <option value="" ng-if="false"></option> + </select> </div> </div> </div> From 99064603a4c1f9113a8d0cb8a87b8ca93af7e4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= <torkel@grafana.org> Date: Tue, 21 Mar 2017 10:35:18 +0100 Subject: [PATCH 3/3] packaging: added rpm posttrans script to fix config file change, fixes #7686 --- build.go | 16 ++++++++++++---- packaging/rpm/control/postinst | 7 ------- packaging/rpm/control/posttrans | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 11 deletions(-) mode change 100644 => 100755 packaging/rpm/control/postinst create mode 100755 packaging/rpm/control/posttrans diff --git a/build.go b/build.go index 7943bd8716c..72f7f498d97 100644 --- a/build.go +++ b/build.go @@ -14,13 +14,13 @@ import ( "log" "os" "os/exec" + "path" "path/filepath" "regexp" "runtime" "strconv" "strings" "time" - "path" ) var ( @@ -126,9 +126,9 @@ func makeLatestDistCopies() { log.Fatalf("failed to create latest copies. Cannot read from /dist") } - latestMapping := map[string]string { - ".deb": "dist/grafana_latest_amd64.deb", - ".rpm": "dist/grafana-latest-1.x86_64.rpm", + latestMapping := map[string]string{ + ".deb": "dist/grafana_latest_amd64.deb", + ".rpm": "dist/grafana-latest-1.x86_64.rpm", ".tar.gz": "dist/grafana-latest.linux-x64.tar.gz", } @@ -287,6 +287,14 @@ func createPackage(options linuxPackageOptions) { "-p", "./dist", } + if options.packageType == "rpm" { + args = append(args, "--rpm-posttrans", "packaging/rpm/control/posttrans") + } + + if options.packageType == "deb" { + args = append(args, "--deb-no-default-config-files") + } + if pkgArch != "" { args = append(args, "-a", pkgArch) } diff --git a/packaging/rpm/control/postinst b/packaging/rpm/control/postinst old mode 100644 new mode 100755 index be3d7692a5f..cf31112679d --- a/packaging/rpm/control/postinst +++ b/packaging/rpm/control/postinst @@ -68,13 +68,6 @@ if [ $1 -eq 1 ] ; then echo " sudo service grafana-server start" fi elif [ $1 -ge 2 ] ; then - if [ -x /opt/grafana/ ]; then - echo "### Upgrading Notice ### " - echo "-- New grafana install home is /usr/share/grafana" - echo "-- Please move sqlite3 database to /var/lib/grafana/" - echo "-- Notice: service name && binary changed to grafana-server" - fi - if [ "$RESTART_ON_UPGRADE" == "true" ]; then stopGrafana startGrafana diff --git a/packaging/rpm/control/posttrans b/packaging/rpm/control/posttrans new file mode 100755 index 00000000000..0afe4561a93 --- /dev/null +++ b/packaging/rpm/control/posttrans @@ -0,0 +1,32 @@ +#!/bin/sh + +set -e + +echo "POSTTRANS: Running script" + +[ -f /etc/sysconfig/grafana-server ] && . /etc/sysconfig/grafana-server + +# copy config files if missing +if [ ! -f /etc/grafana/grafana.ini ]; then + echo "POSTTRANS: Config file not found" + + if [ -f /etc/grafana/grafana.ini.rpmsave ]; then + echo "POSTTRANS: /etc/grafana/grafana.ini.rpmsave config file found." + mv /etc/grafana/grafana.ini.rpmsave /etc/grafana/grafana.ini + echo "POSTTRANS: /etc/grafana/grafana.ini restored" + + if [ -f /etc/grafana/ldap.toml.rpmsave ]; then + echo "POSTTRANS: /etc/grafana/ldap.toml.rpmsave found" + mv /etc/grafana/ldap.toml.rpmsave /etc/grafana/ldap.toml + echo "POSTTRANS: /etc/grafana/ldap.toml restored" + fi + + echo "POSTTRANS: Restoring config file permissions" + chown -Rh root:$GRAFANA_GROUP /etc/grafana/* + chmod 755 /etc/grafana + find /etc/grafana -type f -exec chmod 640 {} ';' + find /etc/grafana -type d -exec chmod 755 {} ';' + fi +fi + +