diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 0aeadcbeadbb..32bdbb017ed3 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -300,6 +300,10 @@ "Comment": "v1.3.0", "Rev": "583e8937c61f1af6513608ccc75c97b6abdf4ff9" }, + { + "ImportPath": "github.com/c4milo/gotoolkit", + "Rev": "bcc06269efa974c4f098619d9aae436846e83d84" + }, { "ImportPath": "github.com/cloudflare/cfssl/auth", "Comment": "1.2.0", @@ -383,32 +387,32 @@ }, { "ImportPath": "github.com/containernetworking/cni/libcni", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { "ImportPath": "github.com/containernetworking/cni/pkg/invoke", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { "ImportPath": "github.com/containernetworking/cni/pkg/types", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { "ImportPath": "github.com/containernetworking/cni/pkg/types/020", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { "ImportPath": "github.com/containernetworking/cni/pkg/types/current", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { "ImportPath": "github.com/containernetworking/cni/pkg/version", - "Comment": "v0.5.2", + "Comment": "spec-v0.3.1", "Rev": "137b4975ecab6e1f0c24c1e3c228a50a3cfba75e" }, { @@ -776,12 +780,12 @@ }, { "ImportPath": "github.com/docker/distribution/digest", - "Comment": "v2.4.0-rc.1-38-gcd27f17", + "Comment": "v2.4.0-rc.1-38-gcd27f179", "Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51" }, { "ImportPath": "github.com/docker/distribution/reference", - "Comment": "v2.4.0-rc.1-38-gcd27f17", + "Comment": "v2.4.0-rc.1-38-gcd27f179", "Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51" }, { @@ -1664,6 +1668,11 @@ "Comment": "v4.0.0-22-g7a54b6f", "Rev": "7a54b6fc903feab1e7cb6573177ca09b544eb1e2" }, + { + "ImportPath": "github.com/hooklift/iso9660", + "Comment": "v1.0.0-6-g1cf07e5", + "Rev": "1cf07e5970d810f027bfbdfa2e9ad86db479c53a" + }, { "ImportPath": "github.com/howeyc/gopass", "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8" @@ -1675,6 +1684,7 @@ }, { "ImportPath": "github.com/inconshreveable/mousetrap", + "Comment": "v1.0", "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" }, { @@ -1807,6 +1817,10 @@ "Comment": "v2.1.1-5-g1b4ae6f", "Rev": "1b4ae6fb4e77b095934d4430860ff202060169f8" }, + { + "ImportPath": "github.com/mitchellh/go-ps", + "Rev": "4fdf99ab29366514c69ccccddab5dc58b8d84062" + }, { "ImportPath": "github.com/mitchellh/go-wordwrap", "Rev": "ad45545899c7b13c020ea92b2072220eefad42b8" @@ -1815,6 +1829,11 @@ "ImportPath": "github.com/mitchellh/mapstructure", "Rev": "53818660ed4955e899c0bcafa97299a388bd7c8e" }, + { + "ImportPath": "github.com/moby/hyperkit/go", + "Comment": "v0.20170425-38-g62fb993", + "Rev": "62fb993cc65090d3efe29e9b1ed871b017eeaa4d" + }, { "ImportPath": "github.com/mreiferson/go-httpclient", "Rev": "31f0106b4474f14bc441575c19d3a5fa21aa1f6c" @@ -1829,82 +1848,82 @@ }, { "ImportPath": "github.com/opencontainers/runc/libcontainer", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/apparmor", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/fs", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/systemd", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/configs", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/configs/validate", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/criurpc", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/keys", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/label", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/seccomp", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/selinux", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/stacktrace", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/system", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/user", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { "ImportPath": "github.com/opencontainers/runc/libcontainer/utils", - "Comment": "v1.0.0-rc2-49-gd223e2a", + "Comment": "v1.0.0-rc2-49-gd223e2ad", "Rev": "d223e2adae83f62d58448a799a5da05730228089" }, { @@ -1913,6 +1932,7 @@ }, { "ImportPath": "github.com/pelletier/go-buffruneio", + "Comment": "v0.1.0", "Rev": "df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d" }, { @@ -1979,17 +1999,17 @@ }, { "ImportPath": "github.com/r2d4/external-storage/lib/controller", - "Comment": "v1.0.0-20-g066bf161", + "Comment": "v1.0.0-20-g066bf16", "Rev": "066bf1613ae2b6e7024ba94fffca35f8b3c83f5b" }, { "ImportPath": "github.com/r2d4/external-storage/lib/leaderelection", - "Comment": "v1.0.0-20-g066bf161", + "Comment": "v1.0.0-20-g066bf16", "Rev": "066bf1613ae2b6e7024ba94fffca35f8b3c83f5b" }, { "ImportPath": "github.com/r2d4/external-storage/lib/leaderelection/resourcelock", - "Comment": "v1.0.0-20-g066bf161", + "Comment": "v1.0.0-20-g066bf16", "Rev": "066bf1613ae2b6e7024ba94fffca35f8b3c83f5b" }, { @@ -2338,8 +2358,13 @@ }, { "ImportPath": "github.com/xiang90/probing", + "Comment": "0.0.1", "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" }, + { + "ImportPath": "github.com/zchee/go-vmnet", + "Rev": "97ebf91740978f1e665defc0a960fb997ebe282b" + }, { "ImportPath": "go.pedge.io/pb/go/google/protobuf", "Rev": "f3c84f58974dc53d460d0855337cad85843bf0df" diff --git a/Makefile b/Makefile index f3ef9478cc46..0c2fb72a01cb 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,7 @@ LOCALKUBE_LDFLAGS := "$(K8S_VERSION_LDFLAGS) $(MINIKUBE_LDFLAGS) -s -w -extldfla LOCALKUBEFILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' ./cmd/localkube/ | grep k8s.io | GOPATH=$(GOPATH) xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}' MINIKUBEFILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' ./cmd/minikube/ | grep k8s.io | GOPATH=$(GOPATH) xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}' +HYPERKIT_FILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' k8s.io/minikube/cmd/drivers/hyperkit | grep k8s.io | GOPATH=$(GOPATH) xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}' MINIKUBE_ENV_linux := CGO_ENABLED=1 GOARCH=amd64 GOOS=linux MINIKUBE_ENV_darwin := CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin @@ -158,7 +159,7 @@ $(GOPATH)/bin/go-bindata: GOBIN=$(GOPATH)/bin go get github.com/jteeuwen/go-bindata/... .PHONY: cross -cross: out/localkube out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe +cross: out/localkube out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/docker-machine-driver-hyperkit .PHONY: cross-e2e e2e-cross: out/e2e-linux-amd64 out/e2e-darwin-amd64 out/e2e-windows-amd64 @@ -213,6 +214,19 @@ out/minikube-installer.exe: out/minikube-windows-amd64.exe mv out/windows_tmp/minikube-installer.exe out/minikube-installer.exe rm -rf out/windows_tmp +out/docker-machine-driver-hyperkit: $(shell $(HYPERKIT_FILES)) +ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) + $(MINIKUBE_DOCKER_CMD) '$(MINIKUBE_ENV_darwin_DOCKER) $(MINIKUBE_ENV_darwin) go build -o $(BUILD_DIR)/docker-machine-driver-hyperkit k8s.io/minikube/cmd/drivers/hyperkit' +else + $(MINIKUBE_ENV_darwin) go build -o $(BUILD_DIR)/docker-machine-driver-hyperkit k8s.io/minikube/cmd/drivers/hyperkit +endif + +.PHONY: install-hyperkit-driver +install-hyperkit-driver: out/docker-machine-driver-hyperkit + sudo cp out/docker-machine-driver-hyperkit $(HOME)/bin/docker-machine-driver-hyperkit + sudo chown root:wheel $(HOME)/bin/docker-machine-driver-hyperkit + sudo chmod u+s $(HOME)/bin/docker-machine-driver-hyperkit + .PHONY: check-release check-release: go test -v ./deploy/minikube/release_sanity_test.go -tags=release diff --git a/cmd/drivers/hyperkit/main.go b/cmd/drivers/hyperkit/main.go new file mode 100644 index 000000000000..878060c549ec --- /dev/null +++ b/cmd/drivers/hyperkit/main.go @@ -0,0 +1,26 @@ +/* +Copyright 2016 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 ( + "github.com/docker/machine/libmachine/drivers/plugin" + "k8s.io/minikube/pkg/minikube/drivers/hyperkit" +) + +func main() { + plugin.RegisterDriver(hyperkit.NewDriver("", "")) +} diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 71099b8292c2..5123e06ea043 100644 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -27,11 +27,15 @@ # Copy only the files we need to this workspace mkdir -p out/ testdata/ gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/minikube-${OS_ARCH} out/ +gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/docker-machine-driver-* out/ gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/e2e-${OS_ARCH} out/ gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/testdata/busybox.yaml testdata/ gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/testdata/pvc.yaml testdata/ gsutil cp gs://minikube-builds/${MINIKUBE_LOCATION}/testdata/busybox-mount-test.yaml testdata/ +# Add the out/ directory to the PATH, for using new drivers. +export PATH="$(pwd)/out/":$PATH + # Linux cleanup virsh -c qemu:///system list --all \ | sed -n '3,$ p' \ @@ -59,6 +63,12 @@ pgrep xhyve | xargs kill || true # Set the executable bit on the e2e binary and out binary chmod +x out/e2e-${OS_ARCH} chmod +x out/minikube-${OS_ARCH} +chmod +x out/docker-machine-driver-* + +if [ -e out/docker-machine-driver-hyperkit ]; then + sudo chown root:wheel out/docker-machine-driver-hyperkit || true + sudo chmod u+s out/docker-machine-driver-hyperkit || true +fi MINIKUBE_WANTREPORTERRORPROMPT=False sudo ./out/minikube-${OS_ARCH} delete \ || MINIKUBE_WANTREPORTERRORPROMPT=False ./out/minikube-${OS_ARCH} delete \ diff --git a/hack/jenkins/minikube_set_pending.sh b/hack/jenkins/minikube_set_pending.sh index 31daad55046d..726a7b9b0385 100755 --- a/hack/jenkins/minikube_set_pending.sh +++ b/hack/jenkins/minikube_set_pending.sh @@ -27,7 +27,7 @@ set -e set +x -for job in "OSX-Virtualbox" "OSX-XHyve" "Linux-Virtualbox" "Linux-KVM" "Linux-KVM-Alt" "Linux-None" "Windows-HyperV"; do +for job in "OSX-Virtualbox" "OSX-XHyve" "OSX-Hyperkit" "Linux-Virtualbox" "Linux-KVM" "Linux-KVM-Alt" "Linux-None" "Windows-HyperV"; do target_url="https://storage.googleapis.com/minikube-builds/logs/${ghprbPullId}/${job}.txt" curl "https://api.github.com/repos/kubernetes/minikube/statuses/${ghprbActualCommit}?access_token=$access_token" \ -H "Content-Type: application/json" \ diff --git a/hack/jenkins/osx_integration_tests_hyperkit.sh b/hack/jenkins/osx_integration_tests_hyperkit.sh new file mode 100755 index 000000000000..db9165a57fc7 --- /dev/null +++ b/hack/jenkins/osx_integration_tests_hyperkit.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Copyright 2016 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. + + +# This script runs the integration tests on an OSX machine for the Hyperkit Driver + +# The script expects the following env variables: +# MINIKUBE_LOCATION: GIT_COMMIT from upstream build. +# COMMIT: Actual commit ID from upstream build +# EXTRA_BUILD_ARGS (optional): Extra args to be passed into the minikube integrations tests +# access_token: The Github API access token. Injected by the Jenkins credential provider. + + +set -e + +OS_ARCH="darwin-amd64" +VM_DRIVER="hyperkit" +JOB_NAME="OSX-Hyperkit" + + +# Download files and set permissions +source common.sh diff --git a/hack/jenkins/print-debug-info.sh b/hack/jenkins/print-debug-info.sh index 201003f86b28..5a82e2609015 100644 --- a/hack/jenkins/print-debug-info.sh +++ b/hack/jenkins/print-debug-info.sh @@ -31,6 +31,7 @@ journalctl -u localkube -n 500 ${SUDO_PREFIX}cat $KUBECONFIG cat $HOME/.kube/config +echo $PATH docker ps diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index e7226185cebe..e6e78f986935 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -391,6 +391,8 @@ func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) { driver = createHypervHost(config) case "none": driver = createNoneHost(config) + case "hyperkit": + driver = createHyperkitHost(config) default: glog.Exitf("Unsupported driver: %s\n", config.VMDriver) } diff --git a/pkg/minikube/cluster/cluster_darwin.go b/pkg/minikube/cluster/cluster_darwin.go index 85dfccd027a8..8cedadaf6c05 100644 --- a/pkg/minikube/cluster/cluster_darwin.go +++ b/pkg/minikube/cluster/cluster_darwin.go @@ -23,6 +23,7 @@ import ( "github.com/docker/machine/libmachine/drivers" cfg "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/minikube/drivers/hyperkit" ) func createVMwareFusionHost(config MachineConfig) drivers.Driver { @@ -57,6 +58,21 @@ type xhyveDriver struct { RawDisk bool } +func createHyperkitHost(config MachineConfig) *hyperkit.Driver { + return &hyperkit.Driver{ + BaseDriver: &drivers.BaseDriver{ + MachineName: cfg.GetMachineName(), + StorePath: constants.GetMinipath(), + SSHUser: "docker", + }, + Boot2DockerURL: config.Downloader.GetISOFileURI(config.MinikubeISO), + DiskSize: config.DiskSize, + Memory: config.Memory, + CPU: config.CPUs, + Cmdline: "loglevel=3 user=docker console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10 systemd.legacy_systemd_cgroup_controller=yes base host=" + cfg.GetMachineName(), + } +} + func createXhyveHost(config MachineConfig) *xhyveDriver { useVirtio9p := !config.DisableDriverMounts return &xhyveDriver{ diff --git a/pkg/minikube/cluster/cluster_non_darwin_panic.go b/pkg/minikube/cluster/cluster_non_darwin_panic.go index c67bde37e118..82b510adfaaa 100644 --- a/pkg/minikube/cluster/cluster_non_darwin_panic.go +++ b/pkg/minikube/cluster/cluster_non_darwin_panic.go @@ -27,3 +27,7 @@ func createVMwareFusionHost(config MachineConfig) drivers.Driver { func createXhyveHost(config MachineConfig) drivers.Driver { panic("xhyve not supported") } + +func createHyperkitHost(config MachineConfig) drivers.Driver { + panic("hyperkit not supported") +} diff --git a/pkg/minikube/drivers/hyperkit/disk.go b/pkg/minikube/drivers/hyperkit/disk.go new file mode 100644 index 000000000000..ebc68aedaa01 --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/disk.go @@ -0,0 +1,64 @@ +/* +Copyright 2016 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 hyperkit + +import ( + "io/ioutil" + "os" + "path/filepath" + "syscall" + + "github.com/cloudflare/cfssl/log" + "github.com/docker/machine/libmachine/mcnutils" +) + +func createDiskImage(sshKeyPath, diskPath string, diskSizeMb int) error { + tarBuf, err := mcnutils.MakeDiskImage(sshKeyPath) + if err != nil { + return err + } + + file, err := os.OpenFile(diskPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer file.Close() + file.Seek(0, os.SEEK_SET) + + if _, err := file.Write(tarBuf.Bytes()); err != nil { + return err + } + file.Close() + + if err := os.Truncate(diskPath, int64(diskSizeMb*1000000)); err != nil { + return err + } + return nil +} + +func fixPermissions(path string) error { + os.Chown(path, syscall.Getuid(), syscall.Getegid()) + files, _ := ioutil.ReadDir(path) + for _, f := range files { + fp := filepath.Join(path, f.Name()) + log.Debugf(fp) + if err := os.Chown(fp, syscall.Getuid(), syscall.Getegid()); err != nil { + return err + } + } + return nil +} diff --git a/pkg/minikube/drivers/hyperkit/disk_test.go b/pkg/minikube/drivers/hyperkit/disk_test.go new file mode 100644 index 000000000000..e85a0dad31e4 --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/disk_test.go @@ -0,0 +1,48 @@ +/* +Copyright 2016 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 hyperkit + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "k8s.io/minikube/pkg/minikube/tests" +) + +func Test_createDiskImage(t *testing.T) { + tmpdir := tests.MakeTempDir() + defer os.RemoveAll(tmpdir) + + sshPath := filepath.Join(tmpdir, "ssh") + ioutil.WriteFile(sshPath, []byte("mysshkey"), 0644) + diskPath := filepath.Join(tmpdir, "disk") + + sizeInMb := 100 + sizeInBytes := int64(sizeInMb) * 1000000 + if err := createDiskImage(sshPath, diskPath, sizeInMb); err != nil { + t.Errorf("createDiskImage() error = %v", err) + } + fi, err := os.Lstat(diskPath) + if err != nil { + t.Errorf("Lstat() error = %v", err) + } + if fi.Size() != sizeInBytes { + t.Errorf("Disk size is %v, want %v", fi.Size(), sizeInBytes) + } +} diff --git a/pkg/minikube/drivers/hyperkit/driver.go b/pkg/minikube/drivers/hyperkit/driver.go new file mode 100644 index 000000000000..b1567efda42c --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/driver.go @@ -0,0 +1,289 @@ +// +build darwin + +/* +Copyright 2016 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 hyperkit + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "syscall" + "time" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/ssh" + "github.com/docker/machine/libmachine/state" + hyperkit "github.com/moby/hyperkit/go" + "github.com/pborman/uuid" + vmnet "github.com/zchee/go-vmnet" + commonutil "k8s.io/minikube/pkg/util" +) + +const ( + isoFilename = "boot2docker.iso" + pidFileName = "hyperkit.pid" + machineFileName = "hyperkit.json" +) + +type Driver struct { + *drivers.BaseDriver + Boot2DockerURL string + DiskSize int + CPU int + Memory int + Cmdline string +} + +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + BaseDriver: &drivers.BaseDriver{ + SSHUser: "docker", + }, + } +} + +func (d *Driver) Create() error { + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return err + } + + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { + return err + } + isoPath := d.ResolveStorePath(isoFilename) + if err := d.extractKernel(isoPath); err != nil { + return err + } + + return d.Start() +} + +// DriverName returns the name of the driver +func (d *Driver) DriverName() string { + return "hyperkit" +} + +// GetCreateFlags returns the mcnflag.Flag slice representing the flags +// that can be set, their descriptions and defaults. +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return nil +} + +// GetSSHHostname returns hostname for use with ssh +func (d *Driver) GetSSHHostname() (string, error) { + return d.IPAddress, nil +} + +// GetURL returns a Docker compatible host URL for connecting to this host +// e.g. tcp://1.2.3.4:2376 +func (d *Driver) GetURL() (string, error) { + ip, err := d.GetIP() + if err != nil { + return "", err + } + return fmt.Sprintf("tcp://%s:2376", ip), nil +} + +// GetState returns the state that the host is in (running, stopped, etc) +func (d *Driver) GetState() (state.State, error) { + pid := d.getPid() + if pid == 0 { + return state.Stopped, nil + } + p, err := os.FindProcess(pid) + if err != nil { + return state.Error, err + } + + // Sending a signal of 0 can be used to check the existence of a process. + if err := p.Signal(syscall.Signal(0)); err != nil { + return state.Stopped, nil + } + if p == nil { + return state.Stopped, nil + } + return state.Running, nil +} + +// Kill stops a host forcefully +func (d *Driver) Kill() error { + return d.sendSignal(syscall.SIGKILL) +} + +// PreCreateCheck allows for pre-create operations to make sure a driver is ready for creation +func (d *Driver) PreCreateCheck() error { + return nil +} + +// Remove a host +func (d *Driver) Remove() error { + s, err := d.GetState() + if err != nil || s == state.Error { + log.Infof("Error checking machine status: %s, assuming it has been removed already", err) + } + if s == state.Running { + if err := d.Stop(); err != nil { + return err + } + } + return nil +} + +// Restart a host. This may just call Stop(); Start() if the provider does not +// have any special restart behaviour. +func (d *Driver) Restart() error { + for _, f := range []func() error{d.Stop, d.Start} { + if err := f(); err != nil { + return err + } + } + return nil +} + +// SetConfigFromFlags configures the driver with the object that was returned +// by RegisterCreateFlags +func (d *Driver) SetConfigFromFlags(opts drivers.DriverOptions) error { + return nil +} + +// Start a host +func (d *Driver) Start() error { + + // TODO: handle different disk types. + diskPath := filepath.Join(d.ResolveStorePath("."), d.MachineName+".rawdisk") + if _, err := os.Stat(diskPath); os.IsNotExist(err) { + if err := createDiskImage(d.publicSSHKeyPath(), diskPath, d.DiskSize); err != nil { + return err + } + if err := fixPermissions(d.ResolveStorePath(".")); err != nil { + return err + } + } + + h, err := hyperkit.New("", "", filepath.Join(d.StorePath, "machines", d.MachineName)) + if err != nil { + return err + } + + // TODO: handle the rest of our settings. + h.Kernel = d.ResolveStorePath("bzimage") + h.Initrd = d.ResolveStorePath("initrd") + h.VMNet = true + h.ISOImage = d.ResolveStorePath(isoFilename) + h.Console = hyperkit.ConsoleFile + h.CPUs = d.CPU + h.Memory = d.Memory + + // Set UUID + h.UUID = uuid.NewUUID().String() + log.Infof("Generated UUID %s", h.UUID) + mac, err := vmnet.GetMACAddressFromUUID(h.UUID) + if err != nil { + return err + } + + // Need to strip 0's + mac = trimMacAddress(mac) + log.Infof("Generated MAC %s", mac) + + h.Disks = []hyperkit.DiskConfig{ + { + Path: diskPath, + Size: d.DiskSize, + Driver: "virtio-blk", + }, + } + log.Infof("Starting with cmdline: %s", d.Cmdline) + if err := h.Start(d.Cmdline); err != nil { + return err + } + + getIP := func() error { + var err error + d.IPAddress, err = GetIPAddressByMACAddress(mac) + if err != nil { + return &commonutil.RetriableError{Err: err} + } + return nil + } + + if err := commonutil.RetryAfter(30, getIP, 2*time.Second); err != nil { + return fmt.Errorf("IP address never found in dhcp leases file %v", err) + } + return nil +} + +// Stop a host gracefully +func (d *Driver) Stop() error { + return d.sendSignal(syscall.SIGTERM) +} + +func (d *Driver) extractKernel(isoPath string) error { + for _, f := range []struct { + pathInIso string + destPath string + }{ + {"/boot/bzimage", "bzimage"}, + {"/boot/initrd", "initrd"}, + {"/isolinux/isolinux.cfg", "isolinux.cfg"}, + } { + fullDestPath := d.ResolveStorePath(f.destPath) + if err := ExtractFile(isoPath, f.pathInIso, fullDestPath); err != nil { + return err + } + } + return nil +} + +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" +} + +func (d *Driver) sendSignal(s os.Signal) error { + pid := d.getPid() + proc, err := os.FindProcess(pid) + if err != nil { + return err + } + + return proc.Signal(s) +} + +func (d *Driver) getPid() int { + pidPath := d.ResolveStorePath(machineFileName) + + f, err := os.Open(pidPath) + if err != nil { + log.Warnf("Error reading pid file: %s", err) + return 0 + } + dec := json.NewDecoder(f) + config := hyperkit.HyperKit{} + if err := dec.Decode(&config); err != nil { + log.Warnf("Error decoding pid file: %s", err) + return 0 + } + + return config.Pid +} diff --git a/pkg/minikube/drivers/hyperkit/iso.go b/pkg/minikube/drivers/hyperkit/iso.go new file mode 100644 index 000000000000..9139073db7b1 --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/iso.go @@ -0,0 +1,87 @@ +/* +Copyright 2016 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 hyperkit + +import ( + "fmt" + "io" + "io/ioutil" + "os" + + "strings" + + "github.com/hooklift/iso9660" +) + +func ExtractFile(isoPath, srcPath, destPath string) error { + iso, err := os.Open(isoPath) + defer iso.Close() + if err != nil { + return err + } + + r, err := iso9660.NewReader(iso) + if err != nil { + return err + } + + f, err := findFile(r, srcPath) + if err != nil { + return err + } + + dst, err := os.Create(destPath) + defer dst.Close() + if err != nil { + return err + } + + _, err = io.Copy(dst, f.Sys().(io.Reader)) + return err +} + +func ReadFile(isoPath, srcPath string) (string, error) { + iso, err := os.Open(isoPath) + defer iso.Close() + if err != nil { + return "", err + } + + r, err := iso9660.NewReader(iso) + if err != nil { + return "", err + } + + f, err := findFile(r, srcPath) + if err != nil { + return "", err + } + + contents, err := ioutil.ReadAll(f.Sys().(io.Reader)) + return string(contents), err +} + +func findFile(r *iso9660.Reader, path string) (os.FileInfo, error) { + // Look through the ISO for a file with a matching path. + for f, err := r.Next(); err != io.EOF; f, err = r.Next() { + // For some reason file paths in the ISO sometimes contain a '.' character at the end, so strip that off. + if strings.TrimSuffix(f.Name(), ".") == path { + return f, nil + } + } + return nil, fmt.Errorf("unable to find file %s", path) +} diff --git a/pkg/minikube/drivers/hyperkit/network.go b/pkg/minikube/drivers/hyperkit/network.go new file mode 100644 index 000000000000..13f48594680e --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/network.go @@ -0,0 +1,110 @@ +/* +Copyright 2016 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 hyperkit + +import ( + "bufio" + "fmt" + "io" + "os" + "regexp" + "strings" +) + +const ( + DHCPLeasesFile = "/var/db/dhcpd_leases" +) + +type DHCPEntry struct { + Name string + IPAddress string + HWAddress string + ID string + Lease string +} + +func GetIPAddressByMACAddress(mac string) (string, error) { + return getIpAddressFromFile(mac, DHCPLeasesFile) +} + +func getIpAddressFromFile(mac, path string) (string, error) { + file, err := os.Open(path) + if err != nil { + return "", err + } + defer file.Close() + + dhcpEntries, err := parseDHCPdLeasesFile(file) + if err != nil { + return "", err + } + for _, dhcpEntry := range dhcpEntries { + if dhcpEntry.HWAddress == mac { + return dhcpEntry.IPAddress, nil + } + } + return "", fmt.Errorf("Could not find an IP address for %s", mac) +} + +func parseDHCPdLeasesFile(file io.Reader) ([]DHCPEntry, error) { + var ( + dhcpEntry *DHCPEntry + dhcpEntries []DHCPEntry + ) + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "{" { + dhcpEntry = new(DHCPEntry) + continue + } else if line == "}" { + dhcpEntries = append(dhcpEntries, *dhcpEntry) + continue + } + + split := strings.SplitN(line, "=", 2) + if len(split) != 2 { + return nil, fmt.Errorf("invalid line in dhcp leases file: %s", line) + } + key, val := split[0], split[1] + switch key { + case "name": + dhcpEntry.Name = val + case "ip_address": + dhcpEntry.IPAddress = val + case "hw_address": + // The mac addresses have a '1,' at the start. + dhcpEntry.HWAddress = val[2:] + case "identifier": + dhcpEntry.ID = val + case "lease": + dhcpEntry.Lease = val + default: + return dhcpEntries, fmt.Errorf("Unable to parse line: %s", line) + } + } + return dhcpEntries, scanner.Err() +} + +// trimMacAddress trimming "0" of the ten's digit +func trimMacAddress(rawUUID string) string { + re := regexp.MustCompile(`0([A-Fa-f0-9](:|$))`) + mac := re.ReplaceAllString(rawUUID, "$1") + + return mac +} diff --git a/pkg/minikube/drivers/hyperkit/network_test.go b/pkg/minikube/drivers/hyperkit/network_test.go new file mode 100644 index 000000000000..d8b831b82398 --- /dev/null +++ b/pkg/minikube/drivers/hyperkit/network_test.go @@ -0,0 +1,101 @@ +/* +Copyright 2016 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 hyperkit + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "k8s.io/minikube/pkg/minikube/tests" +) + +var validLeases = []byte(`{ + name=foo + ip_address=1.2.3.4 + hw_address=1,a1:b2:c3:d4:e5:f6 + identifier=1,a2:b3:c4:d5:e6:f7 + lease=0x597e1267 +} +{ + name=bar + ip_address=192.168.64.3 + hw_address=1,a4:b5:c6:d7:e8:f9 + identifier=1,a0:b0:c0:d0:e0:f0 + lease=0x597e1267 +} +{ + name=bar + ip_address=192.168.64.4 + hw_address=1,a5:b6:c7:d8:e9:f1 + identifier=1,a5:b6:c7:d8:e9:f1 + lease=0x597e1268 +}`) + +func Test_getIpAddressFromFile(t *testing.T) { + tmpdir := tests.MakeTempDir() + defer os.RemoveAll(tmpdir) + + dhcpFile := filepath.Join(tmpdir, "dhcp") + ioutil.WriteFile(dhcpFile, validLeases, 0644) + + invalidFile := filepath.Join(tmpdir, "invalid") + ioutil.WriteFile(invalidFile, []byte("foo"), 0644) + + type args struct { + mac string + path string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + "valid", + args{"a1:b2:c3:d4:e5:f6", dhcpFile}, + "1.2.3.4", + false, + }, + { + "duplicate", + args{"a4:b5:c6:d7:e8:f9", dhcpFile}, + "192.168.64.3", + false, + }, + { + "invalid", + args{"a1:b2:c3:d4:e5:f6", invalidFile}, + "", + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getIpAddressFromFile(tt.args.mac, tt.args.path) + if (err != nil) != tt.wantErr { + t.Errorf("getIpAddressFromFile() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("getIpAddressFromFile() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/vendor/github.com/c4milo/gotoolkit/.travis.yml b/vendor/github.com/c4milo/gotoolkit/.travis.yml new file mode 100644 index 000000000000..50701f19b781 --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/.travis.yml @@ -0,0 +1,11 @@ +language: go + +go: + - 1.4 + - 1.5 + - 1.8 + - tip + +matrix: + allow_failures: + - go: tip diff --git a/vendor/github.com/c4milo/gotoolkit/CONTRIBUTING.md b/vendor/github.com/c4milo/gotoolkit/CONTRIBUTING.md new file mode 100644 index 000000000000..fa1e3271e87d --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/CONTRIBUTING.md @@ -0,0 +1,65 @@ +### Thanks for your interest in contributing to this project and for taking the time to read this guide. + +## Code of conduct +*Taken from http://libvirt.org/governance.html with minor adjustments.* + +The open source community covers people from a wide variety of countries, backgrounds and positions. This global diversity is a great strength for this project, but can also lead to communication issues, which may in turn cause unhappiness. To maximize happiness of the project community taken as a whole, all members (whether users, contributors or committers) are expected to abide by the project's code of conduct. At a high level the code can be summarized as "be excellent to each other". Expanding on this: + +**Be respectful:** disagreements between people are to be expected and are usually the sign of healthy debate and engagement. Disagreements can lead to frustration and even anger for some members. Turning to personal insults, intimidation or threatening behavior does not improve the situation. Participants should thus take care to ensure all communications / interactions stay professional at all times. + +**Be considerate:** remember that the community has members with a diverse background many of whom have English as a second language. What might appear impolite, may simply be a result of a lack of knowledge of the English language. Bear in mind that actions will have an impact on other community members and the project as a whole, so take potential consequences into account before pursuing a course of action. + +**Be forgiving:** humans are fallible and as such prone to make mistakes and inexplicably change their positions at times. Don't assume that other members are acting with malicious intent. Be prepared to forgive people who make mistakes and assist each other in learning from them. Playing a blame game doesn't help anyone. + +## Issues +* Before reporting an issue make sure you search first if anybody has already reported a similar issue and whether or not it has been fixed. +* Make sure your issue report sufficiently details the problem. +* Include code samples reproducing the issue. +* Please do not derail or troll issues. Keep the discussion on topic and respect the Code of conduct. +* Please do not open issues for personal support requests, use the mailing list instead. +* If you want to tackle any open issue, make sure you let people know you are working on it. + +## Development workflow +Go is unlike any other language in that it forces a specific development workflow and project structure. Trying to fight it is useless, frustrating and time consuming. So, you better be prepare to adapt your workflow when contributing to Go projects. + +### Prerequisites +* **Go**: To install Go please follow its installation guide at https://golang.org/doc/install +* **Git:** + * **Debian-based distros:** `apt-get install git-core` + * **OSX:** `brew install git` + +### Pull Requests +* Please be generous describing your changes. +* Although it is highly suggested to include tests, they are not a hard requirement in order to get your contributions accepted. +* Keep pull requests small so core developers can review them quickly. + +### Workflow for third-party code contributions +* In Github, fork `https://github.com/c4milo/gotoolkit` to your own account +* Get the package using "go get": `go get github.com/c4milo/gotoolkit` +* Move to where the package was cloned: `cd $GOPATH/src/github.com/c4milo/gotoolkit/` +* Add a git remote pointing to your own fork: `git remote add downstream git@github.com:/gotoolkit.git` +* Create a branch for making your changes, then commit them. +* Push changes to downstream repository, this is your own fork: `git push downstream` +* In Github, from your fork, create the Pull Request and send it upstream. +* You are done. + + +### Workflow for core developers +Since core developers usually have access to the upstream repository, there is no need for having a workflow like the one for thid-party contributors. + +* Get the package using "go get": `go get github.com/c4milo/gotoolkit` +* Create a branch for making your changes, then commit them. +* Push changes to the repository: `git push origin ` +* In Github, create the Pull Request from your branch to master. +* Before merging into master, wait for at least two developers to code review your contribution. + + +## Resources +* **Art of Computer Programming:** http://www-cs-faculty.stanford.edu/~uno/news.html +* **Algorithm Design Manual (2nd edition):** http://www.amazon.com/Algorithm-Design-Manual-Steve-Skiena/dp/0387948600 +* **Algorithms (4th Edition):** http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X/ref=sr_1_2?s=books&ie=UTF8&qid=1410027698&sr=1-2 +* **Introduction to Algorithms, 3rd Edition:** http://www.amazon.com/Introduction-Algorithms-3rd-Thomas-Cormen/dp/0262033844/ref=sr_1_1?s=books&ie=UTF8&qid=1410027698&sr=1-1 +* **Cracking the Coding Interview: 150 Programming Questions and Solutions:** http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X/ref=pd_bxgy_b_img_y +* **CS 97SI: Introduction to Competitive Programming Contests:** http://web.stanford.edu/class/cs97si/ +* **Algorithm tutorials at Topcoder:** http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=alg_index +* **CS 161 - Design and Analysis of Algorithms:** http://openclassroom.stanford.edu/MainFolder/CoursePage.php?course=IntroToAlgorithms diff --git a/vendor/github.com/c4milo/gotoolkit/LICENSE b/vendor/github.com/c4milo/gotoolkit/LICENSE new file mode 100644 index 000000000000..52d135112eeb --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/LICENSE @@ -0,0 +1,374 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/c4milo/gotoolkit/README.md b/vendor/github.com/c4milo/gotoolkit/README.md new file mode 100644 index 000000000000..3aaa55367b35 --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/README.md @@ -0,0 +1,12 @@ +# Go Toolkit +[![GoDoc](https://godoc.org/github.com/c4milo/gotoolkit?status.svg)](https://godoc.org/github.com/c4milo/gotoolkit) +[![Build Status](https://travis-ci.org/c4milo/gotoolkit.svg?branch=master)](https://travis-ci.org/c4milo/gotoolkit) + +A set of algorithms and data structures that are not part of the standard Go packages and that we need +on a daily basis. + +## Algorithms +* **SliceStack** +* **ListStack** +* **ListQueue** +* **SliceQueue** diff --git a/vendor/github.com/c4milo/gotoolkit/queue.go b/vendor/github.com/c4milo/gotoolkit/queue.go new file mode 100644 index 000000000000..6caf125895ff --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/queue.go @@ -0,0 +1,114 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package gotoolkit + +import "errors" + +// Queue defines an interface for implementing Queue data structures. +type Queue interface { + Enqueue(item interface{}) + Dequeue() (interface{}, error) + Peek() (interface{}, error) + IsEmpty() bool + Size() uint64 +} + +// ListQueue implements a queue backed by a linked list, it may be faster than SliceQueue +// but consumes more memory and has worse cache locality than SliceQueue +type ListQueue struct { + first *node + last *node + size uint64 +} + +// Enqueue adds an element to the end of the queue. +func (q *ListQueue) Enqueue(item interface{}) { + last := new(node) + last.item = item + + if q.IsEmpty() { + q.first = last + } else { + oldLast := q.last + oldLast.next = last + } + q.last = last + q.size++ +} + +// Dequeue removes the first element from the queue. +func (q *ListQueue) Dequeue() (interface{}, error) { + if q.IsEmpty() { + q.last = nil + return nil, errors.New("unable to dequeue element, queue is empty") + } + + item := q.first.item + q.first = q.first.next + q.size-- + return item, nil +} + +// Peek returns the first element in the queue without removing it. +func (q *ListQueue) Peek() (interface{}, error) { + if q.IsEmpty() { + return nil, errors.New("unable to peek element, queue is empty") + } + return q.first.item, nil +} + +// IsEmpty returns whether the queue is empty or not. +func (q *ListQueue) IsEmpty() bool { + return q.first == nil +} + +// Size returns the number of elements in the queue. +func (q *ListQueue) Size() uint64 { + return q.size +} + +// SliceQueue implements a queue backed by a growing slice. Useful for memory +// constrained environments. It also has better cache locality than ListQueue +type SliceQueue struct { + size uint64 + backing []interface{} +} + +// Enqueue adds an element to the end of the queue. +func (s *SliceQueue) Enqueue(item interface{}) { + s.size++ + s.backing = append(s.backing, item) +} + +// Peek returns the first element of the queue without removing it from the queue. +func (s *SliceQueue) Peek() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to peek element, queue is empty") + } + return s.backing[0], nil +} + +// Dequeue removes and return the first element from the queue. +func (s *SliceQueue) Dequeue() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to dequeue element, queue is empty") + } + + item := s.backing[0] + // https://github.com/golang/go/wiki/SliceTricks + s.backing = append(s.backing[:0], s.backing[1:]...) + s.size-- + return item, nil +} + +// IsEmpty returns whether or not the queue is empty. +func (s *SliceQueue) IsEmpty() bool { + return len(s.backing) == 0 +} + +// Size returns the number of elements in the queue. +func (s *SliceQueue) Size() uint64 { + return s.size +} diff --git a/vendor/github.com/c4milo/gotoolkit/stack.go b/vendor/github.com/c4milo/gotoolkit/stack.go new file mode 100644 index 000000000000..8314cb370cbd --- /dev/null +++ b/vendor/github.com/c4milo/gotoolkit/stack.go @@ -0,0 +1,110 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package gotoolkit + +import "errors" + +// Stack defines an interface for implementing Stack data structures. +type Stack interface { + Push(item interface{}) + Pop() (interface{}, error) + Peek() (interface{}, error) + IsEmpty() bool + Size() uint64 +} + +type node struct { + item interface{} + next *node +} + +// ListStack is a stack backed by a linked list, it may be faster than SliceStack +// but consumes more memory and has worse cache locality than SliceQueue. +type ListStack struct { + first *node + size uint64 +} + +// Push adds an element to the top of the stack. +func (s *ListStack) Push(item interface{}) { + oldFirst := s.first + s.first = new(node) + s.first.item = item + s.first.next = oldFirst + s.size++ +} + +// Peek returns the latest added element without removing it from the stack. +func (s *ListStack) Peek() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to peek element, stack is empty") + } + + return s.first.item, nil +} + +// Pop removes and return the latest added element from the stack. +func (s *ListStack) Pop() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to pop element, stack is empty") + } + item := s.first.item + s.first = s.first.next + s.size-- + return item, nil +} + +// IsEmpty returns whether or not the stack is empty. +func (s *ListStack) IsEmpty() bool { + return s.first == nil +} + +// Size returns the number of elements in the stack. +func (s *ListStack) Size() uint64 { + return s.size +} + +// SliceStack implements a stack backed by a growing slice. Useful for memory +// constrained environments. It also has better cache locality. +type SliceStack struct { + size uint64 + backing []interface{} +} + +// Push adds an element to the top of the stack. +func (s *SliceStack) Push(item interface{}) { + s.size++ + s.backing = append(s.backing, item) +} + +// Peek returns the latest added element without removing it from the stack. +func (s *SliceStack) Peek() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to peek element, stack is empty") + } + return s.backing[s.size-1], nil +} + +// Pop removes and return the latest added element from the stack. +func (s *SliceStack) Pop() (interface{}, error) { + if s.IsEmpty() { + return nil, errors.New("unable to pop element, stack is empty") + } + + s.size-- + item := s.backing[s.size] + s.backing = s.backing[0:s.size] + return item, nil +} + +// IsEmpty returns whether or not the stack is empty. +func (s *SliceStack) IsEmpty() bool { + return len(s.backing) == 0 +} + +// Size returns the number of elements in the stack. +func (s *SliceStack) Size() uint64 { + return s.size +} diff --git a/vendor/github.com/hooklift/iso9660/.travis.yml b/vendor/github.com/hooklift/iso9660/.travis.yml new file mode 100644 index 000000000000..40ea7c80c6f5 --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/.travis.yml @@ -0,0 +1,15 @@ +sudo: false +language: go + +go: + - 1.4 + - 1.5 + - 1.8 + - tip + +matrix: + allow_failures: + - go: tip + +install: + - make deps diff --git a/vendor/github.com/hooklift/iso9660/CONTRIBUTING.md b/vendor/github.com/hooklift/iso9660/CONTRIBUTING.md new file mode 100644 index 000000000000..9e90de7c463d --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/CONTRIBUTING.md @@ -0,0 +1,51 @@ +### Thanks for your interest in contributing to this project and for taking the time to read this guide. + +## Code of conduct +*Taken from http://libvirt.org/governance.html with minor adjustments.* + +The open source community covers people from a wide variety of countries, backgrounds and positions. This global diversity is a great strength for this project, but can also lead to communication issues, which may in turn cause unhappiness. To maximize happiness of the project community taken as a whole, all members (whether users, contributors or committers) are expected to abide by the project's code of conduct. At a high level the code can be summarized as "be excellent to each other". Expanding on this: + +**Be respectful:** disagreements between people are to be expected and are usually the sign of healthy debate and engagement. Disagreements can lead to frustration and even anger for some members. Turning to personal insults, intimidation or threatening behavior does not improve the situation. Participants should thus take care to ensure all communications / interactions stay professional at all times. + +**Be considerate:** remember that the community has members with a diverse background many of whom have English as a second language. What might appear impolite, may simply be a result of a lack of knowledge of the English language. Bear in mind that actions will have an impact on other community members and the project as a whole, so take potential consequences into account before pursuing a course of action. + +**Be forgiving:** humans are fallible and as such prone to make mistakes and inexplicably change their positions at times. Don't assume that other members are acting with malicious intent. Be prepared to forgive people who make mistakes and assist each other in learning from them. Playing a blame game doesn't help anyone. + +## Issues +* Before reporting an issue make sure you search first if anybody has already reported a similar issue and whether or not it has been fixed. +* Make sure your issue report sufficiently details the problem. +* Include code samples reproducing the issue. +* Please do not derail or troll issues. Keep the discussion on topic and respect the Code of conduct. +* If you want to tackle any open issue, make sure you let people know you are working on it. + +## Development workflow +Go is unlike any other language in that it forces a specific development workflow and project structure. Trying to fight it is useless, frustrating and time consuming. So, you better be prepare to adapt your workflow when contributing to Go projects. + +### Prerequisites +* **Go**: To install Go please follow its installation guide at https://golang.org/doc/install +* **Git:** brew install git + +### Pull Requests +* Please be generous describing your changes. +* Although it is highly suggested to include tests, they are not a hard requirement in order to get your contributions accepted. +* Keep pull requests small so core developers can review them quickly. + +### Workflow for third-party code contributions +* In Github, fork `https://github.com/hooklift/iso9660.git` to your own account +* Get the package using "go get": `go get github.com/hooklift/iso9660` +* Move to where the package was cloned: `cd $GOPATH/src/github.com/hooklift/iso9660` +* Add a git remote pointing to your own fork: `git remote add downstream git@github.com:/iso9660.git` +* Create a branch for making your changes, then commit them. +* Push changes to downstream repository, this is your own fork: `git push downstream` +* In Github, from your fork, create the Pull Request and send it upstream. +* You are done. + + +### Workflow for core developers +Since core developers usually have access to the upstream repository, there is no need for having a workflow like the one for thid-party contributors. + +* Get the package using "go get": `go get github.com/hooklift/iso9660` +* Create a branch for making your changes, then commit them. +* Push changes to the repository: `git push origin ` +* In Github, create the Pull Request from your branch to master. +* Before merging into master, wait for at least two developers to code review your contribution. diff --git a/vendor/github.com/hooklift/iso9660/LICENSE b/vendor/github.com/hooklift/iso9660/LICENSE new file mode 100644 index 000000000000..52d135112eeb --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/LICENSE @@ -0,0 +1,374 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hooklift/iso9660/Makefile b/vendor/github.com/hooklift/iso9660/Makefile new file mode 100644 index 000000000000..03b588a4e28c --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/Makefile @@ -0,0 +1,12 @@ +GHACCOUNT := hooklift +NAME := iso9660 +VERSION := v1.0.0 + +include common.mk + +deps: + go get github.com/c4milo/github-release + go get github.com/mitchellh/gox + go get github.com/docopt/docopt-go + go get github.com/c4milo/gotoolkit + go get github.com/hooklift/assert diff --git a/vendor/github.com/hooklift/iso9660/README.md b/vendor/github.com/hooklift/iso9660/README.md new file mode 100644 index 000000000000..8a529a4a96ef --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/README.md @@ -0,0 +1,25 @@ +# iso9660 +[![GoDoc](https://godoc.org/github.com/hooklift/iso9660?status.svg)](https://godoc.org/github.com/hooklift/iso9660) +[![Build Status](https://travis-ci.org/hooklift/iso9660.svg?branch=master)](https://travis-ci.org/hooklift/iso9660) + +Go library and CLI to extract data from ISO9660 images. + +### CLI +``` +$ ./iso9660 +Usage: + iso9660 + iso9660 -h | --help + iso9660 --version +``` + +### Library +An example on how to use the library to extract files and directories from an ISO image can be found in our CLI source code at: +https://github.com/hooklift/iso9660/blob/master/cmd/iso9660/main.go + +### Not supported +* Reading files recorded in interleave mode +* Multi-extent or reading individual files larger than 4GB +* Joliet extensions, meaning that file names longer than 32 characters are going to be truncated. Unicode characters are not going to be properly decoded either. +* Multisession extension +* Rock Ridge extension, making unable to return recorded POSIX permissions, timestamps as well as owner and group for files and directories. diff --git a/vendor/github.com/hooklift/iso9660/common.mk b/vendor/github.com/hooklift/iso9660/common.mk new file mode 100644 index 000000000000..35b67b4403bb --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/common.mk @@ -0,0 +1,43 @@ +PLATFORM := $(shell go env | grep GOHOSTOS | cut -d '"' -f 2) +ARCH := $(shell go env | grep GOARCH | cut -d '"' -f 2) +BRANCH := $(shell git rev-parse --abbrev-ref HEAD) +LDFLAGS := -ldflags "-X main.Version=$(VERSION) -X main.Name=$(NAME)" + +test: + go test ./... + +build: + go build -o build/$(NAME) $(LDFLAGS) cmd/$(NAME)/main.go + +install: + go install $(LDFLAGS) + +compile: + @rm -rf build/ + @gox $(LDFLAGS) \ + -osarch="darwin/amd64" \ + -os="linux" \ + -os="solaris" \ + -os="freebsd" \ + -os="windows" \ + -output "build/$(NAME)_$(VERSION)_{{.OS}}_{{.Arch}}/$(NAME)" \ + ./... + +dist: compile + $(eval FILES := $(shell ls build)) + @rm -rf dist && mkdir dist + @for f in $(FILES); do \ + (cd $(shell pwd)/build/$$f && tar -cvzf ../../dist/$$f.tar.gz *); \ + (cd $(shell pwd)/dist && shasum -a 512 $$f.tar.gz > $$f.sha512); \ + echo $$f; \ + done + +release: dist + @latest_tag=$$(git describe --tags `git rev-list --tags --max-count=1`); \ + comparison="$$latest_tag..HEAD"; \ + if [ -z "$$latest_tag" ]; then comparison=""; fi; \ + changelog=$$(git log $$comparison --oneline --no-merges); \ + github-release $(GHACCOUNT)/$(NAME) $(VERSION) $(BRANCH) "**Changelog**
$$changelog" 'dist/*'; \ + git pull + +.PHONY: test build install compile deps dist release diff --git a/vendor/github.com/hooklift/iso9660/iso9660.go b/vendor/github.com/hooklift/iso9660/iso9660.go new file mode 100644 index 000000000000..c5a114cd91ef --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/iso9660.go @@ -0,0 +1,418 @@ +// Package iso9660 implements ECMA-119 standard, also known as ISO 9660. +// +// References: +// +// * https://en.wikipedia.org/wiki/ISO_9660 +// +// * http://alumnus.caltech.edu/~pje/iso9660.html +// +// * http://users.telenet.be/it3.consultants.bvba/handouts/ISO9960.html +// +// * http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf +// +// * http://www.drdobbs.com/database/inside-the-iso-9660-filesystem-format/184408899 +// +// * http://www.cdfs.com +// +// * http://wiki.osdev.org/ISO_9660 +package iso9660 + +import ( + "io" + "os" + "strings" + "time" +) + +// File represents a concrete implementation of os.FileInfo interface for +// accessing ISO 9660 file data +type File struct { + DirectoryRecord + fileID string + // We have the raw image here only to be able to access file extents + image *os.File +} + +// Name returns the file's name. +func (f *File) Name() string { + name := strings.Split(f.fileID, ";")[0] + return strings.ToLower(name) +} + +// Size returns the file size in bytes +func (f *File) Size() int64 { + return int64(f.ExtentLengthBE) +} + +// Mode returns file's mode and permissions bits. Since we don't yet support +// Rock Ridge extensions we cannot extract POSIX permissions and the rest of the +// normal metadata. So, right we return 0740 for directories and 0640 for files. +func (f *File) Mode() os.FileMode { + if f.IsDir() { + return os.FileMode(0740) + } + return os.FileMode(0640) +} + +// ModTime returns file's modification time. +func (f *File) ModTime() time.Time { + return time.Now() +} + +// IsDir tells whether the file is a directory or not. +func (f *File) IsDir() bool { + if (f.FileFlags & 2) == 2 { + return true + } + return false +} + +// Sys returns io.Reader instance pointing to the file's content if it is not a directory, nil otherwise. +func (f *File) Sys() interface{} { + if f.IsDir() { + return nil + } + + return io.NewSectionReader(f.image, int64(f.ExtentLocationBE*sectorSize), int64(f.ExtentLengthBE)) +} + +const ( + bootRecord = 0 + primaryVol = 1 + supplementaryVol = 2 + volPartition = 3 + volSetTerminator = 255 + // System area goes from sectors 0x00 to 0x0F. Volume descriptors can be + // found starting at sector 0x10 + dataAreaSector = 0x10 + sectorSize = 2048 +) + +// VolumeDescriptor identify the volume, the partitions recorded on the volume, +// the volume creator(s), certain attributes of the volume, the location of +// other recorded descriptors and the version of the standard which applies +// to the volume descriptor. +// +// When preparing to mount a CD, your first action will be reading the volume +// descriptors (specifically, you will be looking for the Primary Volume Descriptor). +// Since sectors 0x00-0x0F of the CD are reserved as System Area, the Volume +// Descriptors can be found starting at sector 0x10. +type VolumeDescriptor struct { + // 0: BootRecord + // 1: Primary Volume Descriptor + // 2: Supplementary Volume Descriptor + // 3: Volume Partition Descriptor + // 4-254: Reserved + // 255: Volume Descriptor Set Terminator + Type byte + // Always "CD001". + StandardID [5]byte + //Volume Descriptor Version (0x01). + Version byte +} + +// BootRecord identifies a system which can recognize and act upon the content +// of the field reserved for boot system use in the Boot Record, and shall +// contain information which is used to achieve a specific state for a system or +// for an application. +type BootRecord struct { + VolumeDescriptor + SystemID [32]byte + ID [32]byte + SystemUse [1977]byte +} + +// Terminator indicates the termination of a Volume Descriptor Set. +type Terminator struct { + VolumeDescriptor + // All bytes of this field are set to (00). + Reserved [2041]byte +} + +// PrimaryVolumePart1 represents the Primary Volume Descriptor first half, before the +// root directory record. We are only reading big-endian values so placeholders +// are used for little-endian ones. +type PrimaryVolumePart1 struct { + VolumeDescriptor + // Unused + _ byte // 00 + // The name of the system that can act upon sectors 0x00-0x0F for the volume. + SystemID [32]byte + // Identification of this volume. + ID [32]byte + //Unused2 + _ [8]byte + // Amount of data available on the CD-ROM. Ignores little-endian order. + // Takes big-endian encoded value. + VolumeSpaceSizeLE int32 + VolumeSpaceSizeBE int32 + Unused2 [32]byte + // The size of the set in this logical volume (number of disks). Ignores + // little-endian order. Takes big-endian encoded value. + VolumeSetSizeLE int16 + VolumeSetSizeBE int16 + // The number of this disk in the Volume Set. Ignores little-endian order. + // Takes big-endian encoded value. + VolumeSeqNumberLE int16 + VolumeSeqNumberBE int16 + // The size in bytes of a logical block. NB: This means that a logical block + // on a CD could be something other than 2 KiB! + LogicalBlkSizeLE int16 + LogicalBlkSizeBE int16 + // The size in bytes of the path table. Ignores little-endian order. + // Takes big-endian encoded value. + PathTableSizeLE int32 + PathTableSizeBE int32 + // LBA location of the path table. The path table pointed to contains only + // little-endian values. + LocPathTableLE int32 + // LBA location of the optional path table. The path table pointed to contains + // only little-endian values. Zero means that no optional path table exists. + LocOptPathTableLE int32 + // LBA location of the path table. The path table pointed to contains + // only big-endian values. + LocPathTableBE int32 + // LBA location of the optional path table. The path table pointed to contains + // only big-endian values. Zero means that no optional path table exists. + LocOptPathTableBE int32 +} + +// DirectoryRecord describes the characteristics of a file or directory, +// beginning with a length octet describing the size of the entire entry. +// Entries themselves are of variable length, up to 255 octets in size. +// Attributes for the file described by the directory entry are stored in the +// directory entry itself (unlike UNIX). +// The root directory entry is a variable length object, so that the name can be of variable length. +// +// Important: before each entry there can be "fake entries" to support the Long File Name. +// +// Even if a directory spans multiple sectors, the directory entries are not +// permitted to cross the sector boundary (unlike the path table). Where there +// is not enough space to record an entire directory entry at the end of a sector, +// that sector is zero-padded and the next consecutive sector is used. +// Unfortunately, the date/time format is different from that used in the Primary +// Volume Descriptor. +type DirectoryRecord struct { + // Extended Attribute Record length, stored at the beginning of + // the file's extent. + ExtendedAttrLen byte + // Location of extent (Logical Block Address) in both-endian format. + ExtentLocationLE uint32 + ExtentLocationBE uint32 + // Data length (size of extent) in both-endian format. + ExtentLengthLE uint32 + ExtentLengthBE uint32 + // Date and the time of the day at which the information in the Extent + // described by the Directory Record was recorded. + RecordedTime [7]byte + // If this Directory Record identifies a directory then bit positions 2, 3 + // and 7 shall be set to ZERO. If no Extended Attribute Record is associated + // with the File Section identified by this Directory Record then bit + // positions 3 and 4 shall be set to ZERO. -- 9.1.6 + FileFlags byte + // File unit size for files recorded in interleaved mode, zero otherwise. + FileUnitSize byte + // Interleave gap size for files recorded in interleaved mode, zero otherwise. + InterleaveGapSize byte + // Volume sequence number - the volume that this extent is recorded on, in + // 16 bit both-endian format. + VolumeSeqNumberLE uint16 + VolumeSeqNumberBE uint16 + // Length of file identifier (file name). This terminates with a ';' + // character followed by the file ID number in ASCII coded decimal ('1'). + FileIDLength byte + // The interpretation of this field depends as follows on the setting of the + // Directory bit of the File Flags field. If set to ZERO, it shall mean: + // + // − The field shall specify an identification for the file. + // − The characters in this field shall be d-characters or d1-characters, SEPARATOR 1, SEPARATOR 2. + // − The field shall be recorded as specified in 7.5. If set to ONE, it shall mean: + // − The field shall specify an identification for the directory. + // − The characters in this field shall be d-characters or d1-characters, or only a (00) byte, or only a (01) byte. + // − The field shall be recorded as specified in 7.6. + // fileID string +} + +// PrimaryVolumePart2 represents the Primary Volume Descriptor half after the +// root directory record. +type PrimaryVolumePart2 struct { + // Identifier of the volume set of which this volume is a member. + VolumeSetID [128]byte + // The volume publisher. For extended publisher information, the first byte + // should be 0x5F, followed by the filename of a file in the root directory. + // If not specified, all bytes should be 0x20. + PublisherID [128]byte + // The identifier of the person(s) who prepared the data for this volume. + // For extended preparation information, the first byte should be 0x5F, + // followed by the filename of a file in the root directory. If not specified, + // all bytes should be 0x20. + DataPreparerID [128]byte + // Identifies how the data are recorded on this volume. For extended information, + // the first byte should be 0x5F, followed by the filename of a file in the root + // directory. If not specified, all bytes should be 0x20. + AppID [128]byte + // Filename of a file in the root directory that contains copyright + // information for this volume set. If not specified, all bytes should be 0x20. + CopyrightFileID [37]byte + // Filename of a file in the root directory that contains abstract information + // for this volume set. If not specified, all bytes should be 0x20. + AbstractFileID [37]byte + // Filename of a file in the root directory that contains bibliographic + // information for this volume set. If not specified, all bytes should be 0x20. + BibliographicFileID [37]byte + // The date and time of when the volume was created. + CreationTime [17]byte + // The date and time of when the volume was modified. + ModificationTime [17]byte + // The date and time after which this volume is considered to be obsolete. + // If not specified, then the volume is never considered to be obsolete. + ExpirationTime [17]byte + // The date and time after which the volume may be used. If not specified, + // the volume may be used immediately. + EffectiveTime [17]byte + // The directory records and path table version (always 0x01). + FileStructVersion byte + // Reserved. Always 0x00. + _ byte + // Contents not defined by ISO 9660. + AppUse [512]byte + // Reserved by ISO. + _ [653]byte +} + +// PrimaryVolume descriptor acts much like the superblock of the UNIX filesystem, providing +// details on the ISO-9660 compliant portions of the disk. While we can have +// many kinds of filesystems on a single ISO-9660 CD-ROM, we can have only one +// ISO-9660 file structure (found as the primary volume-descriptor type). +// +// Directory entries are successively stored within this region. Evaluation of +// the ISO 9660 filenames is begun at this location. The root directory is stored +// as an extent, or sequential series of sectors, that contains each of the +// directory entries appearing in the root. +// +// Since ISO 9660 works by segmenting the CD-ROM into logical blocks, the size +// of these blocks is found in the primary volume descriptor as well. +type PrimaryVolume struct { + PrimaryVolumePart1 + DirectoryRecord DirectoryRecord + PrimaryVolumePart2 +} + +// SupplementaryVolume is used by Joliet. +type SupplementaryVolume struct { + VolumeDescriptor + Flags int `struc:"int8"` + SystemID string `struc:"[32]byte"` + ID string `struc:"[32]byte"` + Unused byte + VolumeSpaceSize int `struc:"int32"` + EscapeSequences string `struc:"[32]byte"` + VolumeSetSize int `struc:"int16"` + VolumeSeqNumber int `struc:"int16"` + LogicalBlkSize int `struc:"int16"` + PathTableSize int `struc:"int32"` + LocLPathTable int `struc:"int32"` + LocOptLPathTable int `struc:"int32"` + LocMPathTable int `struc:"int32"` + LocOptMPathTable int `struc:"int32"` + RootDirRecord DirectoryRecord + VolumeSetID string `struc:"[128]byte"` + PublisherID string `struc:"[128]byte"` + DataPreparerID string `struc:"[128]byte"` + AppID string `struc:"[128]byte"` + CopyrightFileID string `struc:"[37]byte"` + AbstractFileID string `struc:"[37]byte"` + BibliographicFileID string `struc:"[37]byte"` + CreationTime Timestamp + ModificationTime Timestamp + ExpirationTime Timestamp + EffectiveTime Timestamp + FileStructVersion int `struc:"int8"` + Reserved byte + AppData [512]byte + Reserved2 byte +} + +// PartitionVolume ... +type PartitionVolume struct { + VolumeDescriptor + Unused byte + SystemID string `struc:"[32]byte"` + ID string `struc:"[32]byte"` + Location int `struc:"int8"` + Size int `struc:"int8"` + SystemUse [1960]byte +} + +// Timestamp ... +type Timestamp struct { + Year int `struc:"[4]byte"` + Month int `struc:"[2]byte"` + DayOfMonth int `struc:"[2]byte"` + Hour int `struc:"[2]byte"` + Minute int `struc:"[2]byte"` + Second int `struc:"[2]byte"` + Millisecond int `struc:"[2]byte"` + GMTOffset int `struc:"uint8"` +} + +// ExtendedAttrRecord are simply a way to extend the attributes of files. +// Since attributes vary according to the user, most everyone has a different +// opinion on what a file attribute should specify. +type ExtendedAttrRecord struct { + OwnerID int `struc:"int16"` + GroupID int `struc:"int16"` + Permissions int `struc:"int16"` + CreationTime Timestamp + ModificationTime Timestamp + ExpirationTime Timestamp + // Specifies the date and the time of the day at which the information in + // the file may be used. If the date and time are not specified then the + // information may be used at once. + EffectiveTime Timestamp + Format int `struc:"uint8"` + Attributes int `struc:"uint8"` + Length int `struc:"int16"` + SystemID string `struc:"[32]byte"` + SystemUse [64]byte + Version int `struc:"uint8"` + EscapeSeqLength int `struc:"uint8"` + Reserved [64]byte + AppUseLength int `struc:"int16,sizeof=AppUse"` + AppUse []byte + EscapeSequences []byte `struc:"sizefrom=AppUseLength"` +} + +// PathTable contains a well-ordered sequence of records describing every +// directory extent on the CD. There are some exceptions with this: the Path +// Table can only contain 65536 records, due to the length of the "Parent Directory Number" field. +// If there are more than this number of directories on the disc, some CD +// authoring software will ignore this limit and create a non-compliant +// CD (this applies to some earlier versions of Nero, for example). If your +// file system uses the path table, you should be aware of this possibility. +// Windows uses the Path Table and will fail with such non-compliant +// CD's (additional nodes exist but appear as zero-byte). Linux, which uses +// the directory tables is not affected by this issue. The location of the path +// tables can be found in the Primary Volume Descriptor. There are two table types +// - the L-Path table (relevant to x86) and the M-Path table. The only +// difference between these two tables is that multi-byte values in the L-Table +// are LSB-first and the values in the M-Table are MSB-first. +// +// The path table is in ascending order of directory level and is alphabetically +// sorted within each directory level. +type PathTable struct { + DirIDLength int `struc:"uint8,sizeof=DirName"` + ExtendedAttrsLen int `struc:"uint8"` + // Number the Logical Block Number of the first Logical Block allocated to + // the Extent in which the directory is recorded. + // This is in a different format depending on whether this is the L-Table or + // M-Table (see explanation above). + ExtentLocation int `struc:"int32"` + // Number of record for parent directory (or 1 for the root directory), as a + // word; the first record is number 1, the second record is number 2, etc. + // Directory number of parent directory (an index in to the path table). + // This is the field that limits the table to 65536 records. + ParentDirNumber int `struc:"int16"` + // Directory Identifier (name) in d-characters. + DirName string +} diff --git a/vendor/github.com/hooklift/iso9660/reader.go b/vendor/github.com/hooklift/iso9660/reader.go new file mode 100644 index 000000000000..1c7d00a66cc5 --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/reader.go @@ -0,0 +1,251 @@ +package iso9660 + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/c4milo/gotoolkit" +) + +var ( + // ErrInvalidImage is returned when an attempt to unpack the image Primary Volume Descriptor failed or + // when the end of the image was reached without finding a primary volume descriptor + ErrInvalidImage = func(err error) error { return fmt.Errorf("invalid-iso9660-image: %s", err) } + // ErrCorruptedImage is returned when a seek operation, on the image, failed. + ErrCorruptedImage = func(err error) error { return fmt.Errorf("corrupted-image: %s", err) } +) + +// Reader defines the state of the ISO9660 image reader. It needs to be instantiated +// from its constructor. +type Reader struct { + // File descriptor to the opened ISO image + image *os.File + // Copy of unencoded Primary Volume Descriptor + pvd PrimaryVolume + // Queue used to walk through file system iteratively + queue gotoolkit.Queue + // Current sector + sector uint32 + // Current bytes read from current sector. + read uint32 +} + +// NewReader creates a new ISO 9660 image reader. +func NewReader(rs *os.File) (*Reader, error) { + // Starts reading from image data area + sector := dataAreaSector + // Iterates over volume descriptors until it finds the primary volume descriptor + // or an error condition. + for { + offset, err := rs.Seek(int64(sector*sectorSize), os.SEEK_SET) + if err != nil { + return nil, ErrCorruptedImage(err) + } + + var volDesc VolumeDescriptor + if err := binary.Read(rs, binary.BigEndian, &volDesc); err != nil { + return nil, ErrCorruptedImage(err) + } + + if volDesc.Type == primaryVol { + // backs up to the beginning of the sector again in order to unpack + // the entire primary volume descriptor more easily. + if _, err := rs.Seek(offset, os.SEEK_SET); err != nil { + return nil, ErrCorruptedImage(err) + } + + reader := new(Reader) + reader.image = rs + reader.queue = new(gotoolkit.SliceQueue) + + if err := reader.unpackPVD(); err != nil { + return nil, ErrCorruptedImage(err) + } + + return reader, nil + } + + if volDesc.Type == volSetTerminator { + return nil, ErrInvalidImage(errors.New("Volume Set Terminator reached. A Primary Volume Descriptor was not found.")) + } + sector++ + } +} + +// Skip skips the given number of directory records. +func (r *Reader) Skip(n int) error { + var drecord File + var len byte + var err error + for i := 0; i < n; i++ { + if len, err = r.unpackDRecord(&drecord); err != nil { + return err + } + r.read += uint32(len) + } + return nil +} + +// Next moves onto the next directory record present in the image. +// It does not use the Path Table since the goal is to read everything +// from the ISO image. +func (r *Reader) Next() (os.FileInfo, error) { + if r.queue.IsEmpty() { + return nil, io.EOF + } + + // We only dequeue the directory when it does not contain more children + // or when it is empty and there is no children to iterate over. + item, err := r.queue.Peek() + if err != nil { + panic(err) + } + + f := item.(File) + if r.sector == 0 { + r.sector = f.ExtentLocationBE + _, err := r.image.Seek(int64(r.sector*sectorSize), os.SEEK_SET) + if err != nil { + return nil, ErrCorruptedImage(err) + } + + // Skips . and .. directories + if err = r.Skip(2); err != nil { + return nil, ErrCorruptedImage(err) + } + } + + var drecord File + var len byte + if (r.read % sectorSize) == 0 { + r.sector++ + _, err := r.image.Seek(int64(r.sector*sectorSize), os.SEEK_SET) + if err != nil { + return nil, ErrCorruptedImage(err) + } + } + + if len, err = r.unpackDRecord(&drecord); err != nil && err != io.EOF { + return nil, ErrCorruptedImage(err) + } + r.read += uint32(len) + + if err == io.EOF { + // directory record is empty, sector space wasted, move onto next sector. + rsize := (sectorSize - (r.read % sectorSize)) + buf := make([]byte, rsize) + if err := binary.Read(r.image, binary.BigEndian, buf); err != nil { + return nil, ErrCorruptedImage(err) + } + r.read += rsize + } + + // If there is no more entries in the current directory, dequeue it. + if r.read >= f.ExtentLengthBE { + r.read = 0 + r.sector = 0 + r.queue.Dequeue() + } + + // End of directory listing, drecord is empty so we don't bother + // to return it and keep iterating to look for the next actual + // directory or file. + if drecord.fileID == "" { + return r.Next() + } + + parent := f.Name() + if parent == "\x00" { + parent = "/" + } + drecord.fileID = filepath.Join(parent, drecord.fileID) + + if drecord.IsDir() { + r.queue.Enqueue(drecord) + } else { + drecord.image = r.image + } + + return &drecord, nil +} + +// unpackDRecord unpacks directory record bits into Go's struct +func (r *Reader) unpackDRecord(f *File) (byte, error) { + // Gets the directory record length + var len byte + if err := binary.Read(r.image, binary.BigEndian, &len); err != nil { + return len, ErrCorruptedImage(err) + } + + if len == 0 { + return len + 1, io.EOF + } + + // Reads directory record into Go struct + var drecord DirectoryRecord + if err := binary.Read(r.image, binary.BigEndian, &drecord); err != nil { + return len, ErrCorruptedImage(err) + } + + f.DirectoryRecord = drecord + // Gets the name + name := make([]byte, drecord.FileIDLength) + if err := binary.Read(r.image, binary.BigEndian, name); err != nil { + return len, ErrCorruptedImage(err) + } + f.fileID = string(name) + + // Padding field as per section 9.1.12 in ECMA-119 + if (drecord.FileIDLength % 2) == 0 { + var zero byte + if err := binary.Read(r.image, binary.BigEndian, &zero); err != nil { + return len, ErrCorruptedImage(err) + } + } + + // System use field as per section 9.1.13 in ECMA-119 + // Directory record has 34 bytes in addition to the name's + // variable length and the padding field mentioned in section 9.1.12 + totalLen := 34 + drecord.FileIDLength - (drecord.FileIDLength % 2) + sysUseLen := int64(len - totalLen) + if sysUseLen > 0 { + sysData := make([]byte, sysUseLen) + if err := binary.Read(r.image, binary.BigEndian, sysData); err != nil { + return len, ErrCorruptedImage(err) + } + } + return len, nil +} + +// unpackPVD unpacks Primary Volume Descriptor in three phases. This is +// because the root directory record is a variable-length record and Go's binary +// package doesn't support unpacking variable-length structs easily. +func (r *Reader) unpackPVD() error { + // Unpack first half + var pvd1 PrimaryVolumePart1 + if err := binary.Read(r.image, binary.BigEndian, &pvd1); err != nil { + return ErrCorruptedImage(err) + } + r.pvd.PrimaryVolumePart1 = pvd1 + + // Unpack root directory record + var drecord File + if _, err := r.unpackDRecord(&drecord); err != nil { + return ErrCorruptedImage(err) + } + r.pvd.DirectoryRecord = drecord.DirectoryRecord + r.queue.Enqueue(drecord) + + // Unpack second half + var pvd2 PrimaryVolumePart2 + if err := binary.Read(r.image, binary.BigEndian, &pvd2); err != nil { + return ErrCorruptedImage(err) + } + r.pvd.PrimaryVolumePart2 = pvd2 + + return nil +} diff --git a/vendor/github.com/hooklift/iso9660/writer.go b/vendor/github.com/hooklift/iso9660/writer.go new file mode 100644 index 000000000000..f23a9f7f7f78 --- /dev/null +++ b/vendor/github.com/hooklift/iso9660/writer.go @@ -0,0 +1 @@ +package iso9660 diff --git a/vendor/github.com/mitchellh/go-ps/.gitignore b/vendor/github.com/mitchellh/go-ps/.gitignore new file mode 100644 index 000000000000..a977916f6583 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/.gitignore @@ -0,0 +1 @@ +.vagrant/ diff --git a/vendor/github.com/mitchellh/go-ps/.travis.yml b/vendor/github.com/mitchellh/go-ps/.travis.yml new file mode 100644 index 000000000000..8f794f71da43 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/.travis.yml @@ -0,0 +1,4 @@ +language: go + +go: + - 1.2.1 diff --git a/vendor/github.com/mitchellh/go-ps/LICENSE.md b/vendor/github.com/mitchellh/go-ps/LICENSE.md new file mode 100644 index 000000000000..229851590442 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/mitchellh/go-ps/README.md b/vendor/github.com/mitchellh/go-ps/README.md new file mode 100644 index 000000000000..8e8baf9d2605 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/README.md @@ -0,0 +1,34 @@ +# Process List Library for Go + +go-ps is a library for Go that implements OS-specific APIs to list and +manipulate processes in a platform-safe way. The library can find and +list processes on Linux, Mac OS X, Solaris, and Windows. + +If you're new to Go, this library has a good amount of advanced Go educational +value as well. It uses some advanced features of Go: build tags, accessing +DLL methods for Windows, cgo for Darwin, etc. + +How it works: + + * **Darwin** uses the `sysctl` syscall to retrieve the process table. + * **Unix** uses the procfs at `/proc` to inspect the process tree. + * **Windows** uses the Windows API, and methods such as + `CreateToolhelp32Snapshot` to get a point-in-time snapshot of + the process table. + +## Installation + +Install using standard `go get`: + +``` +$ go get github.com/mitchellh/go-ps +... +``` + +## TODO + +Want to contribute? Here is a short TODO list of things that aren't +implemented for this library that would be nice: + + * FreeBSD support + * Plan9 support diff --git a/vendor/github.com/mitchellh/go-ps/Vagrantfile b/vendor/github.com/mitchellh/go-ps/Vagrantfile new file mode 100644 index 000000000000..61662ab1e3e7 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/Vagrantfile @@ -0,0 +1,43 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "chef/ubuntu-12.04" + + config.vm.provision "shell", inline: $script + + ["vmware_fusion", "vmware_workstation"].each do |p| + config.vm.provider "p" do |v| + v.vmx["memsize"] = "1024" + v.vmx["numvcpus"] = "2" + v.vmx["cpuid.coresPerSocket"] = "1" + end + end +end + +$script = <