Merge pull request #12707 from mikedanese/move-test-contrib
move contrib/for-tests to test/images
This commit is contained in:
@@ -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")
|
||||
|
||||
})
|
||||
|
6
test/images/dnsutils/Dockerfile
Normal file
6
test/images/dnsutils/Dockerfile
Normal 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
|
8
test/images/dnsutils/Makefile
Normal file
8
test/images/dnsutils/Makefile
Normal 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
|
20
test/images/entrypoint-tester/Dockerfile
Normal file
20
test/images/entrypoint-tester/Dockerfile
Normal 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"]
|
15
test/images/entrypoint-tester/Makefile
Normal file
15
test/images/entrypoint-tester/Makefile
Normal 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
|
29
test/images/entrypoint-tester/ep.go
Normal file
29
test/images/entrypoint-tester/ep.go
Normal 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)
|
||||
}
|
6
test/images/jessie-dnsutils/Dockerfile
Normal file
6
test/images/jessie-dnsutils/Dockerfile
Normal 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
|
8
test/images/jessie-dnsutils/Makefile
Normal file
8
test/images/jessie-dnsutils/Makefile
Normal 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
|
16
test/images/mount-tester-user/Dockerfile
Normal file
16
test/images/mount-tester-user/Dockerfile
Normal 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
|
9
test/images/mount-tester-user/Makefile
Normal file
9
test/images/mount-tester-user/Makefile
Normal 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)
|
17
test/images/mount-tester/Dockerfile
Normal file
17
test/images/mount-tester/Dockerfile
Normal 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"]
|
15
test/images/mount-tester/Makefile
Normal file
15
test/images/mount-tester/Makefile
Normal 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
|
193
test/images/mount-tester/mt.go
Normal file
193
test/images/mount-tester/mt.go
Normal 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)
|
||||
}
|
19
test/images/network-tester/Dockerfile
Normal file
19
test/images/network-tester/Dockerfile
Normal 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"]
|
16
test/images/network-tester/Makefile
Normal file
16
test/images/network-tester/Makefile
Normal 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
|
44
test/images/network-tester/rc.json
Normal file
44
test/images/network-tester/rc.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
test/images/network-tester/service.json
Normal file
22
test/images/network-tester/service.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
269
test/images/network-tester/webserver.go
Normal file
269
test/images/network-tester/webserver.go
Normal 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
2
test/images/porter/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
porter
|
||||
.tag
|
18
test/images/porter/Dockerfile
Normal file
18
test/images/porter/Dockerfile
Normal 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"]
|
32
test/images/porter/Makefile
Normal file
32
test/images/porter/Makefile
Normal 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
|
5
test/images/porter/README.md
Normal file
5
test/images/porter/README.md
Normal 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.
|
||||
|
||||
|
||||
[]()
|
35
test/images/porter/pod.json
Normal file
35
test/images/porter/pod.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
59
test/images/porter/porter.go
Normal file
59
test/images/porter/porter.go
Normal 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())
|
||||
}
|
6
test/images/resource-consumer/Dockerfile
Normal file
6
test/images/resource-consumer/Dockerfile
Normal 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"]
|
17
test/images/resource-consumer/Makefile
Normal file
17
test/images/resource-consumer/Makefile
Normal 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
|
56
test/images/resource-consumer/consume-cpu/consume_cpu.go
Normal file
56
test/images/resource-consumer/consume-cpu/consume_cpu.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
32
test/images/resource-consumer/resource_consumer.go
Normal file
32
test/images/resource-consumer/resource_consumer.go
Normal 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))
|
||||
}
|
119
test/images/resource-consumer/resource_consumer_handler.go
Normal file
119
test/images/resource-consumer/resource_consumer_handler.go
Normal 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:])
|
||||
}
|
44
test/images/resource-consumer/utils.go
Normal file
44
test/images/resource-consumer/utils.go
Normal 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
|
||||
}
|
26
test/images/volumes-tester/gluster/Dockerfile
Normal file
26
test/images/volumes-tester/gluster/Dockerfile
Normal 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"]
|
13
test/images/volumes-tester/gluster/Makefile
Normal file
13
test/images/volumes-tester/gluster/Makefile
Normal 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:
|
8
test/images/volumes-tester/gluster/README.md
Normal file
8
test/images/volumes-tester/gluster/README.md
Normal 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!
|
||||
|
||||
|
||||
[]()
|
14
test/images/volumes-tester/gluster/glusterd.vol
Normal file
14
test/images/volumes-tester/gluster/glusterd.vol
Normal 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
|
1
test/images/volumes-tester/gluster/index.html
Normal file
1
test/images/volumes-tester/gluster/index.html
Normal file
@@ -0,0 +1 @@
|
||||
Hello from GlusterFS!
|
39
test/images/volumes-tester/gluster/run_gluster.sh
Executable file
39
test/images/volumes-tester/gluster/run_gluster.sh
Executable 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
|
||||
|
33
test/images/volumes-tester/iscsi/Dockerfile
Normal file
33
test/images/volumes-tester/iscsi/Dockerfile
Normal 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"]
|
22
test/images/volumes-tester/iscsi/Makefile
Normal file
22
test/images/volumes-tester/iscsi/Makefile
Normal 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)
|
14
test/images/volumes-tester/iscsi/README.md
Normal file
14
test/images/volumes-tester/iscsi/README.md
Normal 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!)
|
||||
|
||||
|
||||
[]()
|
BIN
test/images/volumes-tester/iscsi/block.tar.gz
Normal file
BIN
test/images/volumes-tester/iscsi/block.tar.gz
Normal file
Binary file not shown.
46
test/images/volumes-tester/iscsi/create_block.sh
Executable file
46
test/images/volumes-tester/iscsi/create_block.sh
Executable 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
|
1
test/images/volumes-tester/iscsi/initiatorname.iscsi
Normal file
1
test/images/volumes-tester/iscsi/initiatorname.iscsi
Normal file
@@ -0,0 +1 @@
|
||||
InitiatorName=iqn.1994-05.com.redhat:eb59fbe2c4c5
|
41
test/images/volumes-tester/iscsi/run_iscsid.sh
Executable file
41
test/images/volumes-tester/iscsi/run_iscsid.sh
Executable 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
|
102
test/images/volumes-tester/iscsi/saveconfig.json
Normal file
102
test/images/volumes-tester/iscsi/saveconfig.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
26
test/images/volumes-tester/nfs/Dockerfile
Normal file
26
test/images/volumes-tester/nfs/Dockerfile
Normal 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"]
|
13
test/images/volumes-tester/nfs/Makefile
Normal file
13
test/images/volumes-tester/nfs/Makefile
Normal 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:
|
10
test/images/volumes-tester/nfs/README.md
Normal file
10
test/images/volumes-tester/nfs/README.md
Normal 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!
|
||||
|
||||
|
||||
[]()
|
1
test/images/volumes-tester/nfs/index.html
Normal file
1
test/images/volumes-tester/nfs/index.html
Normal file
@@ -0,0 +1 @@
|
||||
Hello from NFS!
|
61
test/images/volumes-tester/nfs/run_nfs.sh
Executable file
61
test/images/volumes-tester/nfs/run_nfs.sh
Executable 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
|
34
test/images/volumes-tester/rbd/Dockerfile
Normal file
34
test/images/volumes-tester/rbd/Dockerfile
Normal 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
|
22
test/images/volumes-tester/rbd/Makefile
Normal file
22
test/images/volumes-tester/rbd/Makefile
Normal 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)
|
BIN
test/images/volumes-tester/rbd/block.tar.gz
Normal file
BIN
test/images/volumes-tester/rbd/block.tar.gz
Normal file
Binary file not shown.
47
test/images/volumes-tester/rbd/bootstrap.sh
Executable file
47
test/images/volumes-tester/rbd/bootstrap.sh
Executable 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
|
38
test/images/volumes-tester/rbd/ceph.conf.sh
Executable file
38
test/images/volumes-tester/rbd/ceph.conf.sh
Executable 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
|
||||
|
49
test/images/volumes-tester/rbd/create_block.sh
Executable file
49
test/images/volumes-tester/rbd/create_block.sh
Executable 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
|
8
test/images/volumes-tester/rbd/keyring
Normal file
8
test/images/volumes-tester/rbd/keyring
Normal 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 *"
|
36
test/images/volumes-tester/rbd/mon.sh
Executable file
36
test/images/volumes-tester/rbd/mon.sh
Executable 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
|
25
test/images/volumes-tester/rbd/osd.sh
Executable file
25
test/images/volumes-tester/rbd/osd.sh
Executable 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
|
Reference in New Issue
Block a user