Merge pull request #12707 from mikedanese/move-test-contrib

move contrib/for-tests to test/images
This commit is contained in:
Marek Grabowski
2015-08-17 10:46:18 +02:00
60 changed files with 21 additions and 13 deletions

View File

@@ -272,7 +272,7 @@ var _ = Describe("Volumes", func() {
ReadOnly: true,
},
}
// Must match content of contrib/for-tests/volumes-tester/nfs/index.html
// Must match content of test/images/volumes-tester/nfs/index.html
testVolumeClient(c, config, volume, "Hello from NFS!")
})
})
@@ -344,12 +344,12 @@ var _ = Describe("Volumes", func() {
volume := api.VolumeSource{
Glusterfs: &api.GlusterfsVolumeSource{
EndpointsName: config.prefix + "-server",
// 'test_vol' comes from contrib/for-tests/volumes-tester/gluster/run_gluster.sh
// 'test_vol' comes from test/images/volumes-tester/gluster/run_gluster.sh
Path: "test_vol",
ReadOnly: true,
},
}
// Must match content of contrib/for-tests/volumes-tester/gluster/index.html
// Must match content of test/images/volumes-tester/gluster/index.html
testVolumeClient(c, config, volume, "Hello from GlusterFS!")
})
})
@@ -389,14 +389,14 @@ var _ = Describe("Volumes", func() {
volume := api.VolumeSource{
ISCSI: &api.ISCSIVolumeSource{
TargetPortal: serverIP + ":3260",
// from contrib/for-tests/volumes-tester/iscsi/initiatorname.iscsi
// from test/images/volumes-tester/iscsi/initiatorname.iscsi
IQN: "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c",
Lun: 0,
FSType: "ext2",
ReadOnly: true,
},
}
// Must match content of contrib/for-tests/volumes-tester/iscsi/block.tar.gz
// Must match content of test/images/volumes-tester/iscsi/block.tar.gz
testVolumeClient(c, config, volume, "Hello from iSCSI")
})
})
@@ -443,7 +443,7 @@ var _ = Describe("Volumes", func() {
Name: config.prefix + "-secret",
},
Data: map[string][]byte{
// from contrib/for-tests/volumes-tester/rbd/keyring
// from test/images/volumes-tester/rbd/keyring
"key": []byte("AQDRrKNVbEevChAAEmRC+pW/KBVHxa0w/POILA=="),
},
}
@@ -473,7 +473,7 @@ var _ = Describe("Volumes", func() {
ReadOnly: true,
},
}
// Must match content of contrib/for-tests/volumes-tester/gluster/index.html
// Must match content of test/images/volumes-tester/gluster/index.html
testVolumeClient(c, config, volume, "Hello from RBD")
})

View File

@@ -0,0 +1,6 @@
FROM debian:wheezy
MAINTAINER Tim Hockin "thockin@google.com"
RUN apt-get -q update && \
apt-get install -y dnsutils && \
apt-get clean

View File

@@ -0,0 +1,8 @@
all:
@echo "try 'make image' or 'make push'"
image:
docker build -t gcr.io/google_containers/dnsutils .
push:
gcloud docker push gcr.io/google_containers/dnsutils

View File

@@ -0,0 +1,20 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM scratch
ADD ep ep
ADD ep ep-2
EXPOSE 8080
ENTRYPOINT ["/ep"]
CMD ["default", "arguments"]

View File

@@ -0,0 +1,15 @@
all: push
TAG = 0.1
ep: ep.go
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./ep.go
image: ep
sudo docker build -t kubernetes/eptest:$(TAG) .
push: image
sudo docker push kubernetes/eptest:$(TAG)
clean:
rm -f ep

View File

@@ -0,0 +1,29 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"fmt"
"os"
)
// This program prints the arguments it's passed and exits.
func main() {
args := os.Args
fmt.Printf("%v\n", args)
os.Exit(0)
}

View File

@@ -0,0 +1,6 @@
FROM debian:jessie
MAINTAINER Abhishek Shah "abshah@google.com"
RUN apt-get -q update && \
apt-get install -y dnsutils && \
apt-get clean

View File

@@ -0,0 +1,8 @@
all:
@echo "try 'make image' or 'make push'"
image:
docker build -t gcr.io/google_containers/jessie-dnsutils .
push:
gcloud docker push gcr.io/google_containers/jessie-dnsutils

View File

@@ -0,0 +1,16 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM gcr.io/google-containers/mounttest:0.3
USER 1001

View File

@@ -0,0 +1,9 @@
all: push
TAG = 0.1
image:
sudo docker build -t gcr.io/google_containers/mounttest-user:$(TAG) .
push: image
gcloud docker push gcr.io/google_containers/mounttest-user:$(TAG)

View File

@@ -0,0 +1,17 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM scratch
ADD mt mt
ENTRYPOINT ["/mt"]

View File

@@ -0,0 +1,15 @@
all: push
TAG = 0.3
mt: mt.go
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./mt.go
image: mt
sudo docker build -t gcr.io/google_containers/mounttest:$(TAG) .
push: image
gcloud docker push gcr.io/google_containers/mounttest:$(TAG)
clean:
rm -f mt

View File

@@ -0,0 +1,193 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"syscall"
)
var (
fsTypePath = ""
fileModePath = ""
filePermPath = ""
readFileContentPath = ""
newFilePath0644 = ""
newFilePath0666 = ""
newFilePath0777 = ""
)
func init() {
flag.StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for")
flag.StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of")
flag.StringVar(&filePermPath, "file_perm", "", "Path to print the perms of")
flag.StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from")
flag.StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644")
flag.StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666")
flag.StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777")
}
// This program performs some tests on the filesystem as dictated by the
// flags passed by the user.
func main() {
flag.Parse()
var (
err error
errs = []error{}
)
// Clear the umask so we can set any mode bits we want.
syscall.Umask(0000)
// NOTE: the ordering of execution of the various command line
// flags is intentional and allows a single command to:
//
// 1. Check the fstype of a path
// 2. Write a new file within that path
// 3. Check that the file's content can be read
//
// Changing the ordering of the following code will break tests.
err = fsType(fsTypePath)
if err != nil {
errs = append(errs, err)
}
err = readWriteNewFile(newFilePath0644, 0644)
if err != nil {
errs = append(errs, err)
}
err = readWriteNewFile(newFilePath0666, 0666)
if err != nil {
errs = append(errs, err)
}
err = readWriteNewFile(newFilePath0777, 0777)
if err != nil {
errs = append(errs, err)
}
err = fileMode(fileModePath)
if err != nil {
errs = append(errs, err)
}
err = filePerm(filePermPath)
if err != nil {
errs = append(errs, err)
}
err = readFileContent(readFileContentPath)
if err != nil {
errs = append(errs, err)
}
if len(errs) != 0 {
os.Exit(1)
}
os.Exit(0)
}
// Defined by Linux (sys/statfs.h) - the type number for tmpfs mounts.
const linuxTmpfsMagic = 0x01021994
func fsType(path string) error {
if path == "" {
return nil
}
buf := syscall.Statfs_t{}
if err := syscall.Statfs(path, &buf); err != nil {
fmt.Printf("error from statfs(%q): %v\n", path, err)
return err
}
if buf.Type == linuxTmpfsMagic {
fmt.Printf("mount type of %q: tmpfs\n", path)
} else {
fmt.Printf("mount type of %q: %v\n", path, buf.Type)
}
return nil
}
func fileMode(path string) error {
if path == "" {
return nil
}
fileinfo, err := os.Lstat(path)
if err != nil {
fmt.Printf("error from Lstat(%q): %v\n", path, err)
return err
}
fmt.Printf("mode of file %q: %v\n", path, fileinfo.Mode())
return nil
}
func filePerm(path string) error {
if path == "" {
return nil
}
fileinfo, err := os.Lstat(path)
if err != nil {
fmt.Printf("error from Lstat(%q): %v\n", path, err)
return err
}
fmt.Printf("perms of file %q: %v\n", path, fileinfo.Mode().Perm())
return nil
}
func readFileContent(path string) error {
if path == "" {
return nil
}
contentBytes, err := ioutil.ReadFile(path)
if err != nil {
fmt.Printf("error reading file content for %q: %v\n", path, err)
return err
}
fmt.Printf("content of file %q: %v\n", path, string(contentBytes))
return nil
}
func readWriteNewFile(path string, perm os.FileMode) error {
if path == "" {
return nil
}
content := "mount-tester new file\n"
err := ioutil.WriteFile(path, []byte(content), perm)
if err != nil {
fmt.Printf("error writing new file %q: %v\n", path, err)
return err
}
return readFileContent(path)
}

View File

@@ -0,0 +1,19 @@
# Copyright 2014 Google Inc. All rights reserved.
#
# 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.
FROM scratch
MAINTAINER Daniel Smith <dbsmith@google.com>
ADD webserver webserver
EXPOSE 8080
ENTRYPOINT ["/webserver"]

View File

@@ -0,0 +1,16 @@
all: push
# Set this to the *next* version to prevent accidentally overwriting the existing image.
TAG = 1.6
webserver: webserver.go
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./webserver.go
container: webserver
docker build -t gcr.io/google_containers/nettest:$(TAG) .
push: container
gcloud docker push gcr.io/google_containers/nettest:$(TAG)
clean:
rm -f webserver

View File

@@ -0,0 +1,44 @@
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": {
"name": "nettest-controller",
"labels": {
"name": "nettest"
}
},
"spec": {
"replicas": 2,
"selector": {
"name": "nettest"
},
"template": {
"metadata": {
"labels": {
"name": "nettest"
}
},
"spec": {
"containers": [
{
"name": "webserver",
"image": "gcr.io/google_containers/nettest:1.6",
"imagePullPolicy": "Always",
"args": [
"-service=nettest",
"-port=8080",
"-namespace=default",
"-peers=2"
],
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
]
}
]
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "nettest",
"labels": {
"name": "nettest"
}
},
"spec": {
"ports": [
{
"port": 8080,
"protocol": "TCP",
"targetPort": 8080
}
],
"selector": {
"name": "nettest"
}
}
}

View File

@@ -0,0 +1,269 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
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.
*/
// A tiny web server for checking networking connectivity.
//
// Will dial out to, and expect to hear from, every pod that is a member of
// the service passed in the flag -service.
//
// Will serve a webserver on given -port.
//
// Visit /read to see the current state, or /quit to shut down.
//
// Visit /status to see pass/running/fail determination. (literally, it will
// return one of those words.)
//
// /write is used by other network test pods to register connectivity.
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"math/rand"
"net/http"
"os"
"sync"
"time"
"k8s.io/kubernetes/pkg/client"
"k8s.io/kubernetes/pkg/util"
)
var (
port = flag.Int("port", 8080, "Port number to serve at.")
peerCount = flag.Int("peers", 8, "Must find at least this many peers for the test to pass.")
service = flag.String("service", "nettest", "Service to find other network test pods in.")
namespace = flag.String("namespace", "default", "Namespace of this pod. TODO: kubernetes should make this discoverable.")
)
// State tracks the internal state of our little http server.
// It's returned verbatim over the /read endpoint.
type State struct {
// Hostname is set once and never changed-- it's always safe to read.
Hostname string
// The below fields require that lock is held before reading or writing.
Sent map[string]int
Received map[string]int
Errors []string
Log []string
StillContactingPeers bool
lock sync.Mutex
}
func (s *State) doneContactingPeers() {
s.lock.Lock()
defer s.lock.Unlock()
s.StillContactingPeers = false
}
// serveStatus returns "pass", "running", or "fail".
func (s *State) serveStatus(w http.ResponseWriter, r *http.Request) {
s.lock.Lock()
defer s.lock.Unlock()
if len(s.Sent) >= *peerCount && len(s.Received) >= *peerCount {
fmt.Fprintf(w, "pass")
return
}
if s.StillContactingPeers {
fmt.Fprintf(w, "running")
return
}
s.Logf("Declaring failure for %s/%s with %d sent and %d received and %d peers", *namespace, *service, len(s.Sent), len(s.Received), *peerCount)
fmt.Fprintf(w, "fail")
}
// serveRead writes our json encoded state
func (s *State) serveRead(w http.ResponseWriter, r *http.Request) {
s.lock.Lock()
defer s.lock.Unlock()
w.WriteHeader(http.StatusOK)
b, err := json.MarshalIndent(s, "", "\t")
s.appendErr(err)
_, err = w.Write(b)
s.appendErr(err)
}
// WritePost is the format that (json encoded) requests to the /write handler should take.
type WritePost struct {
Source string
Dest string
}
// WriteResp is returned by /write
type WriteResp struct {
Hostname string
}
// serveWrite records the contact in our state.
func (s *State) serveWrite(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
s.lock.Lock()
defer s.lock.Unlock()
w.WriteHeader(http.StatusOK)
var wp WritePost
s.appendErr(json.NewDecoder(r.Body).Decode(&wp))
if wp.Source == "" {
s.appendErr(fmt.Errorf("%v: Got request with no source", s.Hostname))
} else {
if s.Received == nil {
s.Received = map[string]int{}
}
s.Received[wp.Source] += 1
}
s.appendErr(json.NewEncoder(w).Encode(&WriteResp{Hostname: s.Hostname}))
}
// appendErr adds err to the list, if err is not nil. s must be locked.
func (s *State) appendErr(err error) {
if err != nil {
s.Errors = append(s.Errors, err.Error())
}
}
// Logf writes to the log message list. s must not be locked.
// s's Log member will drop an old message if it would otherwise
// become longer than 500 messages.
func (s *State) Logf(format string, args ...interface{}) {
s.lock.Lock()
defer s.lock.Unlock()
s.Log = append(s.Log, fmt.Sprintf(format, args...))
if len(s.Log) > 500 {
s.Log = s.Log[1:]
}
}
// s must not be locked
func (s *State) appendSuccessfulSend(toHostname string) {
s.lock.Lock()
defer s.lock.Unlock()
if s.Sent == nil {
s.Sent = map[string]int{}
}
s.Sent[toHostname] += 1
}
var (
// Our one and only state object
state State
)
func main() {
flag.Parse()
if *service == "" {
log.Fatal("Must provide -service flag.")
}
hostname, err := os.Hostname()
if err != nil {
log.Fatalf("Error getting hostname: %v", err)
}
state := State{
Hostname: hostname,
StillContactingPeers: true,
}
go contactOthers(&state)
http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
os.Exit(0)
})
http.HandleFunc("/read", state.serveRead)
http.HandleFunc("/write", state.serveWrite)
http.HandleFunc("/status", state.serveStatus)
go log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", *port), nil))
select {}
}
// Find all sibling pods in the service and post to their /write handler.
func contactOthers(state *State) {
defer state.doneContactingPeers()
client, err := client.NewInCluster()
if err != nil {
log.Fatalf("Unable to create client; error: %v\n", err)
}
// Double check that that worked by getting the server version.
if v, err := client.ServerVersion(); err != nil {
log.Fatalf("Unable to get server version: %v\n", err)
} else {
log.Printf("Server version: %#v\n", v)
}
// Do this repeatedly, in case there's some propagation delay with getting
// newly started pods into the endpoints list.
for i := 0; i < 15; i++ {
endpoints, err := client.Endpoints(*namespace).Get(*service)
if err != nil {
state.Logf("Unable to read the endpoints for %v/%v: %v; will try again.", *namespace, *service, err)
time.Sleep(time.Duration(1+rand.Intn(10)) * time.Second)
}
eps := util.StringSet{}
for _, ss := range endpoints.Subsets {
for _, a := range ss.Addresses {
for _, p := range ss.Ports {
eps.Insert(fmt.Sprintf("http://%s:%d", a.IP, p.Port))
}
}
}
for ep := range eps {
state.Logf("Attempting to contact %s", ep)
contactSingle(ep, state)
}
time.Sleep(5 * time.Second)
}
}
// contactSingle dials the address 'e' and tries to POST to its /write address.
func contactSingle(e string, state *State) {
body, err := json.Marshal(&WritePost{
Dest: e,
Source: state.Hostname,
})
if err != nil {
log.Fatalf("json marshal error: %v", err)
}
resp, err := http.Post(e+"/write", "application/json", bytes.NewReader(body))
if err != nil {
state.Logf("Warning: unable to contact the endpoint %q: %v", e, err)
return
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
state.Logf("Warning: unable to read response from '%v': '%v'", e, err)
return
}
var wr WriteResp
err = json.Unmarshal(body, &wr)
if err != nil {
state.Logf("Warning: unable to unmarshal response (%v) from '%v': '%v'", string(body), e, err)
return
}
state.appendSuccessfulSend(wr.Hostname)
}

2
test/images/porter/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
porter
.tag

View File

@@ -0,0 +1,18 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM scratch
MAINTAINER Daniel Smith <dbsmith@google.com>
ADD porter porter
ENTRYPOINT ["/porter"]

View File

@@ -0,0 +1,32 @@
# Use:
#
# `make porter` will build porter.
# `make tag` will suggest a tag.
# `make container` will build a container-- you must supply a tag.
# `make push` will push the container-- you must supply a tag.
REPO ?= gcr.io/google_containers
porter: porter.go
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' ./porter.go
.tag: porter
md5sum porter | cut -d " " -f 1 > .tag
tag: .tag
@echo "Suggest using TAG=$(shell cat .tag)"
@echo "$$ make container TAG=$(shell cat .tag)"
@echo "or"
@echo "$$ make push TAG=$(shell cat .tag)"
container:
$(if $(TAG),,$(error TAG is not defined. Use 'make tag' to see a suggestion))
docker build -t $(REPO)/porter:$(TAG) .
push:
$(if $(TAG),,$(error TAG is not defined. Use 'make tag' to see a suggestion))
gcloud docker push $(REPO)/porter:$(TAG)
clean:
rm -f porter
rm -f .tag

View File

@@ -0,0 +1,5 @@
This directory contains go source, Dockerfile and Makefile for making a test
container which serves requested data on ports specified in ENV variables.
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/porter/README.md?pixel)]()

View File

@@ -0,0 +1,35 @@
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "porter"
},
"spec": {
"containers": [
{
"name": "porter",
"image": "gcr.io/google_containers/porter:59ad46ed2c56ba50fa7f1dc176c07c37",
"env": [
{
"name": "SERVE_PORT_80",
"value": "foo"
},
{
"name": "SERVE_PORT_81",
"value": "<html><head></head><body><a href=\"/rewriteme\">rewritten link</a></body></html>"
}
],
"ports": [
{
"name": "p80",
"containerPort": 80
},
{
"name": "p81",
"containerPort": 81
}
]
}
]
}
}

View File

@@ -0,0 +1,59 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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.
*/
// A tiny binary for testing ports.
//
// Reads env vars; for every var of the form SERVE_PORT_X, where X is a valid
// port number, porter starts an HTTP server which serves the env var's value
// in response to any query.
package main
import (
"fmt"
"log"
"net/http"
"os"
"strings"
)
const prefix = "SERVE_PORT_"
func main() {
for _, vk := range os.Environ() {
// Put everything before the first = sign in parts[0], and
// everything else in parts[1] (even if there are multiple =
// characters).
parts := strings.SplitN(vk, "=", 2)
key := parts[0]
value := parts[1]
if strings.HasPrefix(key, prefix) {
port := strings.TrimPrefix(key, prefix)
go servePort(port, value)
}
}
select {}
}
func servePort(port, value string) {
s := &http.Server{
Addr: "0.0.0.0:" + port,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, value)
}),
}
log.Printf("server on port %q failed: %v", port, s.ListenAndServe())
}

View File

@@ -0,0 +1,6 @@
FROM scratch
MAINTAINER Ewa Socala <socaa@google.com>
ADD consumer /consumer
ADD consume-cpu /consume-cpu
EXPOSE 8080
ENTRYPOINT ["/consumer"]

View File

@@ -0,0 +1,17 @@
all: clean consumer
TAG = alpha
consumer:
CGO_ENABLED=0 godep go build -a -installsuffix cgo --ldflags '-w' -o consume-cpu/consume-cpu ./consume-cpu/consume_cpu.go
CGO_ENABLED=0 godep go build -a -installsuffix cgo --ldflags '-w' -o consumer .
container:
sudo docker build -t gcr.io/google_containers/resource_consumer:$(TAG) .
run_container:
docker run --publish=8080:8080 gcr.io/google_containers/resource_consumer:$(TAG)
clean:
rm -f consumer
rm -f consume-cpu/consume-cpu

View File

@@ -0,0 +1,56 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"flag"
"math"
"time"
"bitbucket.org/bertimus9/systemstat"
)
const sleep = time.Duration(10) * time.Millisecond
func doSomething() {
for i := 1; i < 10000000; i++ {
x := float64(0)
x += math.Sqrt(0)
}
}
var (
milicores = flag.Int("milicores", 0, "milicores number")
durationSec = flag.Int("duration-sec", 0, "duration time in seconds")
)
func main() {
flag.Parse()
// converte milicores to percentage
milicoresPct := float64(*milicores) / float64(10)
duration := time.Duration(*durationSec) * time.Second
start := time.Now()
first := systemstat.GetProcCPUSample()
for time.Now().Sub(start) < duration {
cpu := systemstat.GetProcCPUAverage(first, systemstat.GetProcCPUSample(), systemstat.GetUptime().Uptime)
if cpu.TotalPct < milicoresPct {
doSomething()
} else {
time.Sleep(sleep)
}
}
}

View File

@@ -0,0 +1,32 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"flag"
"fmt"
"log"
"net/http"
)
var port = flag.Int("port", 8080, "Port number.")
func main() {
flag.Parse()
var resourceConsumerHandler ResourceConsumerHandler
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), resourceConsumerHandler))
}

View File

@@ -0,0 +1,119 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"fmt"
"net/http"
"net/url"
"strconv"
)
const (
badRequest = "Bad request. Not a POST request"
unknownFunction = "unknown function"
incorrectFunctionArgument = "incorrect function argument"
notGivenFunctionArgument = "not given function argument"
consumeCPUAddress = "/ConsumeCPU"
consumeMemAddress = "/ConsumeMem"
getCurrentStatusAddress = "/GetCurrentStatus"
milicoresQuery = "milicores"
megabytesQuery = "megabytes"
durationSecQuery = "durationSec"
)
type ResourceConsumerHandler struct{}
func (handler ResourceConsumerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
http.Error(w, badRequest, http.StatusBadRequest)
}
// parsing POST request data and URL data
if err := req.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// handle consumeCPU
if req.URL.Path == consumeCPUAddress {
handler.handleConsumeCPU(w, req.PostForm)
return
}
// handle consumeMem
if req.URL.Path == consumeMemAddress {
handler.handleConsumeMem(w, req.PostForm)
return
}
// handle getCurrentStatus
if req.URL.Path == getCurrentStatusAddress {
handler.handleGetCurrentStatus(w)
return
}
http.Error(w, unknownFunction, http.StatusNotFound)
}
func (handler ResourceConsumerHandler) handleConsumeCPU(w http.ResponseWriter, query url.Values) {
// geting string data for consumeCPU
durationSecString := query.Get(durationSecQuery)
milicoresString := query.Get(milicoresQuery)
if durationSecString == "" || milicoresString == "" {
http.Error(w, notGivenFunctionArgument, http.StatusBadRequest)
return
} else {
// convert data (strings to ints) for consumeCPU
durationSec, durationSecError := strconv.Atoi(durationSecString)
milicores, milicoresError := strconv.Atoi(milicoresString)
if durationSecError != nil || milicoresError != nil {
http.Error(w, incorrectFunctionArgument, http.StatusBadRequest)
return
}
go ConsumeCPU(milicores, durationSec)
fmt.Fprintln(w, consumeCPUAddress[1:])
fmt.Fprintln(w, milicores, milicoresQuery)
fmt.Fprintln(w, durationSec, durationSecQuery)
}
}
func (handler ResourceConsumerHandler) handleConsumeMem(w http.ResponseWriter, query url.Values) {
// geting string data for consumeMem
durationSecString := query.Get(durationSecQuery)
megabytesString := query.Get(megabytesQuery)
if durationSecString == "" || megabytesString == "" {
http.Error(w, notGivenFunctionArgument, http.StatusBadRequest)
return
} else {
// convert data (strings to ints) for consumeMem
durationSec, durationSecError := strconv.Atoi(durationSecString)
megabytes, megabytesError := strconv.Atoi(megabytesString)
if durationSecError != nil || megabytesError != nil {
http.Error(w, incorrectFunctionArgument, http.StatusBadRequest)
return
}
ConsumeMem(megabytes, durationSec)
fmt.Fprintln(w, "Warning: not implemented!")
fmt.Fprintln(w, consumeMemAddress[1:])
fmt.Fprintln(w, megabytes, megabytesQuery)
fmt.Fprintln(w, durationSec, durationSecQuery)
}
}
func (handler ResourceConsumerHandler) handleGetCurrentStatus(w http.ResponseWriter) {
GetCurrentStatus()
fmt.Fprintln(w, "Warning: not implemented!")
fmt.Fprint(w, getCurrentStatusAddress[1:])
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 main
import (
"fmt"
"log"
"os/exec"
)
const consumeCPUBinary = "./consume-cpu/consume-cpu"
func ConsumeCPU(milicores int, durationSec int) {
log.Printf("ConsumeCPU milicores: %v, durationSec: %v", milicores, durationSec)
// creating new consume cpu process
arg1 := fmt.Sprintf("-milicores=%d", milicores)
arg2 := fmt.Sprintf("-duration-sec=%d", durationSec)
consumeCPU := exec.Command(consumeCPUBinary, arg1, arg2)
consumeCPU.Start()
}
func ConsumeMem(megabytes int, durationSec int) {
log.Printf("ConsumeMem megabytes: %v, durationSec: %v", megabytes, durationSec)
// not implemented
}
func GetCurrentStatus() {
log.Printf("GetCurrentStatus")
// not implemented
}

View File

@@ -0,0 +1,26 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM ubuntu:14.04
MAINTAINER Jan Safranek, jsafrane@redhat.com
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -qq && apt-get install -y glusterfs-server -qq
ADD glusterd.vol /etc/glusterfs/
ADD run_gluster.sh /usr/local/bin/
ADD index.html /vol/
RUN chmod 644 /vol/index.html
EXPOSE 24007/tcp 24008/tcp 49152/tcp
ENTRYPOINT ["/usr/local/bin/run_gluster.sh"]

View File

@@ -0,0 +1,13 @@
all: push
TAG = 0.1
container:
docker build -t gcr.io/google_containers/volume-gluster . # Build new image and automatically tag it as latest
docker tag gcr.io/google_containers/volume-gluster gcr.io/google_containers/volume-gluster:$(TAG) # Add the version tag to the latest image
push: container
gcloud docker push gcr.io/google_containers/volume-gluster # Push image tagged as latest to repository
gcloud docker push gcr.io/google_containers/volume-gluster:$(TAG) # Push version tagged image to repository (since this image is already pushed it will simply create or update version tag)
clean:

View File

@@ -0,0 +1,8 @@
# Gluster server container for testing
This container exports test_vol volume with an index.html inside.
Used by test/e2e/* to test GlusterfsVolumeSource. Not for production use!
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/volumes-tester/gluster/README.md?pixel)]()

View File

@@ -0,0 +1,14 @@
# This is default glusterd.vol (incl. commented out base-port),
# with added "rpc-auth-allow-insecure on" to allow connection
# from non-privileged ports.
volume management
type mgmt/glusterd
option working-directory /var/lib/glusterd
option transport-type socket,rdma
option transport.socket.keepalive-time 10
option transport.socket.keepalive-interval 2
option transport.socket.read-fail-log off
# option base-port 49152
option rpc-auth-allow-insecure on
end-volume

View File

@@ -0,0 +1 @@
Hello from GlusterFS!

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
function start()
{
/usr/sbin/glusterd -p /run/glusterd.pid
gluster volume create test_vol `hostname -i`:/vol force
gluster volume start test_vol
}
function stop()
{
gluster --mode=script volume stop test_vol force
kill $(cat /run/glusterd.pid)
exit 0
}
trap stop TERM
start "$@"
while true; do
read
done

View File

@@ -0,0 +1,33 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM fedora
MAINTAINER Jan Safranek, jsafrane@redhat.com
RUN yum install -y iscsi-initiator-utils targetcli net-tools strace && yum clean all
ADD run_iscsid.sh /usr/local/bin/
ADD initiatorname.iscsi /etc/iscsi/
ADD block.tar.gz /
# This JSON file was generated by targetcli with these commands:
# /backstores/fileio create block /block
# /iscsi create
# # Enable demo mode (no authentication!):
# /iscsi/iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c/tpg1 set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1
# /iscsi/iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c/tpg1/luns create /backstores/fileio/block
# saveconfig
ADD saveconfig.json /etc/target/
EXPOSE 3260/tcp
ENTRYPOINT ["/usr/local/bin/run_iscsid.sh"]

View File

@@ -0,0 +1,22 @@
all: push
TAG = 0.1
container:
# Build new image and automatically tag it as latest
docker build -t gcr.io/google_containers/volume-iscsi .
# Add the version tag to the latest image
docker tag gcr.io/google_containers/volume-iscsi gcr.io/google_containers/volume-iscsi:$(TAG)
block:
# Create block.tar.gz with ext2 block device with index.html inside.
# block.tar.gz is already available in git and users don't need to
# regenerate it, this target is here just for reference.
# Run as root!
./create_block.sh
push: container
# Push image tagged as latest to repository
gcloud docker push gcr.io/google_containers/volume-iscsi
# Push version tagged image to repository (since this image is already pushed it will simply create or update version tag)
gcloud docker push gcr.io/google_containers/volume-iscsi:$(TAG)

View File

@@ -0,0 +1,14 @@
# iSCSI target container for testing.
Inspired by https://github.com/rvykydal/dockerfile-iscsid
* The container needs /lib/modules from the host to insert appropriate
kernel modules for iscsi. This assumes that these modules are installed
on the host!
* The container needs to run with docker --privileged
block.tar.gz is a small ext2 filesystem created by `make block` (run as root!)
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/volumes-tester/iscsi/README.md?pixel)]()

Binary file not shown.

View File

@@ -0,0 +1,46 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
# Exit on the first error.
set -e
MNTDIR=`mktemp -d`
cleanup()
{
# Make sure we return the right exit code
RET=$?
# Silently remove everything and ignore errors
set +e
/bin/umount $MNTDIR 2>/dev/null
/bin/rmdir $MNTDIR 2>/dev/null
/bin/rm block 2>/dev/null
exit $RET
}
trap cleanup TERM EXIT
# Create 1MB device with ext2
dd if=/dev/zero of=block count=1 bs=1M
mkfs.ext2 block
# Add index.html to it
mount -o loop block $MNTDIR
echo "Hello from iSCSI" > $MNTDIR/index.html
umount $MNTDIR
rm block.tar.gz 2>/dev/null || :
tar cfz block.tar.gz block

View File

@@ -0,0 +1 @@
InitiatorName=iqn.1994-05.com.redhat:eb59fbe2c4c5

View File

@@ -0,0 +1,41 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
function start()
{
targetcli restoreconfig
iscsid
echo "iscsid started"
}
function stop()
{
echo "Stopping iscsid"
kill $( cat /var/run/iscsid.pid )
targetcli clearconfig confirm=True
echo "iscsid stopped"
exit 0
}
trap stop TERM
start
while true; do
sleep 5
done

View File

@@ -0,0 +1,102 @@
{
"fabric_modules": [],
"storage_objects": [
{
"attributes": {
"block_size": 512,
"emulate_3pc": 1,
"emulate_caw": 1,
"emulate_dpo": 0,
"emulate_fua_read": 0,
"emulate_fua_write": 1,
"emulate_model_alias": 1,
"emulate_rest_reord": 0,
"emulate_tas": 1,
"emulate_tpu": 0,
"emulate_tpws": 0,
"emulate_ua_intlck_ctrl": 0,
"emulate_write_cache": 1,
"enforce_pr_isids": 1,
"force_pr_aptpl": 0,
"is_nonrot": 0,
"max_unmap_block_desc_count": 1,
"max_unmap_lba_count": 8192,
"max_write_same_len": 4096,
"optimal_sectors": 16384,
"pi_prot_format": 0,
"pi_prot_type": 0,
"queue_depth": 128,
"unmap_granularity": 1,
"unmap_granularity_alignment": 0
},
"dev": "block",
"name": "block",
"plugin": "fileio",
"size": 1048576,
"write_back": true,
"wwn": "521c57aa-9d9b-4e5d-ab1a-527487f92a33"
}
],
"targets": [
{
"fabric": "iscsi",
"tpgs": [
{
"attributes": {
"authentication": 0,
"cache_dynamic_acls": 1,
"default_cmdsn_depth": 64,
"default_erl": 0,
"demo_mode_discovery": 1,
"demo_mode_write_protect": 0,
"generate_node_acls": 1,
"login_timeout": 15,
"netif_timeout": 2,
"prod_mode_write_protect": 0,
"t10_pi": 0
},
"enable": true,
"luns": [
{
"index": 0,
"storage_object": "/backstores/fileio/block"
}
],
"node_acls": [],
"parameters": {
"AuthMethod": "CHAP,None",
"DataDigest": "CRC32C,None",
"DataPDUInOrder": "Yes",
"DataSequenceInOrder": "Yes",
"DefaultTime2Retain": "20",
"DefaultTime2Wait": "2",
"ErrorRecoveryLevel": "0",
"FirstBurstLength": "65536",
"HeaderDigest": "CRC32C,None",
"IFMarkInt": "2048~65535",
"IFMarker": "No",
"ImmediateData": "Yes",
"InitialR2T": "Yes",
"MaxBurstLength": "262144",
"MaxConnections": "1",
"MaxOutstandingR2T": "1",
"MaxRecvDataSegmentLength": "8192",
"MaxXmitDataSegmentLength": "262144",
"OFMarkInt": "2048~65535",
"OFMarker": "No",
"TargetAlias": "LIO Target"
},
"portals": [
{
"ip_address": "0.0.0.0",
"iser": false,
"port": 3260
}
],
"tag": 1
}
],
"wwn": "iqn.2003-01.org.linux-iscsi.f21.x8664:sn.4b0aae584f7c"
}
]
}

View File

@@ -0,0 +1,26 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
FROM ubuntu:14.04
MAINTAINER Jan Safranek, jsafrane@redhat.com
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -qq && apt-get install -y nfs-kernel-server -qq
RUN mkdir -p /exports
ADD run_nfs.sh /usr/local/bin/
ADD index.html /exports/index.html
RUN chmod 644 /exports/index.html
EXPOSE 2049/tcp
ENTRYPOINT ["/usr/local/bin/run_nfs.sh", "/exports"]

View File

@@ -0,0 +1,13 @@
all: push
TAG = 0.2
container:
docker build -t gcr.io/google_containers/volume-nfs . # Build new image and automatically tag it as latest
docker tag gcr.io/google_containers/volume-nfs gcr.io/google_containers/volume-nfs:$(TAG) # Add the version tag to the latest image
push: container
gcloud docker push gcr.io/google_containers/volume-nfs # Push image tagged as latest to repository
gcloud docker push gcr.io/google_containers/volume-nfs:$(TAG) # Push version tagged image to repository (since this image is already pushed it will simply create or update version tag)
clean:

View File

@@ -0,0 +1,10 @@
# NFS server container for testing
This container exports '/' directory with an index.html inside. NFSv4 only.
Inspired by https://github.com/cpuguy83/docker-nfs-server.
Used by test/e2e/* to test NFSVolumeSource. Not for production use!
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/volumes-tester/nfs/README.md?pixel)]()

View File

@@ -0,0 +1 @@
Hello from NFS!

View File

@@ -0,0 +1,61 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
function start()
{
# prepare /etc/exports
for i in "$@"; do
# fsid=0: needed for NFSv4
echo "$i *(rw,fsid=0,no_root_squash)" >> /etc/exports
echo "Serving $i"
done
mount -t nfsd nfds /proc/fs/nfsd
# -N 2 -N 3: disable NFSv2+3
# -V 4.x: enable NFSv4
/usr/sbin/rpc.mountd -N 2 -N 3 -V 4 -V 4.1
/usr/sbin/exportfs -r
/usr/sbin/rpc.nfsd -N 2 -N 3 -V 4 -V 4.1 2
echo "NFS started"
}
function stop()
{
echo "Stopping NFS"
/usr/sbin/rpc.nfsd 0
/usr/sbin/exportfs -au
/usr/sbin/exportfs -f
kill $( pidof rpc.mountd )
umount /proc/fs/nfsd
echo > /etc/exports
exit 0
}
trap stop TERM
start "$@"
# Ugly hack to do nothing and wait for SIGTERM
while true; do
read
done

View File

@@ -0,0 +1,34 @@
# Copyright 2015 Google Inc. All rights reserved.
#
# 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.
# CEPH all in one
# Based on image by Ricardo Rocha, ricardo@catalyst.net.nz
FROM fedora
MAINTAINER Jan Safranek jsafrane@redhat.com
# Base Packages
RUN yum install -y wget ceph ceph-fuse strace && yum clean all
# Get ports exposed
EXPOSE 6789
ADD ./bootstrap.sh /bootstrap.sh
ADD ./mon.sh /mon.sh
ADD ./osd.sh /osd.sh
ADD ./ceph.conf.sh /ceph.conf.sh
ADD ./keyring /var/lib/ceph/mon/keyring
ADD ./block.tar.gz /
CMD /bootstrap.sh

View File

@@ -0,0 +1,22 @@
all: push
TAG = 0.1
container:
# Build new image and automatically tag it as latest
docker build -t gcr.io/google_containers/volume-rbd .
# Add the version tag to the latest image
docker tag gcr.io/google_containers/volume-rbd gcr.io/google_containers/volume-rbd:$(TAG)
block:
# Create block.tar.gz with ext2 block device with index.html inside.
# block.tar.gz is already available in git and users don't need to
# regenerate it, this target is here just for reference.
# Run as root!
./create_block.sh
push: container
# Push image tagged as latest to repository
gcloud docker push gcr.io/google_containers/volume-rbd
# Push version tagged image to repository (since this image is already pushed it will simply create or update version tag)
gcloud docker push gcr.io/google_containers/volume-rbd:$(TAG)

Binary file not shown.

View File

@@ -0,0 +1,47 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
#
# Bootstraps a CEPH server.
# It creates two OSDs on local machine, creates RBD pool there
# and imports 'block' device there.
#
# We must create fresh OSDs and filesystem here, because shipping it
# in a container would increase the image by ~300MB.
#
# Create /etc/ceph/ceph.conf
sh ./ceph.conf.sh `hostname -i`
# Configure and start ceph-mon
sh ./mon.sh `hostname -i`
# Configure and start 2x ceph-osd
mkdir -p /var/lib/ceph/osd/ceph-0 /var/lib/ceph/osd/ceph-1
sh ./osd.sh 0
sh ./osd.sh 1
# Prepare a RBD volume
# NOTE: we need Ceph kernel modules on the host!
rbd import block foo
echo "Ceph is ready"
# Wait forever
while true; do
sleep 10
done

View File

@@ -0,0 +1,38 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
#
# Configures /etc/ceph.conf from a template.
#
echo "
[global]
auth cluster required = none
auth service required = none
auth client required = none
[mon.a]
host = cephbox
mon addr = $1
[osd]
osd journal size = 128
journal dio = false
[osd.0]
osd host = cephbox
" > /etc/ceph/ceph.conf

View File

@@ -0,0 +1,49 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
# Create block.tar.gz with a small ext2 filesystem.
# It must be run as root (to mount with '-o loop')!
# Exit on the first error.
set -e
MNTDIR=`mktemp -d`
cleanup()
{
# Make sure we return the right exit code
RET=$?
# Silently remove everything and ignore errors
set +e
/bin/umount $MNTDIR 2>/dev/null
/bin/rmdir $MNTDIR 2>/dev/null
/bin/rm block 2>/dev/null
exit $RET
}
trap cleanup TERM EXIT
# Create 1MB device with ext2
dd if=/dev/zero of=block count=1 bs=1M
mkfs.ext2 block
# Add index.html to it
mount -o loop block $MNTDIR
echo "Hello from RBD" > $MNTDIR/index.html
umount $MNTDIR
rm block.tar.gz 2>/dev/null || :
tar cfz block.tar.gz block

View File

@@ -0,0 +1,8 @@
[mon.]
key = AQDRrKNV6z4UChAABzP1ZyysTU4pjgjNOf/p3A==
[client.admin]
key = AQDRrKNVbEevChAAEmRC+pW/KBVHxa0w/POILA==
auid = 0
caps mds = "allow *"
caps mon = "allow *"
caps osd = "allow *"

View File

@@ -0,0 +1,36 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
#
# Configures and launches a new MON.
#
# monitor setup
monmaptool --create --clobber --fsid `uuidgen` --add a $1:6789 /etc/ceph/monmap
mkdir /var/lib/ceph/mon/ceph-a
ceph-mon -i a --mkfs --monmap /etc/ceph/monmap -k /var/lib/ceph/mon/keyring
cp /var/lib/ceph/mon/keyring /var/lib/ceph/mon/ceph-a
ceph-mon -i a --monmap /etc/ceph/monmap -k /var/lib/ceph/mon/ceph-a/keyring
# client setup (handy)
cp /var/lib/ceph/mon/keyring /etc/ceph
# for this test we want to
ceph osd getcrushmap -o /tmp/crushc
crushtool -d /tmp/crushc -o /tmp/crushd
sed -i 's/step chooseleaf firstn 0 type host/step chooseleaf firstn 0 type osd/' /tmp/crushd
crushtool -c /tmp/crushd -o /tmp/crushc
ceph osd setcrushmap -i /tmp/crushc

View File

@@ -0,0 +1,25 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# 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.
#
# Configures and launches a new OSD.
#
ceph osd create
ceph-osd -i $1 --mkfs --mkkey
ceph auth add osd.$1 osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/ceph-$1/keyring
ceph osd crush add $1 1 root=default host=cephbox
ceph-osd -i $1 -k /var/lib/ceph/osd/ceph-$1/keyring