Fix dockerfile container image. (#2892)

master
Harshavardhana 8 years ago committed by GitHub
parent df59967f59
commit fdaa129a5b
  1. 6
      Dockerfile
  2. 83
      README.md
  3. 10
      cmd/main.go
  4. 54
      cmd/update-main.go
  5. 112
      cmd/update-main_nix_test.go
  6. 112
      cmd/update-main_windows_test.go
  7. 1
      docs/Docker.md

@ -1,19 +1,17 @@
FROM golang:1.7-alpine FROM golang:1.7-alpine
WORKDIR /go/src/app WORKDIR /go/src/app
ENV ALLOW_CONTAINER_ROOT=1
COPY . /go/src/app COPY . /go/src/app
RUN \ RUN \
apk add --no-cache git && \ apk add --no-cache git && \
go-wrapper download && \ go-wrapper download && \
go-wrapper install && \ go-wrapper install -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
mkdir -p /export/docker && \ mkdir -p /export/docker && \
cp /go/src/app/docs/Docker.md /export/docker/ && \ cp /go/src/app/docs/Docker.md /export/docker/ && \
rm -rf /go/pkg /go/src && \ rm -rf /go/pkg /go/src && \
apk del git apk del git
EXPOSE 9000 EXPOSE 9000
ENTRYPOINT ["go-wrapper", "run", "server"] ENTRYPOINT ["go-wrapper", "run"]
VOLUME ["/export"] VOLUME ["/export"]
CMD ["/export"]

@ -35,107 +35,47 @@ $ go get -u github.com/minio/minio
In the examples below, Minio serves the contents of the ``Photos`` directory as an object store. In the examples below, Minio serves the contents of the ``Photos`` directory as an object store.
### Docker Container ### Docker Container
```sh ```sh
$ docker pull minio/minio $ docker pull minio/minio
$ docker run -p 9000:9000 minio/minio ~/Photos $ docker run -p 9000:9000 minio/minio server /export
``` ```
Please visit Minio Docker quickstart guide for more [here](https://docs.minio.io/docs/minio-docker-quickstart-guide) Please visit Minio Docker quickstart guide for more [here](https://docs.minio.io/docs/minio-docker-quickstart-guide)
### GNU/Linux ### GNU/Linux
```sh ```sh
$ chmod +x minio $ chmod +x minio
$ ./minio --help $ ./minio --help
$ ./minio server ~/Photos $ ./minio server ~/Photos
...
Endpoint: http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
AccessKey: USWUXHGYZQYFYFFIT3RE
SecretKey: MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Region: us-east-1
Browser Access:
http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
$ mc config host add myminio http://10.0.0.10:9000 USWUXHGYZQYFYFFIT3RE MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Object API (Amazon S3 compatible):
Go: https://docs.minio.io/docs/golang-client-quickstart-guide
Java: https://docs.minio.io/docs/java-client-quickstart-guide
Python: https://docs.minio.io/docs/python-client-quickstart-guide
JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
``` ```
### OS X ### OS X
```sh ```sh
$ chmod 755 minio $ chmod 755 minio
$ ./minio --help $ ./minio --help
$ ./minio server ~/Photos $ ./minio server ~/Photos
...
Endpoint: http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
AccessKey: USWUXHGYZQYFYFFIT3RE
SecretKey: MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Region: us-east-1
Browser Access:
http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
$ mc config host add myminio http://10.0.0.10:9000 USWUXHGYZQYFYFFIT3RE MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Object API (Amazon S3 compatible):
Go: https://docs.minio.io/docs/golang-client-quickstart-guide
Java: https://docs.minio.io/docs/java-client-quickstart-guide
Python: https://docs.minio.io/docs/python-client-quickstart-guide
JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
``` ```
### Microsoft Windows ### Microsoft Windows
```sh ```sh
C:\Users\Username\Downloads> minio.exe --help C:\Users\Username\Downloads> minio.exe --help
C:\Users\Username\Downloads> minio.exe server D:\Photos C:\Users\Username\Downloads> minio.exe server D:\Photos
...
Endpoint: http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
AccessKey: USWUXHGYZQYFYFFIT3RE
SecretKey: MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Region: us-east-1
Browser Access:
http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
$ mc.exe config host add myminio http://10.0.0.10:9000 USWUXHGYZQYFYFFIT3RE MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Object API (Amazon S3 compatible):
Go: https://docs.minio.io/docs/golang-client-quickstart-guide
Java: https://docs.minio.io/docs/java-client-quickstart-guide
Python: https://docs.minio.io/docs/python-client-quickstart-guide
JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
``` ```
### FreeBSD ### FreeBSD
```sh ```sh
$ chmod 755 minio $ chmod 755 minio
$ ./minio --help $ ./minio --help
$ ./minio server ~/Photos $ ./minio server ~/Photos
...
Endpoint: http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
AccessKey: USWUXHGYZQYFYFFIT3RE
SecretKey: MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Region: us-east-1
Browser Access:
http://10.0.0.10:9000 http://127.0.0.1:9000 http://172.17.0.1:9000
Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
$ mc config host add myminio http://10.0.0.10:9000 USWUXHGYZQYFYFFIT3RE MOJRH0mkL1IPauahWITSVvyDrQbEEIwljvmxdq03
Object API (Amazon S3 compatible):
Go: https://docs.minio.io/docs/golang-client-quickstart-guide
Java: https://docs.minio.io/docs/java-client-quickstart-guide
Python: https://docs.minio.io/docs/python-client-quickstart-guide
JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
``` ```
Please visit official zfs FreeBSD guide for more details [here](https://www.freebsd.org/doc/handbook/zfs-quickstart.html) Please visit official zfs FreeBSD guide for more details [here](https://www.freebsd.org/doc/handbook/zfs-quickstart.html)
@ -164,6 +104,5 @@ For more examples please navigate to [Minio Client Complete Guide](https://docs.
- [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio) - [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio)
- [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide) - [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide)
## 6. Contribute to Minio Project ## 6. Contribute to Minio Project
Please follow Minio [Contributor's Guide](https://github.com/minio/minio/blob/master/CONTRIBUTING.md) Please follow Minio [Contributor's Guide](https://github.com/minio/minio/blob/master/CONTRIBUTING.md)

@ -22,6 +22,7 @@ import (
"os" "os"
"sort" "sort"
"strings" "strings"
"time"
"github.com/minio/cli" "github.com/minio/cli"
"github.com/minio/mc/pkg/console" "github.com/minio/mc/pkg/console"
@ -156,7 +157,6 @@ func checkMainSyntax(c *cli.Context) {
func Main() { func Main() {
app := registerApp() app := registerApp()
app.Before = func(c *cli.Context) error { app.Before = func(c *cli.Context) error {
configDir := c.GlobalString("config-dir") configDir := c.GlobalString("config-dir")
if configDir == "" { if configDir == "" {
fatalIf(errors.New("Config directory is empty"), "Unable to get config file.") fatalIf(errors.New("Config directory is empty"), "Unable to get config file.")
@ -185,11 +185,11 @@ func Main() {
// Do not print update messages, if quiet flag is set. // Do not print update messages, if quiet flag is set.
if !globalQuiet { if !globalQuiet {
if strings.HasPrefix(Version, "RELEASE.") { if strings.HasPrefix(ReleaseTag, "RELEASE.") && c.Args().Get(0) != "update" {
updateMsg, _, err := getReleaseUpdate(minioUpdateStableURL) updateMsg, _, err := getReleaseUpdate(minioUpdateStableURL, 1*time.Second)
if err != nil { if err != nil {
// Ignore any errors during getReleaseUpdate() because // Ignore any errors during getReleaseUpdate(), possibly
// the internet might not be available. // because of network errors.
return nil return nil
} }
console.Println(updateMsg) console.Println(updateMsg)

@ -17,10 +17,13 @@
package cmd package cmd
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -110,7 +113,8 @@ func parseReleaseData(data string) (time.Time, error) {
if releaseDateSplits[0] != "minio" { if releaseDateSplits[0] != "minio" {
return time.Time{}, (errors.New("Update data malformed, missing minio tag")) return time.Time{}, (errors.New("Update data malformed, missing minio tag"))
} }
// "OFFICIAL" tag is still kept for backward compatibility, we should remove this for the next release. // "OFFICIAL" tag is still kept for backward compatibility.
// We should remove this for the next release.
if releaseDateSplits[1] != "RELEASE" && releaseDateSplits[1] != "OFFICIAL" { if releaseDateSplits[1] != "RELEASE" && releaseDateSplits[1] != "OFFICIAL" {
return time.Time{}, (errors.New("Update data malformed, missing RELEASE tag")) return time.Time{}, (errors.New("Update data malformed, missing RELEASE tag"))
} }
@ -128,8 +132,28 @@ func parseReleaseData(data string) (time.Time, error) {
return parsedDate, nil return parsedDate, nil
} }
// User Agent should always following the below style.
// Please open an issue to discuss any new changes here.
//
// Minio (OS; ARCH) APP/VER APP/VER
var (
userAgentSuffix = "Minio/" + Version + " " + "Minio/" + ReleaseTag + " " + "Minio/" + CommitID
userAgentPrefix = "Minio (" + runtime.GOOS + "; " + runtime.GOARCH + ") "
userAgent = userAgentPrefix + userAgentSuffix
)
// Check if the operating system is a docker container.
func isDocker() bool {
cgroup, err := ioutil.ReadFile("/proc/self/cgroup")
if err != nil && os.IsNotExist(err) {
return false
}
fatalIf(err, "Unable to read `cgroup` file.")
return bytes.Contains(cgroup, []byte("docker"))
}
// verify updates for releases. // verify updates for releases.
func getReleaseUpdate(updateURL string) (updateMsg updateMessage, errMsg string, err error) { func getReleaseUpdate(updateURL string, duration time.Duration) (updateMsg updateMessage, errMsg string, err error) {
// Construct a new update url. // Construct a new update url.
newUpdateURLPrefix := updateURL + "/" + runtime.GOOS + "-" + runtime.GOARCH newUpdateURLPrefix := updateURL + "/" + runtime.GOOS + "-" + runtime.GOARCH
newUpdateURL := newUpdateURLPrefix + "/minio.shasum" newUpdateURL := newUpdateURLPrefix + "/minio.shasum"
@ -153,7 +177,7 @@ func getReleaseUpdate(updateURL string) (updateMsg updateMessage, errMsg string,
// Instantiate a new client with 3 sec timeout. // Instantiate a new client with 3 sec timeout.
client := &http.Client{ client := &http.Client{
Timeout: 3 * time.Second, Timeout: duration,
} }
// Parse current minio version into RFC3339. // Parse current minio version into RFC3339.
@ -170,23 +194,32 @@ func getReleaseUpdate(updateURL string) (updateMsg updateMessage, errMsg string,
return return
} }
// Initialize new request.
req, err := http.NewRequest("GET", newUpdateURL, nil)
if err != nil {
return
}
// Set user agent.
req.Header.Set("User-Agent", userAgent+" "+fmt.Sprintf("Docker/%t", isDocker()))
// Fetch new update. // Fetch new update.
data, err := client.Get(newUpdateURL) resp, err := client.Do(req)
if err != nil { if err != nil {
return return
} }
// Verify if we have a valid http response i.e http.StatusOK. // Verify if we have a valid http response i.e http.StatusOK.
if data != nil { if resp != nil {
if data.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
errMsg = "Failed to retrieve update notice." errMsg = "Failed to retrieve update notice."
err = errors.New("http status : " + data.Status) err = errors.New("http status : " + resp.Status)
return return
} }
} }
// Read the response body. // Read the response body.
updateBody, err := ioutil.ReadAll(data.Body) updateBody, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
errMsg = "Failed to retrieve update notice. Please try again later." errMsg = "Failed to retrieve update notice. Please try again later."
return return
@ -226,10 +259,11 @@ func mainUpdate(ctx *cli.Context) {
var updateMsg updateMessage var updateMsg updateMessage
var errMsg string var errMsg string
var err error var err error
var secs = time.Second * 3
if ctx.Bool("experimental") { if ctx.Bool("experimental") {
updateMsg, errMsg, err = getReleaseUpdate(minioUpdateExperimentalURL) updateMsg, errMsg, err = getReleaseUpdate(minioUpdateExperimentalURL, secs)
} else { } else {
updateMsg, errMsg, err = getReleaseUpdate(minioUpdateStableURL) updateMsg, errMsg, err = getReleaseUpdate(minioUpdateStableURL, secs)
} }
fatalIf(err, errMsg) fatalIf(err, errMsg)
console.Println(updateMsg) console.Println(updateMsg)

@ -0,0 +1,112 @@
// +build linux darwin dragonfly freebsd netbsd openbsd
/*
* Minio Cloud Storage, (C) 2016 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"runtime"
"testing"
"time"
)
// Validate when release versions are properly set.
func TestReleaseUpdateVersion(t *testing.T) {
Version = "2016-10-06T00:08:32Z"
ReleaseTag = "RELEASE.2016-10-06T00-08-32Z"
CommitID = "d1c38ba8f0b3aecdf9b932c087dd65c21eebac33"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z")
}))
userAgentSuffix = "Minio/" + Version + " " + "Minio/" + ReleaseTag + " " + "Minio/" + CommitID
userAgentPrefix = "Minio (" + runtime.GOOS + "; " + runtime.GOARCH + ") "
userAgent = userAgentPrefix + userAgentSuffix
defer ts.Close()
testCases := []struct {
updateURL string
updateMsg updateMessage
errMsg string
shouldPass bool
}{
{
updateURL: ts.URL,
updateMsg: updateMessage{
Download: ts.URL + "/" + runtime.GOOS + "-" + runtime.GOARCH + "/minio",
Version: "2016-10-06T00:08:32Z",
Update: true,
},
errMsg: "",
shouldPass: true,
},
}
// Validates all the errors reported.
for i, testCase := range testCases {
updateMsg, errMsg, err := getReleaseUpdate(testCase.updateURL, time.Second*1)
if testCase.shouldPass && err != nil {
t.Errorf("Test %d: Unable to fetch release update %s", i+1, err)
}
if errMsg != testCase.errMsg {
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.errMsg, errMsg)
}
if !reflect.DeepEqual(updateMsg, testCase.updateMsg) {
t.Errorf("Test %d: Expected %#v, got %#v", i+1, testCase.updateMsg, updateMsg)
}
}
}
func TestReleaseUpdate(t *testing.T) {
Version = "DEVELOPMENT.GOGET"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()
testCases := []struct {
updateURL string
updateMsg updateMessage
errMsg string
shouldPass bool
}{
{
updateURL: ts.URL,
updateMsg: updateMessage{
Download: ts.URL + "/" + runtime.GOOS + "-" + runtime.GOARCH + "/minio",
Version: "DEVELOPMENT.GOGET",
},
errMsg: "Unable to parse version string as time.",
shouldPass: false,
},
}
// Validates all the errors reported.
for i, testCase := range testCases {
updateMsg, errMsg, err := getReleaseUpdate(testCase.updateURL, time.Second*1)
if testCase.shouldPass && err != nil {
t.Errorf("Test %d: Unable to fetch release update %s", i+1, err)
}
if errMsg != testCase.errMsg {
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.errMsg, errMsg)
}
if !reflect.DeepEqual(updateMsg, testCase.updateMsg) {
t.Errorf("Test %d: Expected %#v, got %#v", i+1, testCase.updateMsg, updateMsg)
}
}
}

@ -0,0 +1,112 @@
// +build windows
/*
* Minio Cloud Storage, (C) 2016 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"runtime"
"testing"
"time"
)
// Validate when release versions are properly set.
func TestReleaseUpdateVersion(t *testing.T) {
Version = "2016-10-06T00:08:32Z"
ReleaseTag = "RELEASE.2016-10-06T00-08-32Z"
CommitID = "d1c38ba8f0b3aecdf9b932c087dd65c21eebac33"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "fbe246edbd382902db9a4035df7dce8cb441357d minio.RELEASE.2016-10-07T01-16-39Z")
}))
userAgentSuffix = "Minio/" + Version + " " + "Minio/" + ReleaseTag + " " + "Minio/" + CommitID
userAgentPrefix = "Minio (" + runtime.GOOS + "; " + runtime.GOARCH + ") "
userAgent = userAgentPrefix + userAgentSuffix
defer ts.Close()
testCases := []struct {
updateURL string
updateMsg updateMessage
errMsg string
shouldPass bool
}{
{
updateURL: ts.URL,
updateMsg: updateMessage{
Download: ts.URL + "/" + runtime.GOOS + "-" + runtime.GOARCH + "/minio.exe",
Version: "2016-10-06T00:08:32Z",
Update: true,
},
errMsg: "",
shouldPass: true,
},
}
// Validates all the errors reported.
for i, testCase := range testCases {
updateMsg, errMsg, err := getReleaseUpdate(testCase.updateURL, time.Second*1)
if testCase.shouldPass && err != nil {
t.Errorf("Test %d: Unable to fetch release update %s", i+1, err)
}
if errMsg != testCase.errMsg {
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.errMsg, errMsg)
}
if !reflect.DeepEqual(updateMsg, testCase.updateMsg) {
t.Errorf("Test %d: Expected %#v, got %#v", i+1, testCase.updateMsg, updateMsg)
}
}
}
func TestReleaseUpdate(t *testing.T) {
Version = "DEVELOPMENT.GOGET"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()
testCases := []struct {
updateURL string
updateMsg updateMessage
errMsg string
shouldPass bool
}{
{
updateURL: ts.URL,
updateMsg: updateMessage{
Download: ts.URL + "/" + runtime.GOOS + "-" + runtime.GOARCH + "/minio.exe",
Version: "DEVELOPMENT.GOGET",
},
errMsg: "Unable to parse version string as time.",
shouldPass: false,
},
}
// Validates all the errors reported.
for i, testCase := range testCases {
updateMsg, errMsg, err := getReleaseUpdate(testCase.updateURL, time.Second*1)
if testCase.shouldPass && err != nil {
t.Errorf("Test %d: Unable to fetch release update %s", i+1, err)
}
if errMsg != testCase.errMsg {
t.Errorf("Test %d: Expected %s, got %s", i+1, testCase.errMsg, errMsg)
}
if !reflect.DeepEqual(updateMsg, testCase.updateMsg) {
t.Errorf("Test %d: Expected %#v, got %#v", i+1, testCase.updateMsg, updateMsg)
}
}
}

@ -1,6 +1,5 @@
# Minio Docker Quickstart Guide [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/minio/minio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) # Minio Docker Quickstart Guide [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/minio/minio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## 1. Test Minio Docker Container ## 1. Test Minio Docker Container
Minio generates new access and secret keys each time you run this command. Container state is lost after you end this session. This mode is only intended for testing purpose. Minio generates new access and secret keys each time you run this command. Container state is lost after you end this session. This mode is only intended for testing purpose.

Loading…
Cancel
Save