mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #61432 from filbranden/killrkt1
Automatic merge from submit-queue (batch tested with PRs 61904, 61565, 61401, 61432, 61772). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Remove rktnetes code **What this PR does / why we need it**: rktnetes is scheduled to be deprecated in 1.10 (#53601). According to the deprecation policy for beta CLI and flags, we can remove the feature in 1.11. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #58721 **Special notes for your reviewer**: **Release note**: ```release-note Removed rknetes code, which was deprecated in 1.10. ``` /assign @yujuhong /hold Hold until the end of the freeze.
This commit is contained in:
		
							
								
								
									
										31
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										31
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -141,26 +141,6 @@
 | 
				
			|||||||
			"ImportPath": "github.com/abbot/go-http-auth",
 | 
								"ImportPath": "github.com/abbot/go-http-auth",
 | 
				
			||||||
			"Rev": "c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35"
 | 
								"Rev": "c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "github.com/appc/spec/schema",
 | 
					 | 
				
			||||||
			"Comment": "v0.8.9-17-gfc380db",
 | 
					 | 
				
			||||||
			"Rev": "fc380db5fc13c6dd71a5b0bf2af0d182865d1b1d"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "github.com/appc/spec/schema/common",
 | 
					 | 
				
			||||||
			"Comment": "v0.8.9-17-gfc380db",
 | 
					 | 
				
			||||||
			"Rev": "fc380db5fc13c6dd71a5b0bf2af0d182865d1b1d"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "github.com/appc/spec/schema/types",
 | 
					 | 
				
			||||||
			"Comment": "v0.8.9-17-gfc380db",
 | 
					 | 
				
			||||||
			"Rev": "fc380db5fc13c6dd71a5b0bf2af0d182865d1b1d"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "github.com/appc/spec/schema/types/resource",
 | 
					 | 
				
			||||||
			"Comment": "v0.8.9-17-gfc380db",
 | 
					 | 
				
			||||||
			"Rev": "fc380db5fc13c6dd71a5b0bf2af0d182865d1b1d"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/armon/circbuf",
 | 
								"ImportPath": "github.com/armon/circbuf",
 | 
				
			||||||
			"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
 | 
								"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
 | 
				
			||||||
@@ -928,11 +908,6 @@
 | 
				
			|||||||
			"Comment": "v14",
 | 
								"Comment": "v14",
 | 
				
			||||||
			"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
 | 
								"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "github.com/coreos/go-systemd/unit",
 | 
					 | 
				
			||||||
			"Comment": "v14",
 | 
					 | 
				
			||||||
			"Rev": "48702e0da86bd25e76cfef347e2adeb434a0d0a6"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/go-systemd/util",
 | 
								"ImportPath": "github.com/coreos/go-systemd/util",
 | 
				
			||||||
			"Comment": "v14",
 | 
								"Comment": "v14",
 | 
				
			||||||
@@ -1229,12 +1204,10 @@
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/garyburd/redigo/internal",
 | 
								"ImportPath": "github.com/garyburd/redigo/internal",
 | 
				
			||||||
			"Comment": "v1.0.0-1-gb8dc900",
 | 
					 | 
				
			||||||
			"Rev": "b8dc90050f24c1a73a52f107f3f575be67b21b7c"
 | 
								"Rev": "b8dc90050f24c1a73a52f107f3f575be67b21b7c"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/garyburd/redigo/redis",
 | 
								"ImportPath": "github.com/garyburd/redigo/redis",
 | 
				
			||||||
			"Comment": "v1.0.0-1-gb8dc900",
 | 
					 | 
				
			||||||
			"Rev": "b8dc90050f24c1a73a52f107f3f575be67b21b7c"
 | 
								"Rev": "b8dc90050f24c1a73a52f107f3f575be67b21b7c"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -2815,10 +2788,6 @@
 | 
				
			|||||||
			"Comment": "v1.0-13-g5292687",
 | 
								"Comment": "v1.0-13-g5292687",
 | 
				
			||||||
			"Rev": "5292687f5379e01054407da44d7c4590a61fd3de"
 | 
								"Rev": "5292687f5379e01054407da44d7c4590a61fd3de"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"ImportPath": "go4.org/errorutil",
 | 
					 | 
				
			||||||
			"Rev": "03efcb870d84809319ea509714dd6d19a1498483"
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "golang.org/x/crypto/bcrypt",
 | 
								"ImportPath": "golang.org/x/crypto/bcrypt",
 | 
				
			||||||
			"Rev": "49796115aa4b964c318aad4f3084fdb41e9aa067"
 | 
								"Rev": "49796115aa4b964c318aad4f3084fdb41e9aa067"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1249
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1249
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -84,8 +84,6 @@ CONTAINER_RUNTIME=${KUBE_CONTAINER_RUNTIME:-docker}
 | 
				
			|||||||
CONTAINER_RUNTIME_ENDPOINT=${KUBE_CONTAINER_RUNTIME_ENDPOINT:-}
 | 
					CONTAINER_RUNTIME_ENDPOINT=${KUBE_CONTAINER_RUNTIME_ENDPOINT:-}
 | 
				
			||||||
CONTAINER_RUNTIME_NAME=${KUBE_CONTAINER_RUNTIME_NAME:-}
 | 
					CONTAINER_RUNTIME_NAME=${KUBE_CONTAINER_RUNTIME_NAME:-}
 | 
				
			||||||
LOAD_IMAGE_COMMAND=${KUBE_LOAD_IMAGE_COMMAND:-}
 | 
					LOAD_IMAGE_COMMAND=${KUBE_LOAD_IMAGE_COMMAND:-}
 | 
				
			||||||
RKT_VERSION=${KUBE_RKT_VERSION:-1.23.0}
 | 
					 | 
				
			||||||
RKT_STAGE1_IMAGE=${KUBE_RKT_STAGE1_IMAGE:-coreos.com/rkt/stage1-coreos}
 | 
					 | 
				
			||||||
# MASTER_EXTRA_METADATA is the extra instance metadata on master instance separated by commas.
 | 
					# MASTER_EXTRA_METADATA is the extra instance metadata on master instance separated by commas.
 | 
				
			||||||
MASTER_EXTRA_METADATA=${KUBE_MASTER_EXTRA_METADATA:-${KUBE_EXTRA_METADATA:-}}
 | 
					MASTER_EXTRA_METADATA=${KUBE_MASTER_EXTRA_METADATA:-${KUBE_EXTRA_METADATA:-}}
 | 
				
			||||||
# MASTER_EXTRA_METADATA is the extra instance metadata on node instance separated by commas.
 | 
					# MASTER_EXTRA_METADATA is the extra instance metadata on node instance separated by commas.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,8 +83,6 @@ CONTAINER_RUNTIME_ENDPOINT=${KUBE_CONTAINER_RUNTIME_ENDPOINT:-}
 | 
				
			|||||||
CONTAINER_RUNTIME_NAME=${KUBE_CONTAINER_RUNTIME_NAME:-}
 | 
					CONTAINER_RUNTIME_NAME=${KUBE_CONTAINER_RUNTIME_NAME:-}
 | 
				
			||||||
LOAD_IMAGE_COMMAND=${KUBE_LOAD_IMAGE_COMMAND:-}
 | 
					LOAD_IMAGE_COMMAND=${KUBE_LOAD_IMAGE_COMMAND:-}
 | 
				
			||||||
GCI_DOCKER_VERSION=${KUBE_GCI_DOCKER_VERSION:-}
 | 
					GCI_DOCKER_VERSION=${KUBE_GCI_DOCKER_VERSION:-}
 | 
				
			||||||
RKT_VERSION=${KUBE_RKT_VERSION:-1.23.0}
 | 
					 | 
				
			||||||
RKT_STAGE1_IMAGE=${KUBE_RKT_STAGE1_IMAGE:-coreos.com/rkt/stage1-coreos}
 | 
					 | 
				
			||||||
# MASTER_EXTRA_METADATA is the extra instance metadata on master instance separated by commas.
 | 
					# MASTER_EXTRA_METADATA is the extra instance metadata on master instance separated by commas.
 | 
				
			||||||
MASTER_EXTRA_METADATA=${KUBE_MASTER_EXTRA_METADATA:-${KUBE_EXTRA_METADATA:-}}
 | 
					MASTER_EXTRA_METADATA=${KUBE_MASTER_EXTRA_METADATA:-${KUBE_EXTRA_METADATA:-}}
 | 
				
			||||||
# MASTER_EXTRA_METADATA is the extra instance metadata on node instance separated by commas.
 | 
					# MASTER_EXTRA_METADATA is the extra instance metadata on node instance separated by commas.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,12 +23,10 @@ set -o errexit
 | 
				
			|||||||
set -o pipefail
 | 
					set -o pipefail
 | 
				
			||||||
set -o nounset
 | 
					set -o nounset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RKT_VERSION="v1.18.0"
 | 
					 | 
				
			||||||
DOCKER2ACI_VERSION="v0.13.0"
 | 
					DOCKER2ACI_VERSION="v0.13.0"
 | 
				
			||||||
MOUNTER_VERSION=$1
 | 
					MOUNTER_VERSION=$1
 | 
				
			||||||
DOCKER_IMAGE=docker://$2
 | 
					DOCKER_IMAGE=docker://$2
 | 
				
			||||||
MOUNTER_ACI_IMAGE=gci-mounter-${MOUNTER_VERSION}.aci
 | 
					MOUNTER_ACI_IMAGE=gci-mounter-${MOUNTER_VERSION}.aci
 | 
				
			||||||
RKT_GCS_DIR=gs://kubernetes-release/rkt/
 | 
					 | 
				
			||||||
MOUNTER_GCS_DIR=gs://kubernetes-release/gci-mounter/
 | 
					MOUNTER_GCS_DIR=gs://kubernetes-release/gci-mounter/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TMPDIR=/tmp
 | 
					TMPDIR=/tmp
 | 
				
			||||||
@@ -37,7 +35,6 @@ DOWNLOAD_DIR=$(mktemp --tmpdir=${TMPDIR} -d gci-mounter-build.XXXXXXXXXX)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Setup a staging directory
 | 
					# Setup a staging directory
 | 
				
			||||||
STAGING_DIR=$(mktemp --tmpdir=${TMPDIR} -d gci-mounter-staging.XXXXXXXXXX)
 | 
					STAGING_DIR=$(mktemp --tmpdir=${TMPDIR} -d gci-mounter-staging.XXXXXXXXXX)
 | 
				
			||||||
RKT_DIR=${STAGING_DIR}/${RKT_VERSION}
 | 
					 | 
				
			||||||
ACI_DIR=${STAGING_DIR}/gci-mounter
 | 
					ACI_DIR=${STAGING_DIR}/gci-mounter
 | 
				
			||||||
CWD=${PWD}
 | 
					CWD=${PWD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,20 +48,8 @@ function cleanup {
 | 
				
			|||||||
# Delete temporary directories on exit
 | 
					# Delete temporary directories on exit
 | 
				
			||||||
trap cleanup EXIT
 | 
					trap cleanup EXIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mkdir ${RKT_DIR}
 | 
					 | 
				
			||||||
mkdir ${ACI_DIR}
 | 
					mkdir ${ACI_DIR}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Download rkt
 | 
					 | 
				
			||||||
cd ${DOWNLOAD_DIR}
 | 
					 | 
				
			||||||
echo "Downloading rkt ${RKT_VERSION}"
 | 
					 | 
				
			||||||
wget "https://github.com/coreos/rkt/releases/download/${RKT_VERSION}/rkt-${RKT_VERSION}.tar.gz" &> /dev/null
 | 
					 | 
				
			||||||
echo "Extracting rkt ${RKT_VERSION}"
 | 
					 | 
				
			||||||
tar xzf rkt-${RKT_VERSION}.tar.gz
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Stage rkt into working directory
 | 
					 | 
				
			||||||
cp rkt-${RKT_VERSION}/rkt ${RKT_DIR}/rkt
 | 
					 | 
				
			||||||
cp rkt-${RKT_VERSION}/stage1-fly.aci ${RKT_DIR}/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Convert docker image to aci and stage it
 | 
					# Convert docker image to aci and stage it
 | 
				
			||||||
echo "Downloading docker2aci ${DOCKER2ACI_VERSION}"
 | 
					echo "Downloading docker2aci ${DOCKER2ACI_VERSION}"
 | 
				
			||||||
wget "https://github.com/appc/docker2aci/releases/download/${DOCKER2ACI_VERSION}/docker2aci-${DOCKER2ACI_VERSION}.tar.gz" &> /dev/null
 | 
					wget "https://github.com/appc/docker2aci/releases/download/${DOCKER2ACI_VERSION}/docker2aci-${DOCKER2ACI_VERSION}.tar.gz" &> /dev/null
 | 
				
			||||||
@@ -74,13 +59,9 @@ ACI_IMAGE=$(${DOWNLOAD_DIR}/docker2aci-${DOCKER2ACI_VERSION}/docker2aci ${DOCKER
 | 
				
			|||||||
cp ${ACI_IMAGE} ${ACI_DIR}/${MOUNTER_ACI_IMAGE}
 | 
					cp ${ACI_IMAGE} ${ACI_DIR}/${MOUNTER_ACI_IMAGE}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Upload the contents to gcs
 | 
					# Upload the contents to gcs
 | 
				
			||||||
echo "Uploading rkt artifacts in ${RKT_DIR} to ${RKT_GCS_DIR}"
 | 
					 | 
				
			||||||
gsutil cp -R ${RKT_DIR} ${RKT_GCS_DIR}
 | 
					 | 
				
			||||||
echo "Uploading gci mounter ACI in ${ACI_DIR} to ${MOUNTER_GCS_DIR}"
 | 
					echo "Uploading gci mounter ACI in ${ACI_DIR} to ${MOUNTER_GCS_DIR}"
 | 
				
			||||||
gsutil cp ${ACI_DIR}/${MOUNTER_ACI_IMAGE} ${MOUNTER_GCS_DIR}
 | 
					gsutil cp ${ACI_DIR}/${MOUNTER_ACI_IMAGE} ${MOUNTER_GCS_DIR}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "Upload completed"
 | 
					echo "Upload completed"
 | 
				
			||||||
echo "Update rkt, stag1-fly.aci & gci-mounter ACI versions and SHA1 in cluster/gce/gci/configure.sh"
 | 
					echo "Updated gci-mounter ACI version and SHA1 in cluster/gce/gci/configure.sh"
 | 
				
			||||||
echo "${RKT_VERSION}/rkt sha1: $(sha1sum ${RKT_DIR}/rkt)"
 | 
					 | 
				
			||||||
echo "${RKT_VERSION}/stage1-fly.aci sha1: $(sha1sum ${RKT_DIR}/stage1-fly.aci)"
 | 
					 | 
				
			||||||
echo "${MOUNTER_ACI_IMAGE} hash: $(sha1sum ${ACI_DIR}/${MOUNTER_ACI_IMAGE})"
 | 
					echo "${MOUNTER_ACI_IMAGE} hash: $(sha1sum ${ACI_DIR}/${MOUNTER_ACI_IMAGE})"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,8 +29,6 @@ const (
 | 
				
			|||||||
	// When these values are updated, also update test/e2e/framework/util.go
 | 
						// When these values are updated, also update test/e2e/framework/util.go
 | 
				
			||||||
	defaultPodSandboxImageName    = "k8s.gcr.io/pause"
 | 
						defaultPodSandboxImageName    = "k8s.gcr.io/pause"
 | 
				
			||||||
	defaultPodSandboxImageVersion = "3.1"
 | 
						defaultPodSandboxImageVersion = "3.1"
 | 
				
			||||||
	// From pkg/kubelet/rkt/rkt.go to avoid circular import
 | 
					 | 
				
			||||||
	defaultRktAPIServiceEndpoint = "localhost:15441"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -54,7 +52,6 @@ func NewContainerRuntimeOptions() *config.ContainerRuntimeOptions {
 | 
				
			|||||||
		DockerDisableSharedPID:    true,
 | 
							DockerDisableSharedPID:    true,
 | 
				
			||||||
		PodSandboxImage:           defaultPodSandboxImage,
 | 
							PodSandboxImage:           defaultPodSandboxImage,
 | 
				
			||||||
		ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
 | 
							ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
 | 
				
			||||||
		RktAPIEndpoint:            defaultRktAPIServiceEndpoint,
 | 
					 | 
				
			||||||
		ExperimentalDockershim:    false,
 | 
							ExperimentalDockershim:    false,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -196,7 +196,6 @@ pkg/kubelet/prober/results
 | 
				
			|||||||
pkg/kubelet/prober/testing
 | 
					pkg/kubelet/prober/testing
 | 
				
			||||||
pkg/kubelet/qos
 | 
					pkg/kubelet/qos
 | 
				
			||||||
pkg/kubelet/remote
 | 
					pkg/kubelet/remote
 | 
				
			||||||
pkg/kubelet/rkt
 | 
					 | 
				
			||||||
pkg/kubelet/secret
 | 
					pkg/kubelet/secret
 | 
				
			||||||
pkg/kubelet/server
 | 
					pkg/kubelet/server
 | 
				
			||||||
pkg/kubelet/server/portforward
 | 
					pkg/kubelet/server/portforward
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -205,23 +205,6 @@ else
 | 
				
			|||||||
    echo "skipped the build."
 | 
					    echo "skipped the build."
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function test_rkt {
 | 
					 | 
				
			||||||
    if [[ -n "${RKT_PATH}" ]]; then
 | 
					 | 
				
			||||||
      ${RKT_PATH} list 2> /dev/null 1> /dev/null
 | 
					 | 
				
			||||||
      if [ "$?" != "0" ]; then
 | 
					 | 
				
			||||||
        echo "Failed to successfully run 'rkt list', please verify that ${RKT_PATH} is the path of rkt binary."
 | 
					 | 
				
			||||||
        exit 1
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      rkt list 2> /dev/null 1> /dev/null
 | 
					 | 
				
			||||||
      if [ "$?" != "0" ]; then
 | 
					 | 
				
			||||||
        echo "Failed to successfully run 'rkt list', please verify that rkt is in \$PATH."
 | 
					 | 
				
			||||||
        exit 1
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Shut down anyway if there's an error.
 | 
					# Shut down anyway if there's an error.
 | 
				
			||||||
set +e
 | 
					set +e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -246,8 +229,6 @@ LOG_DIR=${LOG_DIR:-"/tmp"}
 | 
				
			|||||||
CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-"docker"}
 | 
					CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-"docker"}
 | 
				
			||||||
CONTAINER_RUNTIME_ENDPOINT=${CONTAINER_RUNTIME_ENDPOINT:-""}
 | 
					CONTAINER_RUNTIME_ENDPOINT=${CONTAINER_RUNTIME_ENDPOINT:-""}
 | 
				
			||||||
IMAGE_SERVICE_ENDPOINT=${IMAGE_SERVICE_ENDPOINT:-""}
 | 
					IMAGE_SERVICE_ENDPOINT=${IMAGE_SERVICE_ENDPOINT:-""}
 | 
				
			||||||
RKT_PATH=${RKT_PATH:-""}
 | 
					 | 
				
			||||||
RKT_STAGE1_IMAGE=${RKT_STAGE1_IMAGE:-""}
 | 
					 | 
				
			||||||
CHAOS_CHANCE=${CHAOS_CHANCE:-0.0}
 | 
					CHAOS_CHANCE=${CHAOS_CHANCE:-0.0}
 | 
				
			||||||
CPU_CFS_QUOTA=${CPU_CFS_QUOTA:-true}
 | 
					CPU_CFS_QUOTA=${CPU_CFS_QUOTA:-true}
 | 
				
			||||||
ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"false"}
 | 
					ENABLE_HOSTPATH_PROVISIONER=${ENABLE_HOSTPATH_PROVISIONER:-"false"}
 | 
				
			||||||
@@ -735,8 +716,6 @@ function start_kubelet {
 | 
				
			|||||||
        --vmodule="${LOG_SPEC}" \
 | 
					        --vmodule="${LOG_SPEC}" \
 | 
				
			||||||
        --chaos-chance="${CHAOS_CHANCE}" \
 | 
					        --chaos-chance="${CHAOS_CHANCE}" \
 | 
				
			||||||
        --container-runtime="${CONTAINER_RUNTIME}" \
 | 
					        --container-runtime="${CONTAINER_RUNTIME}" \
 | 
				
			||||||
        --rkt-path="${RKT_PATH}" \
 | 
					 | 
				
			||||||
        --rkt-stage1-image="${RKT_STAGE1_IMAGE}" \
 | 
					 | 
				
			||||||
        --hostname-override="${HOSTNAME_OVERRIDE}" \
 | 
					        --hostname-override="${HOSTNAME_OVERRIDE}" \
 | 
				
			||||||
        ${cloud_config_arg} \
 | 
					        ${cloud_config_arg} \
 | 
				
			||||||
        --address="${KUBELET_HOST}" \
 | 
					        --address="${KUBELET_HOST}" \
 | 
				
			||||||
@@ -966,10 +945,6 @@ if [ "${CONTAINER_RUNTIME}" == "docker" ] && ! kube::util::ensure_docker_daemon_
 | 
				
			|||||||
  exit 1
 | 
					  exit 1
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [[ "${CONTAINER_RUNTIME}" == "rkt" ]]; then
 | 
					 | 
				
			||||||
  test_rkt
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [[ "${START_MODE}" != "kubeletonly" ]]; then
 | 
					if [[ "${START_MODE}" != "kubeletonly" ]]; then
 | 
				
			||||||
  test_apiserver_off
 | 
					  test_apiserver_off
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -74,7 +74,6 @@ go_library(
 | 
				
			|||||||
        "//pkg/kubelet/prober:go_default_library",
 | 
					        "//pkg/kubelet/prober:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/prober/results:go_default_library",
 | 
					        "//pkg/kubelet/prober/results:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/remote:go_default_library",
 | 
					        "//pkg/kubelet/remote:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/rkt:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/secret:go_default_library",
 | 
					        "//pkg/kubelet/secret:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/server:go_default_library",
 | 
					        "//pkg/kubelet/server:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/server/portforward:go_default_library",
 | 
					        "//pkg/kubelet/server/portforward:go_default_library",
 | 
				
			||||||
@@ -281,7 +280,6 @@ filegroup(
 | 
				
			|||||||
        "//pkg/kubelet/prober:all-srcs",
 | 
					        "//pkg/kubelet/prober:all-srcs",
 | 
				
			||||||
        "//pkg/kubelet/qos:all-srcs",
 | 
					        "//pkg/kubelet/qos:all-srcs",
 | 
				
			||||||
        "//pkg/kubelet/remote:all-srcs",
 | 
					        "//pkg/kubelet/remote:all-srcs",
 | 
				
			||||||
        "//pkg/kubelet/rkt:all-srcs",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/secret:all-srcs",
 | 
					        "//pkg/kubelet/secret:all-srcs",
 | 
				
			||||||
        "//pkg/kubelet/server:all-srcs",
 | 
					        "//pkg/kubelet/server:all-srcs",
 | 
				
			||||||
        "//pkg/kubelet/stats:all-srcs",
 | 
					        "//pkg/kubelet/stats:all-srcs",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,8 +38,6 @@ func (i *imageFsInfoProvider) ImageFsInfoLabel() (string, error) {
 | 
				
			|||||||
	switch i.runtime {
 | 
						switch i.runtime {
 | 
				
			||||||
	case types.DockerContainerRuntime:
 | 
						case types.DockerContainerRuntime:
 | 
				
			||||||
		return cadvisorfs.LabelDockerImages, nil
 | 
							return cadvisorfs.LabelDockerImages, nil
 | 
				
			||||||
	case types.RktContainerRuntime:
 | 
					 | 
				
			||||||
		return cadvisorfs.LabelRktImages, nil
 | 
					 | 
				
			||||||
	case types.RemoteContainerRuntime:
 | 
						case types.RemoteContainerRuntime:
 | 
				
			||||||
		// This is a temporary workaround to get stats for cri-o from cadvisor
 | 
							// This is a temporary workaround to get stats for cri-o from cadvisor
 | 
				
			||||||
		// and should be removed.
 | 
							// and should be removed.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,7 +75,6 @@ func EphemeralStorageCapacityFromFsInfo(info cadvisorapi2.FsInfo) v1.ResourceLis
 | 
				
			|||||||
// https://github.com/kubernetes/kubernetes/issues/51798
 | 
					// https://github.com/kubernetes/kubernetes/issues/51798
 | 
				
			||||||
// UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI
 | 
					// UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI
 | 
				
			||||||
func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool {
 | 
					func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool {
 | 
				
			||||||
	return runtime == kubetypes.RktContainerRuntime ||
 | 
						return (runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
 | 
				
			||||||
		(runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
 | 
					 | 
				
			||||||
		runtimeEndpoint == CrioSocket
 | 
							runtimeEndpoint == CrioSocket
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,16 +67,6 @@ type ContainerRuntimeOptions struct {
 | 
				
			|||||||
	// CNIBinDir is the full path of the directory in which to search for
 | 
						// CNIBinDir is the full path of the directory in which to search for
 | 
				
			||||||
	// CNI plugin binaries
 | 
						// CNI plugin binaries
 | 
				
			||||||
	CNIBinDir string
 | 
						CNIBinDir string
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// rkt-specific options.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// rktPath is the path of rkt binary. Leave empty to use the first rkt in $PATH.
 | 
					 | 
				
			||||||
	RktPath string
 | 
					 | 
				
			||||||
	// rktApiEndpoint is the endpoint of the rkt API service to communicate with.
 | 
					 | 
				
			||||||
	RktAPIEndpoint string
 | 
					 | 
				
			||||||
	// rktStage1Image is the image to use as stage1. Local paths and
 | 
					 | 
				
			||||||
	// http/https URLs are supported.
 | 
					 | 
				
			||||||
	RktStage1Image string
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
 | 
					func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
 | 
				
			||||||
@@ -95,17 +85,9 @@ func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
 | 
				
			|||||||
	fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "Use this for the docker endpoint to communicate with")
 | 
						fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "Use this for the docker endpoint to communicate with")
 | 
				
			||||||
	fs.DurationVar(&s.ImagePullProgressDeadline.Duration, "image-pull-progress-deadline", s.ImagePullProgressDeadline.Duration, "If no pulling progress is made before this deadline, the image pulling will be cancelled.")
 | 
						fs.DurationVar(&s.ImagePullProgressDeadline.Duration, "image-pull-progress-deadline", s.ImagePullProgressDeadline.Duration, "If no pulling progress is made before this deadline, the image pulling will be cancelled.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Network plugin settings. Shared by both docker and rkt.
 | 
						// Network plugin settings for Docker.
 | 
				
			||||||
	fs.StringVar(&s.NetworkPluginName, "network-plugin", s.NetworkPluginName, "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle")
 | 
						fs.StringVar(&s.NetworkPluginName, "network-plugin", s.NetworkPluginName, "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle")
 | 
				
			||||||
	fs.StringVar(&s.CNIConfDir, "cni-conf-dir", s.CNIConfDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d")
 | 
						fs.StringVar(&s.CNIConfDir, "cni-conf-dir", s.CNIConfDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d")
 | 
				
			||||||
	fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> A comma-separated list of full paths of directories in which to search for CNI plugin binaries. Default: /opt/cni/bin")
 | 
						fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> A comma-separated list of full paths of directories in which to search for CNI plugin binaries. Default: /opt/cni/bin")
 | 
				
			||||||
	fs.Int32Var(&s.NetworkPluginMTU, "network-plugin-mtu", s.NetworkPluginMTU, "<Warning: Alpha feature> The MTU to be passed to the network plugin, to override the default. Set to 0 to use the default 1460 MTU.")
 | 
						fs.Int32Var(&s.NetworkPluginMTU, "network-plugin-mtu", s.NetworkPluginMTU, "<Warning: Alpha feature> The MTU to be passed to the network plugin, to override the default. Set to 0 to use the default 1460 MTU.")
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Rkt-specific settings.
 | 
					 | 
				
			||||||
	fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH.  Only used if --container-runtime='rkt'.")
 | 
					 | 
				
			||||||
	fs.MarkDeprecated("rkt-path", "will be removed in a future version. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
 | 
					 | 
				
			||||||
	fs.StringVar(&s.RktAPIEndpoint, "rkt-api-endpoint", s.RktAPIEndpoint, "The endpoint of the rkt API service to communicate with. Only used if --container-runtime='rkt'.")
 | 
					 | 
				
			||||||
	fs.MarkDeprecated("rkt-api-endpoint", "will be removed in a future version. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
 | 
					 | 
				
			||||||
	fs.StringVar(&s.RktStage1Image, "rkt-stage1-image", s.RktStage1Image, "image to use as stage1. Local paths and http/https URLs are supported. If empty, the 'stage1.aci' in the same directory as '--rkt-path' will be used.")
 | 
					 | 
				
			||||||
	fs.MarkDeprecated("rkt-stage1-image", "will be removed in a future version. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,7 +87,6 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/kubelet/prober"
 | 
						"k8s.io/kubernetes/pkg/kubelet/prober"
 | 
				
			||||||
	proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
 | 
						proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/remote"
 | 
						"k8s.io/kubernetes/pkg/kubelet/remote"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/rkt"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/secret"
 | 
						"k8s.io/kubernetes/pkg/kubelet/secret"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/server"
 | 
						"k8s.io/kubernetes/pkg/kubelet/server"
 | 
				
			||||||
	serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats"
 | 
						serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats"
 | 
				
			||||||
@@ -600,12 +599,10 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
 | 
				
			|||||||
	var nl *NoOpLegacyHost
 | 
						var nl *NoOpLegacyHost
 | 
				
			||||||
	pluginSettings.LegacyRuntimeHost = nl
 | 
						pluginSettings.LegacyRuntimeHost = nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if containerRuntime == kubetypes.RktContainerRuntime {
 | 
						if containerRuntime == "rkt" {
 | 
				
			||||||
		glog.Warningln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
 | 
							glog.Fatalln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// rktnetes cannot be run with CRI.
 | 
					 | 
				
			||||||
	if containerRuntime != kubetypes.RktContainerRuntime {
 | 
					 | 
				
			||||||
	// kubelet defers to the runtime shim to setup networking. Setting
 | 
						// kubelet defers to the runtime shim to setup networking. Setting
 | 
				
			||||||
	// this to nil will prevent it from trying to invoke the plugin.
 | 
						// this to nil will prevent it from trying to invoke the plugin.
 | 
				
			||||||
	// It's easier to always probe and initialize plugins till cri
 | 
						// It's easier to always probe and initialize plugins till cri
 | 
				
			||||||
@@ -701,45 +698,6 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
 | 
				
			|||||||
			imageService,
 | 
								imageService,
 | 
				
			||||||
			stats.NewLogMetricsService())
 | 
								stats.NewLogMetricsService())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		// rkt uses the legacy, non-CRI, integration. Configure it the old way.
 | 
					 | 
				
			||||||
		// TODO: Include hairpin mode settings in rkt?
 | 
					 | 
				
			||||||
		conf := &rkt.Config{
 | 
					 | 
				
			||||||
			Path:            crOptions.RktPath,
 | 
					 | 
				
			||||||
			Stage1Image:     crOptions.RktStage1Image,
 | 
					 | 
				
			||||||
			InsecureOptions: "image,ondisk",
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		runtime, err := rkt.New(
 | 
					 | 
				
			||||||
			crOptions.RktAPIEndpoint,
 | 
					 | 
				
			||||||
			conf,
 | 
					 | 
				
			||||||
			klet,
 | 
					 | 
				
			||||||
			kubeDeps.Recorder,
 | 
					 | 
				
			||||||
			containerRefManager,
 | 
					 | 
				
			||||||
			klet,
 | 
					 | 
				
			||||||
			klet.livenessManager,
 | 
					 | 
				
			||||||
			httpClient,
 | 
					 | 
				
			||||||
			klet.networkPlugin,
 | 
					 | 
				
			||||||
			hairpinMode == kubeletconfiginternal.HairpinVeth,
 | 
					 | 
				
			||||||
			utilexec.New(),
 | 
					 | 
				
			||||||
			kubecontainer.RealOS{},
 | 
					 | 
				
			||||||
			imageBackOff,
 | 
					 | 
				
			||||||
			kubeCfg.SerializeImagePulls,
 | 
					 | 
				
			||||||
			float32(kubeCfg.RegistryPullQPS),
 | 
					 | 
				
			||||||
			int(kubeCfg.RegistryBurst),
 | 
					 | 
				
			||||||
			kubeCfg.RuntimeRequestTimeout.Duration,
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		klet.containerRuntime = runtime
 | 
					 | 
				
			||||||
		klet.runner = kubecontainer.DirectStreamingRunner(runtime)
 | 
					 | 
				
			||||||
		klet.StatsProvider = stats.NewCadvisorStatsProvider(
 | 
					 | 
				
			||||||
			klet.cadvisor,
 | 
					 | 
				
			||||||
			klet.resourceAnalyzer,
 | 
					 | 
				
			||||||
			klet.podManager,
 | 
					 | 
				
			||||||
			klet.runtimeCache,
 | 
					 | 
				
			||||||
			klet.containerRuntime)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})
 | 
						klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})
 | 
				
			||||||
	klet.runtimeState = newRuntimeState(maxWaitForContainerRuntime)
 | 
						klet.runtimeState = newRuntimeState(maxWaitForContainerRuntime)
 | 
				
			||||||
@@ -2108,9 +2066,6 @@ func (kl *Kubelet) updateRuntimeUp() {
 | 
				
			|||||||
		glog.Errorf("Container runtime sanity check failed: %v", err)
 | 
							glog.Errorf("Container runtime sanity check failed: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// rkt uses the legacy, non-CRI integration. Don't check the runtime
 | 
					 | 
				
			||||||
	// conditions for it.
 | 
					 | 
				
			||||||
	if kl.containerRuntimeName != kubetypes.RktContainerRuntime {
 | 
					 | 
				
			||||||
	if s == nil {
 | 
						if s == nil {
 | 
				
			||||||
		glog.Errorf("Container runtime status is nil")
 | 
							glog.Errorf("Container runtime status is nil")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -2136,7 +2091,6 @@ func (kl *Kubelet) updateRuntimeUp() {
 | 
				
			|||||||
		glog.Errorf("Container runtime not ready: %v", runtimeReady)
 | 
							glog.Errorf("Container runtime not ready: %v", runtimeReady)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules)
 | 
						kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules)
 | 
				
			||||||
	kl.runtimeState.setRuntimeSync(kl.clock.Now())
 | 
						kl.runtimeState.setRuntimeSync(kl.clock.Now())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,108 +0,0 @@
 | 
				
			|||||||
package(default_visibility = ["//visibility:public"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load(
 | 
					 | 
				
			||||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
					 | 
				
			||||||
    "go_library",
 | 
					 | 
				
			||||||
    "go_test",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "cap.go",
 | 
					 | 
				
			||||||
        "config.go",
 | 
					 | 
				
			||||||
        "container_id.go",
 | 
					 | 
				
			||||||
        "doc.go",
 | 
					 | 
				
			||||||
        "image.go",
 | 
					 | 
				
			||||||
        "log.go",
 | 
					 | 
				
			||||||
        "rkt.go",
 | 
					 | 
				
			||||||
        "systemd.go",
 | 
					 | 
				
			||||||
        "version.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    importpath = "k8s.io/kubernetes/pkg/kubelet/rkt",
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//pkg/credentialprovider:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/credentialprovider/secrets:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/container:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/events:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/images:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/leaky:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/lifecycle:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/network:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/network/hairpin:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/prober/results:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/types:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/util/format:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/securitycontext:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/util/parsers:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/util/selinux:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/util/strings:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/util/term:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/util/version:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/dbus:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/unit:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/docker/docker/api/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/golang/glog:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/google.golang.org/grpc:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/api/core/v1:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/client-go/tools/record:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/utils/exec:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_test(
 | 
					 | 
				
			||||||
    name = "go_default_test",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "fake_rkt_interface_test.go",
 | 
					 | 
				
			||||||
        "rkt_test.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    embed = [":go_default_library"],
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//pkg/kubelet/container:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/container/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/lifecycle:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/network:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/network/kubenet:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/network/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//pkg/kubelet/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/dbus:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/unit:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/golang/mock/gomock:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/stretchr/testify/assert:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/google.golang.org/grpc:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/api/core/v1:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/client-go/util/testing:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/utils/exec:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/k8s.io/utils/exec/testing:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
approvers:
 | 
					 | 
				
			||||||
- euank
 | 
					 | 
				
			||||||
- yifan-gu
 | 
					 | 
				
			||||||
@@ -1,110 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(yifan): Export this to higher level package.
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	CAP_CHOWN = iota
 | 
					 | 
				
			||||||
	CAP_DAC_OVERRIDE
 | 
					 | 
				
			||||||
	CAP_DAC_READ_SEARCH
 | 
					 | 
				
			||||||
	CAP_FOWNER
 | 
					 | 
				
			||||||
	CAP_FSETID
 | 
					 | 
				
			||||||
	CAP_KILL
 | 
					 | 
				
			||||||
	CAP_SETGID
 | 
					 | 
				
			||||||
	CAP_SETUID
 | 
					 | 
				
			||||||
	CAP_SETPCAP
 | 
					 | 
				
			||||||
	CAP_LINUX_IMMUTABLE
 | 
					 | 
				
			||||||
	CAP_NET_BIND_SERVICE
 | 
					 | 
				
			||||||
	CAP_NET_BROADCAST
 | 
					 | 
				
			||||||
	CAP_NET_ADMIN
 | 
					 | 
				
			||||||
	CAP_NET_RAW
 | 
					 | 
				
			||||||
	CAP_IPC_LOCK
 | 
					 | 
				
			||||||
	CAP_IPC_OWNER
 | 
					 | 
				
			||||||
	CAP_SYS_MODULE
 | 
					 | 
				
			||||||
	CAP_SYS_RAWIO
 | 
					 | 
				
			||||||
	CAP_SYS_CHROOT
 | 
					 | 
				
			||||||
	CAP_SYS_PTRACE
 | 
					 | 
				
			||||||
	CAP_SYS_PACCT
 | 
					 | 
				
			||||||
	CAP_SYS_ADMIN
 | 
					 | 
				
			||||||
	CAP_SYS_BOOT
 | 
					 | 
				
			||||||
	CAP_SYS_NICE
 | 
					 | 
				
			||||||
	CAP_SYS_RESOURCE
 | 
					 | 
				
			||||||
	CAP_SYS_TIME
 | 
					 | 
				
			||||||
	CAP_SYS_TTY_CONFIG
 | 
					 | 
				
			||||||
	CAP_MKNOD
 | 
					 | 
				
			||||||
	CAP_LEASE
 | 
					 | 
				
			||||||
	CAP_AUDIT_WRITE
 | 
					 | 
				
			||||||
	CAP_AUDIT_CONTROL
 | 
					 | 
				
			||||||
	CAP_SETFCAP
 | 
					 | 
				
			||||||
	CAP_MAC_OVERRIDE
 | 
					 | 
				
			||||||
	CAP_MAC_ADMIN
 | 
					 | 
				
			||||||
	CAP_SYSLOG
 | 
					 | 
				
			||||||
	CAP_WAKE_ALARM
 | 
					 | 
				
			||||||
	CAP_BLOCK_SUSPEND
 | 
					 | 
				
			||||||
	CAP_AUDIT_READ
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(yifan): Export this to higher level package.
 | 
					 | 
				
			||||||
var capabilityList = map[int]string{
 | 
					 | 
				
			||||||
	CAP_CHOWN:            "CAP_CHOWN",
 | 
					 | 
				
			||||||
	CAP_DAC_OVERRIDE:     "CAP_DAC_OVERRIDE",
 | 
					 | 
				
			||||||
	CAP_DAC_READ_SEARCH:  "CAP_DAC_READ_SEARCH",
 | 
					 | 
				
			||||||
	CAP_FOWNER:           "CAP_FOWNER",
 | 
					 | 
				
			||||||
	CAP_FSETID:           "CAP_FSETID",
 | 
					 | 
				
			||||||
	CAP_KILL:             "CAP_KILL",
 | 
					 | 
				
			||||||
	CAP_SETGID:           "CAP_SETGID",
 | 
					 | 
				
			||||||
	CAP_SETUID:           "CAP_SETUID",
 | 
					 | 
				
			||||||
	CAP_SETPCAP:          "CAP_SETPCAP",
 | 
					 | 
				
			||||||
	CAP_LINUX_IMMUTABLE:  "CAP_LINUX_IMMUTABLE",
 | 
					 | 
				
			||||||
	CAP_NET_BIND_SERVICE: "CAP_NET_BIND_SERVICE",
 | 
					 | 
				
			||||||
	CAP_NET_BROADCAST:    "CAP_NET_BROADCAST",
 | 
					 | 
				
			||||||
	CAP_NET_ADMIN:        "CAP_NET_ADMIN",
 | 
					 | 
				
			||||||
	CAP_NET_RAW:          "CAP_NET_RAW",
 | 
					 | 
				
			||||||
	CAP_IPC_LOCK:         "CAP_IPC_LOCK",
 | 
					 | 
				
			||||||
	CAP_IPC_OWNER:        "CAP_IPC_OWNER",
 | 
					 | 
				
			||||||
	CAP_SYS_MODULE:       "CAP_SYS_MODULE",
 | 
					 | 
				
			||||||
	CAP_SYS_RAWIO:        "CAP_SYS_RAWIO",
 | 
					 | 
				
			||||||
	CAP_SYS_CHROOT:       "CAP_SYS_CHROOT",
 | 
					 | 
				
			||||||
	CAP_SYS_PTRACE:       "CAP_SYS_PTRACE",
 | 
					 | 
				
			||||||
	CAP_SYS_PACCT:        "CAP_SYS_PACCT",
 | 
					 | 
				
			||||||
	CAP_SYS_ADMIN:        "CAP_SYS_ADMIN",
 | 
					 | 
				
			||||||
	CAP_SYS_BOOT:         "CAP_SYS_BOOT",
 | 
					 | 
				
			||||||
	CAP_SYS_NICE:         "CAP_SYS_NICE",
 | 
					 | 
				
			||||||
	CAP_SYS_RESOURCE:     "CAP_SYS_RESOURCE",
 | 
					 | 
				
			||||||
	CAP_SYS_TIME:         "CAP_SYS_TIME",
 | 
					 | 
				
			||||||
	CAP_SYS_TTY_CONFIG:   "CAP_SYS_TTY_CONFIG",
 | 
					 | 
				
			||||||
	CAP_MKNOD:            "CAP_MKNOD",
 | 
					 | 
				
			||||||
	CAP_LEASE:            "CAP_LEASE",
 | 
					 | 
				
			||||||
	CAP_AUDIT_WRITE:      "CAP_AUDIT_WRITE",
 | 
					 | 
				
			||||||
	CAP_AUDIT_CONTROL:    "CAP_AUDIT_CONTROL",
 | 
					 | 
				
			||||||
	CAP_SETFCAP:          "CAP_SETFCAP",
 | 
					 | 
				
			||||||
	CAP_MAC_OVERRIDE:     "CAP_MAC_OVERRIDE",
 | 
					 | 
				
			||||||
	CAP_MAC_ADMIN:        "CAP_MAC_ADMIN",
 | 
					 | 
				
			||||||
	CAP_SYSLOG:           "CAP_SYSLOG",
 | 
					 | 
				
			||||||
	CAP_WAKE_ALARM:       "CAP_WAKE_ALARM",
 | 
					 | 
				
			||||||
	CAP_BLOCK_SUSPEND:    "CAP_BLOCK_SUSPEND",
 | 
					 | 
				
			||||||
	CAP_AUDIT_READ:       "CAP_AUDIT_READ",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// allCapabilities returns the capability list with all capabilities.
 | 
					 | 
				
			||||||
func allCapabilities() []string {
 | 
					 | 
				
			||||||
	var capabilities []string
 | 
					 | 
				
			||||||
	for _, cap := range capabilityList {
 | 
					 | 
				
			||||||
		capabilities = append(capabilities, cap)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return capabilities
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,108 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Config stores the global configuration for the rkt runtime.
 | 
					 | 
				
			||||||
// Detailed documents can be found at:
 | 
					 | 
				
			||||||
// https://github.com/coreos/rkt/blob/master/Documentation/commands.md#global-options
 | 
					 | 
				
			||||||
type Config struct {
 | 
					 | 
				
			||||||
	// The absolute path to the binary, or leave empty to find it in $PATH.
 | 
					 | 
				
			||||||
	Path string
 | 
					 | 
				
			||||||
	// The rkt data directory.
 | 
					 | 
				
			||||||
	Dir string
 | 
					 | 
				
			||||||
	// The image to use as stage1.
 | 
					 | 
				
			||||||
	Stage1Image string
 | 
					 | 
				
			||||||
	// The debug flag for rkt.
 | 
					 | 
				
			||||||
	Debug bool
 | 
					 | 
				
			||||||
	// Comma-separated list of security features to disable.
 | 
					 | 
				
			||||||
	// Allowed values: "none", "image", "tls", "ondisk", "http", "all".
 | 
					 | 
				
			||||||
	InsecureOptions string
 | 
					 | 
				
			||||||
	// The local config directory.
 | 
					 | 
				
			||||||
	LocalConfigDir string
 | 
					 | 
				
			||||||
	// The user config directory.
 | 
					 | 
				
			||||||
	UserConfigDir string
 | 
					 | 
				
			||||||
	// The system config directory.
 | 
					 | 
				
			||||||
	SystemConfigDir string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// buildGlobalOptions returns an array of global command line options.
 | 
					 | 
				
			||||||
func (c *Config) buildGlobalOptions() []string {
 | 
					 | 
				
			||||||
	var result []string
 | 
					 | 
				
			||||||
	if c == nil {
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if c.Debug {
 | 
					 | 
				
			||||||
		result = append(result, "--debug=true")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.InsecureOptions != "" {
 | 
					 | 
				
			||||||
		result = append(result, fmt.Sprintf("--insecure-options=%s", c.InsecureOptions))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.LocalConfigDir != "" {
 | 
					 | 
				
			||||||
		result = append(result, fmt.Sprintf("--local-config=%s", c.LocalConfigDir))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.UserConfigDir != "" {
 | 
					 | 
				
			||||||
		result = append(result, fmt.Sprintf("--user-config=%s", c.UserConfigDir))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.SystemConfigDir != "" {
 | 
					 | 
				
			||||||
		result = append(result, fmt.Sprintf("--system-config=%s", c.SystemConfigDir))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c.Dir != "" {
 | 
					 | 
				
			||||||
		result = append(result, fmt.Sprintf("--dir=%s", c.Dir))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getConfig gets configurations from the rkt API service
 | 
					 | 
				
			||||||
// and merge it with the existing config. The merge rule is
 | 
					 | 
				
			||||||
// that the fields in the provided config will override the
 | 
					 | 
				
			||||||
// result that get from the rkt api service.
 | 
					 | 
				
			||||||
func (r *Runtime) getConfig(cfg *Config) (*Config, error) {
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
	resp, err := r.apisvc.GetInfo(ctx, &rktapi.GetInfoRequest{})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	flags := resp.Info.GlobalFlags
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if flags.Dir != "" {
 | 
					 | 
				
			||||||
		cfg.Dir = flags.Dir
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if flags.LocalConfigDir != "" {
 | 
					 | 
				
			||||||
		cfg.LocalConfigDir = flags.LocalConfigDir
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if flags.UserConfigDir != "" {
 | 
					 | 
				
			||||||
		cfg.UserConfigDir = flags.UserConfigDir
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if flags.SystemConfigDir != "" {
 | 
					 | 
				
			||||||
		cfg.SystemConfigDir = flags.SystemConfigDir
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if flags.InsecureFlags != "" {
 | 
					 | 
				
			||||||
		cfg.InsecureOptions = fmt.Sprintf("%s,%s", cfg.InsecureOptions, flags.InsecureFlags)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return cfg, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,55 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// containerID defines the ID of rkt containers, it will
 | 
					 | 
				
			||||||
// be returned to kubelet, and kubelet will use this for
 | 
					 | 
				
			||||||
// container level operations.
 | 
					 | 
				
			||||||
type containerID struct {
 | 
					 | 
				
			||||||
	uuid    string // rkt uuid of the pod.
 | 
					 | 
				
			||||||
	appName string // Name of the app in that pod.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// buildContainerID constructs the containers's ID using containerID,
 | 
					 | 
				
			||||||
// which consists of the pod uuid and the container name.
 | 
					 | 
				
			||||||
// The result can be used to uniquely identify a container.
 | 
					 | 
				
			||||||
func buildContainerID(c *containerID) kubecontainer.ContainerID {
 | 
					 | 
				
			||||||
	return kubecontainer.ContainerID{
 | 
					 | 
				
			||||||
		Type: RktType,
 | 
					 | 
				
			||||||
		ID:   fmt.Sprintf("%s:%s", c.uuid, c.appName),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// parseContainerID parses the containerID into pod uuid and the container name. The
 | 
					 | 
				
			||||||
// results can be used to get more information of the container.
 | 
					 | 
				
			||||||
func parseContainerID(id kubecontainer.ContainerID) (*containerID, error) {
 | 
					 | 
				
			||||||
	tuples := strings.Split(id.ID, ":")
 | 
					 | 
				
			||||||
	if len(tuples) != 2 {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("rkt: cannot parse container ID for: %q, required format is [UUID:APPNAME]", id)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &containerID{
 | 
					 | 
				
			||||||
		uuid:    tuples[0],
 | 
					 | 
				
			||||||
		appName: tuples[1],
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt contains the Containerruntime interface implementation for rkt.
 | 
					 | 
				
			||||||
package rkt // import "k8s.io/kubernetes/pkg/kubelet/rkt"
 | 
					 | 
				
			||||||
@@ -1,218 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/coreos/go-systemd/dbus"
 | 
					 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/types"
 | 
					 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// fakeRktInterface mocks the rktapi.PublicAPIClient interface for testing purpose.
 | 
					 | 
				
			||||||
type fakeRktInterface struct {
 | 
					 | 
				
			||||||
	sync.Mutex
 | 
					 | 
				
			||||||
	info       rktapi.Info
 | 
					 | 
				
			||||||
	images     []*rktapi.Image
 | 
					 | 
				
			||||||
	podFilters []*rktapi.PodFilter
 | 
					 | 
				
			||||||
	pods       []*rktapi.Pod
 | 
					 | 
				
			||||||
	called     []string
 | 
					 | 
				
			||||||
	err        error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newFakeRktInterface() *fakeRktInterface {
 | 
					 | 
				
			||||||
	return &fakeRktInterface{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) CleanCalls() {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
	f.called = nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) GetInfo(ctx context.Context, in *rktapi.GetInfoRequest, opts ...grpc.CallOption) (*rktapi.GetInfoResponse, error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f.called = append(f.called, "GetInfo")
 | 
					 | 
				
			||||||
	return &rktapi.GetInfoResponse{Info: &f.info}, f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) ListPods(ctx context.Context, in *rktapi.ListPodsRequest, opts ...grpc.CallOption) (*rktapi.ListPodsResponse, error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f.called = append(f.called, "ListPods")
 | 
					 | 
				
			||||||
	f.podFilters = in.Filters
 | 
					 | 
				
			||||||
	return &rktapi.ListPodsResponse{Pods: f.pods}, f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) InspectPod(ctx context.Context, in *rktapi.InspectPodRequest, opts ...grpc.CallOption) (*rktapi.InspectPodResponse, error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f.called = append(f.called, "InspectPod")
 | 
					 | 
				
			||||||
	for _, pod := range f.pods {
 | 
					 | 
				
			||||||
		if pod.Id == in.Id {
 | 
					 | 
				
			||||||
			return &rktapi.InspectPodResponse{Pod: pod}, f.err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &rktapi.InspectPodResponse{}, fmt.Errorf("pod %q not found", in.Id)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) ListImages(ctx context.Context, in *rktapi.ListImagesRequest, opts ...grpc.CallOption) (*rktapi.ListImagesResponse, error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f.called = append(f.called, "ListImages")
 | 
					 | 
				
			||||||
	return &rktapi.ListImagesResponse{Images: f.images}, f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) InspectImage(ctx context.Context, in *rktapi.InspectImageRequest, opts ...grpc.CallOption) (*rktapi.InspectImageResponse, error) {
 | 
					 | 
				
			||||||
	return nil, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) ListenEvents(ctx context.Context, in *rktapi.ListenEventsRequest, opts ...grpc.CallOption) (rktapi.PublicAPI_ListenEventsClient, error) {
 | 
					 | 
				
			||||||
	return nil, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktInterface) GetLogs(ctx context.Context, in *rktapi.GetLogsRequest, opts ...grpc.CallOption) (rktapi.PublicAPI_GetLogsClient, error) {
 | 
					 | 
				
			||||||
	return nil, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// fakeSystemd mocks the systemdInterface for testing purpose.
 | 
					 | 
				
			||||||
// TODO(yifan): Remove this once we have a package for launching rkt pods.
 | 
					 | 
				
			||||||
// See https://github.com/coreos/rkt/issues/1769.
 | 
					 | 
				
			||||||
type fakeSystemd struct {
 | 
					 | 
				
			||||||
	sync.Mutex
 | 
					 | 
				
			||||||
	called           []string
 | 
					 | 
				
			||||||
	resetFailedUnits []string
 | 
					 | 
				
			||||||
	version          string
 | 
					 | 
				
			||||||
	err              error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newFakeSystemd() *fakeSystemd {
 | 
					 | 
				
			||||||
	return &fakeSystemd{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) CleanCalls() {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
	f.called = nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) Version() (systemdVersion, error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f.called = append(f.called, "Version")
 | 
					 | 
				
			||||||
	v, _ := strconv.Atoi(f.version)
 | 
					 | 
				
			||||||
	return systemdVersion(v), f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) ListUnits() ([]dbus.UnitStatus, error) {
 | 
					 | 
				
			||||||
	return nil, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) StopUnit(name string, mode string, ch chan<- string) (int, error) {
 | 
					 | 
				
			||||||
	return 0, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) RestartUnit(name string, mode string, ch chan<- string) (int, error) {
 | 
					 | 
				
			||||||
	return 0, fmt.Errorf("Not implemented")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeSystemd) ResetFailedUnit(name string) error {
 | 
					 | 
				
			||||||
	f.called = append(f.called, "ResetFailedUnit")
 | 
					 | 
				
			||||||
	f.resetFailedUnits = append(f.resetFailedUnits, name)
 | 
					 | 
				
			||||||
	return f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type fakeRktCli struct {
 | 
					 | 
				
			||||||
	sync.Mutex
 | 
					 | 
				
			||||||
	cmds   []string
 | 
					 | 
				
			||||||
	result []string
 | 
					 | 
				
			||||||
	err    error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newFakeRktCli() *fakeRktCli {
 | 
					 | 
				
			||||||
	return &fakeRktCli{
 | 
					 | 
				
			||||||
		cmds:   []string{},
 | 
					 | 
				
			||||||
		result: []string{},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktCli) RunCommand(config *Config, args ...string) (result []string, err error) {
 | 
					 | 
				
			||||||
	f.Lock()
 | 
					 | 
				
			||||||
	defer f.Unlock()
 | 
					 | 
				
			||||||
	cmd := append([]string{"rkt"}, args...)
 | 
					 | 
				
			||||||
	f.cmds = append(f.cmds, strings.Join(cmd, " "))
 | 
					 | 
				
			||||||
	return f.result, f.err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeRktCli) Reset() {
 | 
					 | 
				
			||||||
	f.cmds = []string{}
 | 
					 | 
				
			||||||
	f.result = []string{}
 | 
					 | 
				
			||||||
	f.err = nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type fakePodDeletionProvider struct {
 | 
					 | 
				
			||||||
	pods map[types.UID]struct{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newFakePodDeletionProvider() *fakePodDeletionProvider {
 | 
					 | 
				
			||||||
	return &fakePodDeletionProvider{
 | 
					 | 
				
			||||||
		pods: make(map[types.UID]struct{}),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakePodDeletionProvider) IsPodDeleted(uid types.UID) bool {
 | 
					 | 
				
			||||||
	_, found := f.pods[uid]
 | 
					 | 
				
			||||||
	return !found
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type fakeUnitGetter struct {
 | 
					 | 
				
			||||||
	networkNamespace kubecontainer.ContainerID
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newfakeUnitGetter() *fakeUnitGetter {
 | 
					 | 
				
			||||||
	return &fakeUnitGetter{
 | 
					 | 
				
			||||||
		networkNamespace: kubecontainer.ContainerID{},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeUnitGetter) getNetworkNamespace(uid types.UID, latestPod *rktapi.Pod) (kubecontainer.ContainerID, error) {
 | 
					 | 
				
			||||||
	return kubecontainer.ContainerID{ID: "42"}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *fakeUnitGetter) getKubernetesDirective(serviceFilePath string) (podServiceDirective, error) {
 | 
					 | 
				
			||||||
	podService := podServiceDirective{
 | 
					 | 
				
			||||||
		id:               "fake",
 | 
					 | 
				
			||||||
		name:             "fake",
 | 
					 | 
				
			||||||
		namespace:        "fake",
 | 
					 | 
				
			||||||
		hostNetwork:      true,
 | 
					 | 
				
			||||||
		networkNamespace: kubecontainer.ContainerID{ID: "42"},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return podService, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,294 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 file contains all image related functions for rkt runtime.
 | 
					 | 
				
			||||||
package rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"path"
 | 
					 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	appcschema "github.com/appc/spec/schema"
 | 
					 | 
				
			||||||
	appctypes "github.com/appc/spec/schema/types"
 | 
					 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
					 | 
				
			||||||
	dockertypes "github.com/docker/docker/api/types"
 | 
					 | 
				
			||||||
	"github.com/golang/glog"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/credentialprovider"
 | 
					 | 
				
			||||||
	credentialprovidersecrets "k8s.io/kubernetes/pkg/credentialprovider/secrets"
 | 
					 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/parsers"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PullImage invokes 'rkt fetch' to download an aci.
 | 
					 | 
				
			||||||
// TODO(yifan): Now we only support docker images, this should be changed
 | 
					 | 
				
			||||||
// once the format of image is landed, see:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// http://issue.k8s.io/7203
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) (string, error) {
 | 
					 | 
				
			||||||
	img := image.Image
 | 
					 | 
				
			||||||
	// TODO(yifan): The credential operation is a copy from dockertools package,
 | 
					 | 
				
			||||||
	// Need to resolve the code duplication.
 | 
					 | 
				
			||||||
	repoToPull, _, _, err := parsers.ParseImageName(img)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	keyring, err := credentialprovidersecrets.MakeDockerKeyring(pullSecrets, r.dockerKeyring)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	creds, ok := keyring.Lookup(repoToPull)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		glog.V(1).Infof("Pulling image %s without credentials", img)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	userConfigDir, err := ioutil.TempDir("", "rktnetes-user-config-dir-")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer os.RemoveAll(userConfigDir)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	config := *r.config
 | 
					 | 
				
			||||||
	config.UserConfigDir = userConfigDir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := r.writeDockerAuthConfig(img, creds, userConfigDir); err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Today, `--no-store` will fetch the remote image regardless of whether the content of the image
 | 
					 | 
				
			||||||
	// has changed or not. This causes performance downgrades when the image tag is ':latest' and
 | 
					 | 
				
			||||||
	// the image pull policy is 'always'. The issue is tracked in https://github.com/coreos/rkt/issues/2937.
 | 
					 | 
				
			||||||
	if _, err := r.cli.RunCommand(&config, "fetch", "--no-store", dockerPrefix+img); err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to fetch: %v", err)
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return r.getImageID(img)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *Runtime) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
 | 
					 | 
				
			||||||
	images, err := r.listImages(image.Image, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(images) == 0 {
 | 
					 | 
				
			||||||
		return "", nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return images[0].Id, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListImages lists all the available appc images on the machine by invoking 'rkt image list'.
 | 
					 | 
				
			||||||
func (r *Runtime) ListImages() ([]kubecontainer.Image, error) {
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
	listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("couldn't list images: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	images := make([]kubecontainer.Image, len(listResp.Images))
 | 
					 | 
				
			||||||
	for i, image := range listResp.Images {
 | 
					 | 
				
			||||||
		images[i] = kubecontainer.Image{
 | 
					 | 
				
			||||||
			ID:       image.Id,
 | 
					 | 
				
			||||||
			RepoTags: []string{buildImageName(image)},
 | 
					 | 
				
			||||||
			Size:     image.Size,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return images, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RemoveImage removes an on-disk image using 'rkt image rm'.
 | 
					 | 
				
			||||||
func (r *Runtime) RemoveImage(image kubecontainer.ImageSpec) error {
 | 
					 | 
				
			||||||
	imageID, err := r.getImageID(image.Image)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, err := r.cli.RunCommand(nil, "image", "rm", imageID); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// buildImageName constructs the image name for kubecontainer.Image.
 | 
					 | 
				
			||||||
// If the annotations contain the docker2aci metadata for this image, those are
 | 
					 | 
				
			||||||
// used instead as they may be more accurate in some cases, namely if a
 | 
					 | 
				
			||||||
// non-appc valid character is present
 | 
					 | 
				
			||||||
func buildImageName(img *rktapi.Image) string {
 | 
					 | 
				
			||||||
	registry := ""
 | 
					 | 
				
			||||||
	repository := ""
 | 
					 | 
				
			||||||
	for _, anno := range img.Annotations {
 | 
					 | 
				
			||||||
		if anno.Key == appcDockerRegistryURL {
 | 
					 | 
				
			||||||
			registry = anno.Value
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if anno.Key == appcDockerRepository {
 | 
					 | 
				
			||||||
			repository = anno.Value
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if registry != "" && repository != "" {
 | 
					 | 
				
			||||||
		// TODO(euank): This could do the special casing for dockerhub and library images
 | 
					 | 
				
			||||||
		return fmt.Sprintf("%s/%s:%s", registry, repository, img.Version)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%s:%s", img.Name, img.Version)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getImageID tries to find the image ID for the given image name.
 | 
					 | 
				
			||||||
// imageName should be in the form of 'name[:version]', e.g., 'example.com/app:latest'.
 | 
					 | 
				
			||||||
// The name should matches the result of 'rkt image list'. If the version is empty,
 | 
					 | 
				
			||||||
// then 'latest' is assumed.
 | 
					 | 
				
			||||||
func (r *Runtime) getImageID(imageName string) (string, error) {
 | 
					 | 
				
			||||||
	images, err := r.listImages(imageName, false)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(images) == 0 {
 | 
					 | 
				
			||||||
		return "", fmt.Errorf("cannot find the image %q", imageName)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return images[0].Id, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type sortByImportTime []*rktapi.Image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s sortByImportTime) Len() int           { return len(s) }
 | 
					 | 
				
			||||||
func (s sortByImportTime) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 | 
					 | 
				
			||||||
func (s sortByImportTime) Less(i, j int) bool { return s[i].ImportTimestamp < s[j].ImportTimestamp }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// listImages lists the images that have the given name. If detail is true,
 | 
					 | 
				
			||||||
// then image manifest is also included in the result.
 | 
					 | 
				
			||||||
// Note that there could be more than one images that have the given name, we
 | 
					 | 
				
			||||||
// will return the result reversely sorted by the import time, so that the latest
 | 
					 | 
				
			||||||
// image comes first.
 | 
					 | 
				
			||||||
func (r *Runtime) listImages(image string, detail bool) ([]*rktapi.Image, error) {
 | 
					 | 
				
			||||||
	repoToPull, tag, _, err := parsers.ParseImageName(image)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	imageFilters := []*rktapi.ImageFilter{
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			// TODO(yifan): Add a field in the ImageFilter to match the whole name,
 | 
					 | 
				
			||||||
			// not just keywords.
 | 
					 | 
				
			||||||
			// https://github.com/coreos/rkt/issues/1872#issuecomment-166456938
 | 
					 | 
				
			||||||
			Keywords: []string{repoToPull},
 | 
					 | 
				
			||||||
			Labels:   []*rktapi.KeyValue{{Key: "version", Value: tag}},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// If the repo name is not a valid ACIdentifier (namely if it has a port),
 | 
					 | 
				
			||||||
	// then it will have a different name in the store. Search for both the
 | 
					 | 
				
			||||||
	// original name and this modified name in case we choose to also change the
 | 
					 | 
				
			||||||
	// api-service to do this un-conversion on its end.
 | 
					 | 
				
			||||||
	if appcRepoToPull, err := appctypes.SanitizeACIdentifier(repoToPull); err != nil {
 | 
					 | 
				
			||||||
		glog.Warningf("could not convert %v to an aci identifier: %v", err)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		imageFilters = append(imageFilters, &rktapi.ImageFilter{
 | 
					 | 
				
			||||||
			Keywords: []string{appcRepoToPull},
 | 
					 | 
				
			||||||
			Labels:   []*rktapi.KeyValue{{Key: "version", Value: tag}},
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
	listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{
 | 
					 | 
				
			||||||
		Detail:  detail,
 | 
					 | 
				
			||||||
		Filters: imageFilters,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("couldn't list images: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO(yifan): Let the API service to sort the result:
 | 
					 | 
				
			||||||
	// See https://github.com/coreos/rkt/issues/1911.
 | 
					 | 
				
			||||||
	sort.Sort(sort.Reverse(sortByImportTime(listResp.Images)))
 | 
					 | 
				
			||||||
	return listResp.Images, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getImageManifest retrieves the image manifest for the given image.
 | 
					 | 
				
			||||||
func (r *Runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) {
 | 
					 | 
				
			||||||
	var manifest appcschema.ImageManifest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	images, err := r.listImages(image, true)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(images) == 0 {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("cannot find the image %q", image)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &manifest, json.Unmarshal(images[0].Manifest, &manifest)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(yifan): This is very racy, inefficient, and unsafe, we need to provide
 | 
					 | 
				
			||||||
// different namespaces. See: https://github.com/coreos/rkt/issues/836.
 | 
					 | 
				
			||||||
func (r *Runtime) writeDockerAuthConfig(image string, credsSlice []credentialprovider.LazyAuthConfiguration, userConfigDir string) error {
 | 
					 | 
				
			||||||
	if len(credsSlice) == 0 {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	creds := dockertypes.AuthConfig{}
 | 
					 | 
				
			||||||
	// TODO handle multiple creds
 | 
					 | 
				
			||||||
	if len(credsSlice) >= 1 {
 | 
					 | 
				
			||||||
		creds = credentialprovider.LazyProvide(credsSlice[0])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	registry := "index.docker.io"
 | 
					 | 
				
			||||||
	// Image spec: [<registry>/]<repository>/<image>[:<version]
 | 
					 | 
				
			||||||
	explicitRegistry := (strings.Count(image, "/") == 2)
 | 
					 | 
				
			||||||
	if explicitRegistry {
 | 
					 | 
				
			||||||
		registry = strings.Split(image, "/")[0]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	authDir := filepath.Join(userConfigDir, "auth.d")
 | 
					 | 
				
			||||||
	if _, err := os.Stat(authDir); os.IsNotExist(err) {
 | 
					 | 
				
			||||||
		if err := os.MkdirAll(authDir, 0600); err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("rkt: Cannot create auth dir: %v", err)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	config := fmt.Sprintf(dockerAuthTemplate, registry, creds.Username, creds.Password)
 | 
					 | 
				
			||||||
	if err := ioutil.WriteFile(path.Join(authDir, registry+".json"), []byte(config), 0600); err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("rkt: Cannot write docker auth config file: %v", err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ImageStats returns the image stat (total storage bytes).
 | 
					 | 
				
			||||||
func (r *Runtime) ImageStats() (*kubecontainer.ImageStats, error) {
 | 
					 | 
				
			||||||
	var imageStat kubecontainer.ImageStats
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
	listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("couldn't list images: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, image := range listResp.Images {
 | 
					 | 
				
			||||||
		imageStat.TotalStorageBytes = imageStat.TotalStorageBytes + uint64(image.Size)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &imageStat, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,123 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/golang/glog"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
					 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
					 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
					 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/util/format"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	journalTimestampLayout = "2006-01-02 15:04:05 -0700 MST"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// processLines write the lines into stdout in the required format.
 | 
					 | 
				
			||||||
func processLines(lines []string, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) {
 | 
					 | 
				
			||||||
	msgKey := "MESSAGE="
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, line := range lines {
 | 
					 | 
				
			||||||
		msgStart := strings.Index(line, msgKey)
 | 
					 | 
				
			||||||
		if msgStart < 0 {
 | 
					 | 
				
			||||||
			glog.Warningf("rkt: Invalid log line %q, missing %q", line, msgKey)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		tss := strings.TrimSpace(line[:msgStart])
 | 
					 | 
				
			||||||
		msg := strings.TrimPrefix(line[msgStart:], msgKey)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		t, err := time.Parse(journalTimestampLayout, tss)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Warningf("rkt: Failed to parse the timestamp %q: %v", tss, err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var result string
 | 
					 | 
				
			||||||
		if logOptions.Timestamps {
 | 
					 | 
				
			||||||
			result = fmt.Sprintf("%s %s\n", t.Format(time.RFC3339), msg)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			result = fmt.Sprintf("%s\n", msg)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if _, err := io.WriteString(stdout, result); err != nil {
 | 
					 | 
				
			||||||
			glog.Warningf("rkt: Cannot write log line %q to output: %v", result, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetContainerLogs uses rkt's GetLogs API to get the logs of the container.
 | 
					 | 
				
			||||||
// By default, it returns a snapshot of the container log. Set |follow| to true to
 | 
					 | 
				
			||||||
// stream the log. Set |follow| to false and specify the number of lines (e.g.
 | 
					 | 
				
			||||||
// "100" or "all") to tail the log.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// TODO(yifan): This doesn't work with lkvm stage1 yet.
 | 
					 | 
				
			||||||
func (r *Runtime) GetContainerLogs(pod *v1.Pod, containerID kubecontainer.ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error {
 | 
					 | 
				
			||||||
	id, err := parseContainerID(containerID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var since int64
 | 
					 | 
				
			||||||
	if logOptions.SinceSeconds != nil {
 | 
					 | 
				
			||||||
		t := metav1.Now().Add(-time.Duration(*logOptions.SinceSeconds) * time.Second)
 | 
					 | 
				
			||||||
		since = t.Unix()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if logOptions.SinceTime != nil {
 | 
					 | 
				
			||||||
		since = logOptions.SinceTime.Unix()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	getLogsRequest := &rktapi.GetLogsRequest{
 | 
					 | 
				
			||||||
		PodId:     id.uuid,
 | 
					 | 
				
			||||||
		AppName:   id.appName,
 | 
					 | 
				
			||||||
		Follow:    logOptions.Follow,
 | 
					 | 
				
			||||||
		SinceTime: since,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if logOptions.TailLines != nil {
 | 
					 | 
				
			||||||
		getLogsRequest.Lines = int32(*logOptions.TailLines)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	stream, err := r.apisvc.GetLogs(context.Background(), getLogsRequest)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("rkt: Failed to create log stream for pod %q: %v", format.Pod(pod), err)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		log, err := stream.Recv()
 | 
					 | 
				
			||||||
		if err == io.EOF {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("rkt: Failed to receive log for pod %q: %v", format.Pod(pod), err)
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		processLines(log.Lines, logOptions, stdout, stderr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,92 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/coreos/go-systemd/dbus"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// systemdVersion is a type wraps the int to implement kubecontainer.Version interface.
 | 
					 | 
				
			||||||
type systemdVersion int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s systemdVersion) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%d", s)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s systemdVersion) Compare(other string) (int, error) {
 | 
					 | 
				
			||||||
	v, err := strconv.Atoi(other)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return -1, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if int(s) < v {
 | 
					 | 
				
			||||||
		return -1, nil
 | 
					 | 
				
			||||||
	} else if int(s) > v {
 | 
					 | 
				
			||||||
		return 1, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// systemdInterface is an abstraction of the go-systemd/dbus to make
 | 
					 | 
				
			||||||
// it mockable for testing.
 | 
					 | 
				
			||||||
// TODO(yifan): Eventually we should move these functionalities to:
 | 
					 | 
				
			||||||
// 1. a package for launching/stopping rkt pods.
 | 
					 | 
				
			||||||
// 2. rkt api-service interface for listing pods.
 | 
					 | 
				
			||||||
// See https://github.com/coreos/rkt/issues/1769.
 | 
					 | 
				
			||||||
type systemdInterface interface {
 | 
					 | 
				
			||||||
	// Version returns the version of the systemd.
 | 
					 | 
				
			||||||
	Version() (systemdVersion, error)
 | 
					 | 
				
			||||||
	// ListUnits lists all the loaded units.
 | 
					 | 
				
			||||||
	ListUnits() ([]dbus.UnitStatus, error)
 | 
					 | 
				
			||||||
	// StopUnits stops the unit with the given name.
 | 
					 | 
				
			||||||
	StopUnit(name string, mode string, ch chan<- string) (int, error)
 | 
					 | 
				
			||||||
	// RestartUnit restarts the unit with the given name.
 | 
					 | 
				
			||||||
	RestartUnit(name string, mode string, ch chan<- string) (int, error)
 | 
					 | 
				
			||||||
	// ResetFailedUnit resets the "failed" state of a specific unit.
 | 
					 | 
				
			||||||
	ResetFailedUnit(name string) error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// systemd implements the systemdInterface using dbus and systemctl.
 | 
					 | 
				
			||||||
// All the functions other then Version() are already implemented by go-systemd/dbus.
 | 
					 | 
				
			||||||
type systemd struct {
 | 
					 | 
				
			||||||
	*dbus.Conn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// newSystemd creates a systemd object that implements systemdInterface.
 | 
					 | 
				
			||||||
func newSystemd() (*systemd, error) {
 | 
					 | 
				
			||||||
	dbusConn, err := dbus.New()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &systemd{dbusConn}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Version returns the version of the systemd.
 | 
					 | 
				
			||||||
func (s *systemd) Version() (systemdVersion, error) {
 | 
					 | 
				
			||||||
	versionStr, err := s.Conn.GetManagerProperty("Version")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return -1, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result, err := strconv.Atoi(strings.Trim(versionStr, "\""))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return -1, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return systemdVersion(result), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,111 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 rkt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	utilversion "k8s.io/kubernetes/pkg/util/version"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type versions struct {
 | 
					 | 
				
			||||||
	sync.RWMutex
 | 
					 | 
				
			||||||
	binVersion     *utilversion.Version
 | 
					 | 
				
			||||||
	apiVersion     *utilversion.Version
 | 
					 | 
				
			||||||
	systemdVersion systemdVersion
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newRktVersion(version string) (*utilversion.Version, error) {
 | 
					 | 
				
			||||||
	return utilversion.ParseSemantic(version)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *Runtime) getVersions() error {
 | 
					 | 
				
			||||||
	r.versions.Lock()
 | 
					 | 
				
			||||||
	defer r.versions.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get systemd version.
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	r.versions.systemdVersion, err = r.systemd.Version()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
	// Example for the version strings returned by GetInfo():
 | 
					 | 
				
			||||||
	// RktVersion:"0.10.0+gitb7349b1" AppcVersion:"0.7.1" ApiVersion:"1.0.0-alpha"
 | 
					 | 
				
			||||||
	resp, err := r.apisvc.GetInfo(ctx, &rktapi.GetInfoRequest{})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get rkt binary version.
 | 
					 | 
				
			||||||
	r.versions.binVersion, err = newRktVersion(resp.Info.RktVersion)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get rkt API version.
 | 
					 | 
				
			||||||
	r.versions.apiVersion, err = newRktVersion(resp.Info.ApiVersion)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// checkVersion tests whether the rkt/systemd/rkt-api-service that meet the version requirement.
 | 
					 | 
				
			||||||
// If all version requirements are met, it returns nil.
 | 
					 | 
				
			||||||
func (r *Runtime) checkVersion(minimumRktBinVersion, minimumRktApiVersion, minimumSystemdVersion string) error {
 | 
					 | 
				
			||||||
	if err := r.getVersions(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r.versions.RLock()
 | 
					 | 
				
			||||||
	defer r.versions.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check systemd version.
 | 
					 | 
				
			||||||
	result, err := r.versions.systemdVersion.Compare(minimumSystemdVersion)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if result < 0 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("rkt: systemd version(%v) is too old, requires at least %v", r.versions.systemdVersion, minimumSystemdVersion)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check rkt binary version.
 | 
					 | 
				
			||||||
	result, err = r.versions.binVersion.Compare(minimumRktBinVersion)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if result < 0 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("rkt: binary version is too old(%v), requires at least %v", r.versions.binVersion, minimumRktBinVersion)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check rkt API version.
 | 
					 | 
				
			||||||
	result, err = r.versions.apiVersion.Compare(minimumRktApiVersion)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if result < 0 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("rkt: API version is too old(%v), requires at least %v", r.versions.apiVersion, minimumRktApiVersion)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -31,7 +31,6 @@ const (
 | 
				
			|||||||
	dockerMinimumAPIVersion = "1.24.0"
 | 
						dockerMinimumAPIVersion = "1.24.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dockerTypeName = "docker"
 | 
						dockerTypeName = "docker"
 | 
				
			||||||
	rktTypeName    = "rkt"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: The admission logic in this file is runtime-dependent. It should be
 | 
					// TODO: The admission logic in this file is runtime-dependent. It should be
 | 
				
			||||||
@@ -72,14 +71,6 @@ func NewRuntimeAdmitHandler(runtime container.Runtime) (*runtimeAdmitHandler, er
 | 
				
			|||||||
				Message: "Docker API version before 1.24 does not support sysctls",
 | 
									Message: "Docker API version before 1.24 does not support sysctls",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}, nil
 | 
							}, nil
 | 
				
			||||||
	case rktTypeName:
 | 
					 | 
				
			||||||
		return &runtimeAdmitHandler{
 | 
					 | 
				
			||||||
			result: lifecycle.PodAdmitResult{
 | 
					 | 
				
			||||||
				Admit:   false,
 | 
					 | 
				
			||||||
				Reason:  UnsupportedReason,
 | 
					 | 
				
			||||||
				Message: "Rkt does not support sysctls",
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		}, nil
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		// Return admit for other runtimes.
 | 
							// Return admit for other runtimes.
 | 
				
			||||||
		return &runtimeAdmitHandler{
 | 
							return &runtimeAdmitHandler{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,6 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// different container runtimes
 | 
						// different container runtimes
 | 
				
			||||||
	DockerContainerRuntime = "docker"
 | 
						DockerContainerRuntime = "docker"
 | 
				
			||||||
	RktContainerRuntime    = "rkt"
 | 
					 | 
				
			||||||
	RemoteContainerRuntime = "remote"
 | 
						RemoteContainerRuntime = "remote"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// User visible keys for managing node allocatable enforcement on the node.
 | 
						// User visible keys for managing node allocatable enforcement on the node.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							@@ -31,7 +31,6 @@ filegroup(
 | 
				
			|||||||
        "//vendor/github.com/PuerkitoBio/purell:all-srcs",
 | 
					        "//vendor/github.com/PuerkitoBio/purell:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/PuerkitoBio/urlesc:all-srcs",
 | 
					        "//vendor/github.com/PuerkitoBio/urlesc:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/abbot/go-http-auth:all-srcs",
 | 
					        "//vendor/github.com/abbot/go-http-auth:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema:all-srcs",
 | 
					 | 
				
			||||||
        "//vendor/github.com/armon/circbuf:all-srcs",
 | 
					        "//vendor/github.com/armon/circbuf:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/asaskevich/govalidator:all-srcs",
 | 
					        "//vendor/github.com/asaskevich/govalidator:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
 | 
					        "//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
 | 
				
			||||||
@@ -125,7 +124,6 @@ filegroup(
 | 
				
			|||||||
        "//vendor/github.com/coreos/go-systemd/daemon:all-srcs",
 | 
					        "//vendor/github.com/coreos/go-systemd/daemon:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/dbus:all-srcs",
 | 
					        "//vendor/github.com/coreos/go-systemd/dbus:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/journal:all-srcs",
 | 
					        "//vendor/github.com/coreos/go-systemd/journal:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/unit:all-srcs",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-systemd/util:all-srcs",
 | 
					        "//vendor/github.com/coreos/go-systemd/util:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/coreos/pkg/capnslog:all-srcs",
 | 
					        "//vendor/github.com/coreos/pkg/capnslog:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/coreos/pkg/dlopen:all-srcs",
 | 
					        "//vendor/github.com/coreos/pkg/dlopen:all-srcs",
 | 
				
			||||||
@@ -349,7 +347,6 @@ filegroup(
 | 
				
			|||||||
        "//vendor/github.com/xanzy/go-cloudstack/cloudstack:all-srcs",
 | 
					        "//vendor/github.com/xanzy/go-cloudstack/cloudstack:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/xiang90/probing:all-srcs",
 | 
					        "//vendor/github.com/xiang90/probing:all-srcs",
 | 
				
			||||||
        "//vendor/github.com/xyproto/simpleredis:all-srcs",
 | 
					        "//vendor/github.com/xyproto/simpleredis:all-srcs",
 | 
				
			||||||
        "//vendor/go4.org/errorutil:all-srcs",
 | 
					 | 
				
			||||||
        "//vendor/golang.org/x/crypto/bcrypt:all-srcs",
 | 
					        "//vendor/golang.org/x/crypto/bcrypt:all-srcs",
 | 
				
			||||||
        "//vendor/golang.org/x/crypto/blowfish:all-srcs",
 | 
					        "//vendor/golang.org/x/crypto/blowfish:all-srcs",
 | 
				
			||||||
        "//vendor/golang.org/x/crypto/cryptobyte:all-srcs",
 | 
					        "//vendor/golang.org/x/crypto/cryptobyte:all-srcs",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										202
									
								
								vendor/github.com/appc/spec/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/appc/spec/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,202 +0,0 @@
 | 
				
			|||||||
Apache License
 | 
					 | 
				
			||||||
                           Version 2.0, January 2004
 | 
					 | 
				
			||||||
                        http://www.apache.org/licenses/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   1. Definitions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
					 | 
				
			||||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
					 | 
				
			||||||
      the copyright owner that is granting the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
					 | 
				
			||||||
      other entities that control, are controlled by, or are under common
 | 
					 | 
				
			||||||
      control with that entity. For the purposes of this definition,
 | 
					 | 
				
			||||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
					 | 
				
			||||||
      direction or management of such entity, whether by contract or
 | 
					 | 
				
			||||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
					 | 
				
			||||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
					 | 
				
			||||||
      exercising permissions granted by this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Source" form shall mean the preferred form for making modifications,
 | 
					 | 
				
			||||||
      including but not limited to software source code, documentation
 | 
					 | 
				
			||||||
      source, and configuration files.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Object" form shall mean any form resulting from mechanical
 | 
					 | 
				
			||||||
      transformation or translation of a Source form, including but
 | 
					 | 
				
			||||||
      not limited to compiled object code, generated documentation,
 | 
					 | 
				
			||||||
      and conversions to other media types.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
					 | 
				
			||||||
      Object form, made available under the License, as indicated by a
 | 
					 | 
				
			||||||
      copyright notice that is included in or attached to the work
 | 
					 | 
				
			||||||
      (an example is provided in the Appendix below).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
					 | 
				
			||||||
      form, that is based on (or derived from) the Work and for which the
 | 
					 | 
				
			||||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
					 | 
				
			||||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
					 | 
				
			||||||
      of this License, Derivative Works shall not include works that remain
 | 
					 | 
				
			||||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
					 | 
				
			||||||
      the Work and Derivative Works thereof.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Contribution" shall mean any work of authorship, including
 | 
					 | 
				
			||||||
      the original version of the Work and any modifications or additions
 | 
					 | 
				
			||||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
					 | 
				
			||||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
					 | 
				
			||||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
					 | 
				
			||||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
					 | 
				
			||||||
      means any form of electronic, verbal, or written communication sent
 | 
					 | 
				
			||||||
      to the Licensor or its representatives, including but not limited to
 | 
					 | 
				
			||||||
      communication on electronic mailing lists, source code control systems,
 | 
					 | 
				
			||||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
					 | 
				
			||||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
					 | 
				
			||||||
      excluding communication that is conspicuously marked or otherwise
 | 
					 | 
				
			||||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
					 | 
				
			||||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
					 | 
				
			||||||
      subsequently incorporated within the Work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
					 | 
				
			||||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
					 | 
				
			||||||
      Work and such Derivative Works in Source or Object form.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
      (except as stated in this section) patent license to make, have made,
 | 
					 | 
				
			||||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
					 | 
				
			||||||
      where such license applies only to those patent claims licensable
 | 
					 | 
				
			||||||
      by such Contributor that are necessarily infringed by their
 | 
					 | 
				
			||||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
					 | 
				
			||||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
					 | 
				
			||||||
      institute patent litigation against any entity (including a
 | 
					 | 
				
			||||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
					 | 
				
			||||||
      or a Contribution incorporated within the Work constitutes direct
 | 
					 | 
				
			||||||
      or contributory patent infringement, then any patent licenses
 | 
					 | 
				
			||||||
      granted to You under this License for that Work shall terminate
 | 
					 | 
				
			||||||
      as of the date such litigation is filed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
					 | 
				
			||||||
      Work or Derivative Works thereof in any medium, with or without
 | 
					 | 
				
			||||||
      modifications, and in Source or Object form, provided that You
 | 
					 | 
				
			||||||
      meet the following conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (a) You must give any other recipients of the Work or
 | 
					 | 
				
			||||||
          Derivative Works a copy of this License; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (b) You must cause any modified files to carry prominent notices
 | 
					 | 
				
			||||||
          stating that You changed the files; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
					 | 
				
			||||||
          that You distribute, all copyright, patent, trademark, and
 | 
					 | 
				
			||||||
          attribution notices from the Source form of the Work,
 | 
					 | 
				
			||||||
          excluding those notices that do not pertain to any part of
 | 
					 | 
				
			||||||
          the Derivative Works; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
					 | 
				
			||||||
          distribution, then any Derivative Works that You distribute must
 | 
					 | 
				
			||||||
          include a readable copy of the attribution notices contained
 | 
					 | 
				
			||||||
          within such NOTICE file, excluding those notices that do not
 | 
					 | 
				
			||||||
          pertain to any part of the Derivative Works, in at least one
 | 
					 | 
				
			||||||
          of the following places: within a NOTICE text file distributed
 | 
					 | 
				
			||||||
          as part of the Derivative Works; within the Source form or
 | 
					 | 
				
			||||||
          documentation, if provided along with the Derivative Works; or,
 | 
					 | 
				
			||||||
          within a display generated by the Derivative Works, if and
 | 
					 | 
				
			||||||
          wherever such third-party notices normally appear. The contents
 | 
					 | 
				
			||||||
          of the NOTICE file are for informational purposes only and
 | 
					 | 
				
			||||||
          do not modify the License. You may add Your own attribution
 | 
					 | 
				
			||||||
          notices within Derivative Works that You distribute, alongside
 | 
					 | 
				
			||||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
					 | 
				
			||||||
          that such additional attribution notices cannot be construed
 | 
					 | 
				
			||||||
          as modifying the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      You may add Your own copyright statement to Your modifications and
 | 
					 | 
				
			||||||
      may provide additional or different license terms and conditions
 | 
					 | 
				
			||||||
      for use, reproduction, or distribution of Your modifications, or
 | 
					 | 
				
			||||||
      for any such Derivative Works as a whole, provided Your use,
 | 
					 | 
				
			||||||
      reproduction, and distribution of the Work otherwise complies with
 | 
					 | 
				
			||||||
      the conditions stated in this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
					 | 
				
			||||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
					 | 
				
			||||||
      by You to the Licensor shall be under the terms and conditions of
 | 
					 | 
				
			||||||
      this License, without any additional terms or conditions.
 | 
					 | 
				
			||||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
					 | 
				
			||||||
      the terms of any separate license agreement you may have executed
 | 
					 | 
				
			||||||
      with Licensor regarding such Contributions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
					 | 
				
			||||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
					 | 
				
			||||||
      except as required for reasonable and customary use in describing the
 | 
					 | 
				
			||||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
					 | 
				
			||||||
      agreed to in writing, Licensor provides the Work (and each
 | 
					 | 
				
			||||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
					 | 
				
			||||||
      implied, including, without limitation, any warranties or conditions
 | 
					 | 
				
			||||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
					 | 
				
			||||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
					 | 
				
			||||||
      appropriateness of using or redistributing the Work and assume any
 | 
					 | 
				
			||||||
      risks associated with Your exercise of permissions under this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
					 | 
				
			||||||
      whether in tort (including negligence), contract, or otherwise,
 | 
					 | 
				
			||||||
      unless required by applicable law (such as deliberate and grossly
 | 
					 | 
				
			||||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
					 | 
				
			||||||
      liable to You for damages, including any direct, indirect, special,
 | 
					 | 
				
			||||||
      incidental, or consequential damages of any character arising as a
 | 
					 | 
				
			||||||
      result of this License or out of the use or inability to use the
 | 
					 | 
				
			||||||
      Work (including but not limited to damages for loss of goodwill,
 | 
					 | 
				
			||||||
      work stoppage, computer failure or malfunction, or any and all
 | 
					 | 
				
			||||||
      other commercial damages or losses), even if such Contributor
 | 
					 | 
				
			||||||
      has been advised of the possibility of such damages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
					 | 
				
			||||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
					 | 
				
			||||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
					 | 
				
			||||||
      or other liability obligations and/or rights consistent with this
 | 
					 | 
				
			||||||
      License. However, in accepting such obligations, You may act only
 | 
					 | 
				
			||||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
					 | 
				
			||||||
      of any other Contributor, and only if You agree to indemnify,
 | 
					 | 
				
			||||||
      defend, and hold each Contributor harmless for any liability
 | 
					 | 
				
			||||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
					 | 
				
			||||||
      of your accepting any such warranty or additional liability.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   END OF TERMS AND CONDITIONS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								vendor/github.com/appc/spec/schema/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/appc/spec/schema/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,36 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "doc.go",
 | 
					 | 
				
			||||||
        "image.go",
 | 
					 | 
				
			||||||
        "kind.go",
 | 
					 | 
				
			||||||
        "pod.go",
 | 
					 | 
				
			||||||
        "version.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    importpath = "github.com/appc/spec/schema",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/go4.org/errorutil:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        ":package-srcs",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/common:all-srcs",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types:all-srcs",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								vendor/github.com/appc/spec/schema/common/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/appc/spec/schema/common/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = ["common.go"],
 | 
					 | 
				
			||||||
    importpath = "github.com/appc/spec/schema/common",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										40
									
								
								vendor/github.com/appc/spec/schema/common/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/appc/spec/schema/common/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,40 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 common
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MakeQueryString takes a comma-separated LABEL=VALUE string and returns an
 | 
					 | 
				
			||||||
// "&"-separated string with URL escaped values.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Examples:
 | 
					 | 
				
			||||||
// 	version=1.0.0,label=v1+v2 -> version=1.0.0&label=v1%2Bv2
 | 
					 | 
				
			||||||
// 	name=db,source=/tmp$1 -> name=db&source=%2Ftmp%241
 | 
					 | 
				
			||||||
func MakeQueryString(app string) (string, error) {
 | 
					 | 
				
			||||||
	parts := strings.Split(app, ",")
 | 
					 | 
				
			||||||
	escapedParts := make([]string, len(parts))
 | 
					 | 
				
			||||||
	for i, s := range parts {
 | 
					 | 
				
			||||||
		p := strings.SplitN(s, "=", 2)
 | 
					 | 
				
			||||||
		if len(p) != 2 {
 | 
					 | 
				
			||||||
			return "", fmt.Errorf("malformed string %q - has a label without a value: %s", app, p[0])
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		escapedParts[i] = fmt.Sprintf("%s=%s", p[0], url.QueryEscape(p[1]))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(escapedParts, "&"), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								vendor/github.com/appc/spec/schema/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/appc/spec/schema/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,25 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 schema provides definitions for the JSON schema of the different
 | 
					 | 
				
			||||||
// manifests in the App Container Specification. The manifests are canonically
 | 
					 | 
				
			||||||
// represented in their respective structs:
 | 
					 | 
				
			||||||
//   - `ImageManifest`
 | 
					 | 
				
			||||||
//   - `PodManifest`
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Validation is performed through serialization: if a blob of JSON data will
 | 
					 | 
				
			||||||
// unmarshal to one of the *Manifests, it is considered a valid implementation
 | 
					 | 
				
			||||||
// of the standard. Similarly, if a constructed *Manifest struct marshals
 | 
					 | 
				
			||||||
// successfully to JSON, it must be valid.
 | 
					 | 
				
			||||||
package schema
 | 
					 | 
				
			||||||
							
								
								
									
										103
									
								
								vendor/github.com/appc/spec/schema/image.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/appc/spec/schema/image.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,103 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 schema
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/types"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"go4.org/errorutil"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ACIExtension      = ".aci"
 | 
					 | 
				
			||||||
	ImageManifestKind = types.ACKind("ImageManifest")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ImageManifest struct {
 | 
					 | 
				
			||||||
	ACKind        types.ACKind       `json:"acKind"`
 | 
					 | 
				
			||||||
	ACVersion     types.SemVer       `json:"acVersion"`
 | 
					 | 
				
			||||||
	Name          types.ACIdentifier `json:"name"`
 | 
					 | 
				
			||||||
	Labels        types.Labels       `json:"labels,omitempty"`
 | 
					 | 
				
			||||||
	App           *types.App         `json:"app,omitempty"`
 | 
					 | 
				
			||||||
	Annotations   types.Annotations  `json:"annotations,omitempty"`
 | 
					 | 
				
			||||||
	Dependencies  types.Dependencies `json:"dependencies,omitempty"`
 | 
					 | 
				
			||||||
	PathWhitelist []string           `json:"pathWhitelist,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// imageManifest is a model to facilitate extra validation during the
 | 
					 | 
				
			||||||
// unmarshalling of the ImageManifest
 | 
					 | 
				
			||||||
type imageManifest ImageManifest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func BlankImageManifest() *ImageManifest {
 | 
					 | 
				
			||||||
	return &ImageManifest{ACKind: ImageManifestKind, ACVersion: AppContainerVersion}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (im *ImageManifest) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	a := imageManifest(*im)
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &a)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if serr, ok := err.(*json.SyntaxError); ok {
 | 
					 | 
				
			||||||
			line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(data), serr.Offset)
 | 
					 | 
				
			||||||
			return fmt.Errorf("\nError at line %d, column %d\n%s%v", line, col, highlight, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nim := ImageManifest(a)
 | 
					 | 
				
			||||||
	if err := nim.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*im = nim
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (im ImageManifest) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := im.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(imageManifest(im))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var imKindError = types.InvalidACKindError(ImageManifestKind)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// assertValid performs extra assertions on an ImageManifest to ensure that
 | 
					 | 
				
			||||||
// fields are set appropriately, etc. It is used exclusively when marshalling
 | 
					 | 
				
			||||||
// and unmarshalling an ImageManifest. Most field-specific validation is
 | 
					 | 
				
			||||||
// performed through the individual types being marshalled; assertValid()
 | 
					 | 
				
			||||||
// should only deal with higher-level validation.
 | 
					 | 
				
			||||||
func (im *ImageManifest) assertValid() error {
 | 
					 | 
				
			||||||
	if im.ACKind != ImageManifestKind {
 | 
					 | 
				
			||||||
		return imKindError
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if im.ACVersion.Empty() {
 | 
					 | 
				
			||||||
		return errors.New(`acVersion must be set`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if im.Name.Empty() {
 | 
					 | 
				
			||||||
		return errors.New(`name must be set`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (im *ImageManifest) GetLabel(name string) (val string, ok bool) {
 | 
					 | 
				
			||||||
	return im.Labels.Get(name)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (im *ImageManifest) GetAnnotation(name string) (val string, ok bool) {
 | 
					 | 
				
			||||||
	return im.Annotations.Get(name)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										42
									
								
								vendor/github.com/appc/spec/schema/kind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/appc/spec/schema/kind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,42 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 schema
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/types"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Kind struct {
 | 
					 | 
				
			||||||
	ACVersion types.SemVer `json:"acVersion"`
 | 
					 | 
				
			||||||
	ACKind    types.ACKind `json:"acKind"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type kind Kind
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (k *Kind) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	nk := kind{}
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &nk)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*k = Kind(nk)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (k Kind) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	return json.Marshal(kind(k))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										173
									
								
								vendor/github.com/appc/spec/schema/pod.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										173
									
								
								vendor/github.com/appc/spec/schema/pod.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,173 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 schema
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/types"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"go4.org/errorutil"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const PodManifestKind = types.ACKind("PodManifest")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type PodManifest struct {
 | 
					 | 
				
			||||||
	ACVersion       types.SemVer          `json:"acVersion"`
 | 
					 | 
				
			||||||
	ACKind          types.ACKind          `json:"acKind"`
 | 
					 | 
				
			||||||
	Apps            AppList               `json:"apps"`
 | 
					 | 
				
			||||||
	Volumes         []types.Volume        `json:"volumes"`
 | 
					 | 
				
			||||||
	Isolators       []types.Isolator      `json:"isolators"`
 | 
					 | 
				
			||||||
	Annotations     types.Annotations     `json:"annotations"`
 | 
					 | 
				
			||||||
	Ports           []types.ExposedPort   `json:"ports"`
 | 
					 | 
				
			||||||
	UserAnnotations types.UserAnnotations `json:"userAnnotations,omitempty"`
 | 
					 | 
				
			||||||
	UserLabels      types.UserLabels      `json:"userLabels,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// podManifest is a model to facilitate extra validation during the
 | 
					 | 
				
			||||||
// unmarshalling of the PodManifest
 | 
					 | 
				
			||||||
type podManifest PodManifest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func BlankPodManifest() *PodManifest {
 | 
					 | 
				
			||||||
	return &PodManifest{ACKind: PodManifestKind, ACVersion: AppContainerVersion}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (pm *PodManifest) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	p := podManifest(*pm)
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &p)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if serr, ok := err.(*json.SyntaxError); ok {
 | 
					 | 
				
			||||||
			line, col, highlight := errorutil.HighlightBytePosition(bytes.NewReader(data), serr.Offset)
 | 
					 | 
				
			||||||
			return fmt.Errorf("\nError at line %d, column %d\n%s%v", line, col, highlight, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	npm := PodManifest(p)
 | 
					 | 
				
			||||||
	if err := npm.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*pm = npm
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (pm PodManifest) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := pm.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(podManifest(pm))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var pmKindError = types.InvalidACKindError(PodManifestKind)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// assertValid performs extra assertions on an PodManifest to
 | 
					 | 
				
			||||||
// ensure that fields are set appropriately, etc. It is used exclusively when
 | 
					 | 
				
			||||||
// marshalling and unmarshalling an PodManifest. Most
 | 
					 | 
				
			||||||
// field-specific validation is performed through the individual types being
 | 
					 | 
				
			||||||
// marshalled; assertValid() should only deal with higher-level validation.
 | 
					 | 
				
			||||||
func (pm *PodManifest) assertValid() error {
 | 
					 | 
				
			||||||
	if pm.ACKind != PodManifestKind {
 | 
					 | 
				
			||||||
		return pmKindError
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type AppList []RuntimeApp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type appList AppList
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (al *AppList) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	a := appList{}
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &a)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nal := AppList(a)
 | 
					 | 
				
			||||||
	if err := nal.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*al = nal
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (al AppList) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := al.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(appList(al))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (al AppList) assertValid() error {
 | 
					 | 
				
			||||||
	seen := map[types.ACName]bool{}
 | 
					 | 
				
			||||||
	for _, a := range al {
 | 
					 | 
				
			||||||
		if _, ok := seen[a.Name]; ok {
 | 
					 | 
				
			||||||
			return fmt.Errorf(`duplicate apps of name %q`, a.Name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		seen[a.Name] = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get retrieves an app by the specified name from the AppList; if there is
 | 
					 | 
				
			||||||
// no such app, nil is returned. The returned *RuntimeApp MUST be considered
 | 
					 | 
				
			||||||
// read-only.
 | 
					 | 
				
			||||||
func (al AppList) Get(name types.ACName) *RuntimeApp {
 | 
					 | 
				
			||||||
	for _, a := range al {
 | 
					 | 
				
			||||||
		if name.Equals(a.Name) {
 | 
					 | 
				
			||||||
			aa := a
 | 
					 | 
				
			||||||
			return &aa
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Mount describes the mapping between a volume and the path it is mounted
 | 
					 | 
				
			||||||
// inside of an app's filesystem.
 | 
					 | 
				
			||||||
// The AppVolume is optional. If missing, the pod-level Volume of the
 | 
					 | 
				
			||||||
// same name shall be used.
 | 
					 | 
				
			||||||
type Mount struct {
 | 
					 | 
				
			||||||
	Volume    types.ACName  `json:"volume"`
 | 
					 | 
				
			||||||
	Path      string        `json:"path"`
 | 
					 | 
				
			||||||
	AppVolume *types.Volume `json:"appVolume,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r Mount) assertValid() error {
 | 
					 | 
				
			||||||
	if r.Volume.Empty() {
 | 
					 | 
				
			||||||
		return errors.New("volume must be set")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Path == "" {
 | 
					 | 
				
			||||||
		return errors.New("path must be set")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RuntimeApp describes an application referenced in a PodManifest
 | 
					 | 
				
			||||||
type RuntimeApp struct {
 | 
					 | 
				
			||||||
	Name           types.ACName      `json:"name"`
 | 
					 | 
				
			||||||
	Image          RuntimeImage      `json:"image"`
 | 
					 | 
				
			||||||
	App            *types.App        `json:"app,omitempty"`
 | 
					 | 
				
			||||||
	ReadOnlyRootFS bool              `json:"readOnlyRootFS,omitempty"`
 | 
					 | 
				
			||||||
	Mounts         []Mount           `json:"mounts,omitempty"`
 | 
					 | 
				
			||||||
	Annotations    types.Annotations `json:"annotations,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RuntimeImage describes an image referenced in a RuntimeApp
 | 
					 | 
				
			||||||
type RuntimeImage struct {
 | 
					 | 
				
			||||||
	Name   *types.ACIdentifier `json:"name,omitempty"`
 | 
					 | 
				
			||||||
	ID     types.Hash          `json:"id"`
 | 
					 | 
				
			||||||
	Labels types.Labels        `json:"labels,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										57
									
								
								vendor/github.com/appc/spec/schema/types/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/appc/spec/schema/types/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,57 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "acidentifier.go",
 | 
					 | 
				
			||||||
        "ackind.go",
 | 
					 | 
				
			||||||
        "acname.go",
 | 
					 | 
				
			||||||
        "annotations.go",
 | 
					 | 
				
			||||||
        "app.go",
 | 
					 | 
				
			||||||
        "date.go",
 | 
					 | 
				
			||||||
        "dependencies.go",
 | 
					 | 
				
			||||||
        "doc.go",
 | 
					 | 
				
			||||||
        "environment.go",
 | 
					 | 
				
			||||||
        "errors.go",
 | 
					 | 
				
			||||||
        "event_handler.go",
 | 
					 | 
				
			||||||
        "exec.go",
 | 
					 | 
				
			||||||
        "hash.go",
 | 
					 | 
				
			||||||
        "isolator.go",
 | 
					 | 
				
			||||||
        "isolator_linux_specific.go",
 | 
					 | 
				
			||||||
        "isolator_resources.go",
 | 
					 | 
				
			||||||
        "isolator_unix.go",
 | 
					 | 
				
			||||||
        "labels.go",
 | 
					 | 
				
			||||||
        "mountpoint.go",
 | 
					 | 
				
			||||||
        "port.go",
 | 
					 | 
				
			||||||
        "semver.go",
 | 
					 | 
				
			||||||
        "url.go",
 | 
					 | 
				
			||||||
        "user_annotations.go",
 | 
					 | 
				
			||||||
        "user_labels.go",
 | 
					 | 
				
			||||||
        "uuid.go",
 | 
					 | 
				
			||||||
        "volume.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    importpath = "github.com/appc/spec/schema/types",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/common:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types/resource:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/github.com/coreos/go-semver/semver:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        ":package-srcs",
 | 
					 | 
				
			||||||
        "//vendor/github.com/appc/spec/schema/types/resource:all-srcs",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										145
									
								
								vendor/github.com/appc/spec/schema/types/acidentifier.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/appc/spec/schema/types/acidentifier.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,145 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// ValidACIdentifier is a regular expression that defines a valid ACIdentifier
 | 
					 | 
				
			||||||
	ValidACIdentifier = regexp.MustCompile("^[a-z0-9]+([-._~/][a-z0-9]+)*$")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	invalidACIdentifierChars = regexp.MustCompile("[^a-z0-9-._~/]")
 | 
					 | 
				
			||||||
	invalidACIdentifierEdges = regexp.MustCompile("(^[-._~/]+)|([-._~/]+$)")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ErrEmptyACIdentifier         = ACIdentifierError("ACIdentifier cannot be empty")
 | 
					 | 
				
			||||||
	ErrInvalidEdgeInACIdentifier = ACIdentifierError("ACIdentifier must start and end with only lower case " +
 | 
					 | 
				
			||||||
		"alphanumeric characters")
 | 
					 | 
				
			||||||
	ErrInvalidCharInACIdentifier = ACIdentifierError("ACIdentifier must contain only lower case " +
 | 
					 | 
				
			||||||
		`alphanumeric characters plus "-._~/"`)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ACIdentifier (an App-Container Identifier) is a format used by keys in image names
 | 
					 | 
				
			||||||
// and image labels of the App Container Standard. An ACIdentifier is restricted to numeric
 | 
					 | 
				
			||||||
// and lowercase URI unreserved characters defined in URI RFC[1]; all alphabetical characters
 | 
					 | 
				
			||||||
// must be lowercase only. Furthermore, the first and last character ("edges") must be
 | 
					 | 
				
			||||||
// alphanumeric, and an ACIdentifier cannot be empty. Programmatically, an ACIdentifier must
 | 
					 | 
				
			||||||
// conform to the regular expression ValidACIdentifier.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// [1] http://tools.ietf.org/html/rfc3986#section-2.3
 | 
					 | 
				
			||||||
type ACIdentifier string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n ACIdentifier) String() string {
 | 
					 | 
				
			||||||
	return string(n)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set sets the ACIdentifier to the given value, if it is valid; if not,
 | 
					 | 
				
			||||||
// an error is returned.
 | 
					 | 
				
			||||||
func (n *ACIdentifier) Set(s string) error {
 | 
					 | 
				
			||||||
	nn, err := NewACIdentifier(s)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		*n = *nn
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Equals checks whether a given ACIdentifier is equal to this one.
 | 
					 | 
				
			||||||
func (n ACIdentifier) Equals(o ACIdentifier) bool {
 | 
					 | 
				
			||||||
	return strings.ToLower(string(n)) == strings.ToLower(string(o))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Empty returns a boolean indicating whether this ACIdentifier is empty.
 | 
					 | 
				
			||||||
func (n ACIdentifier) Empty() bool {
 | 
					 | 
				
			||||||
	return n.String() == ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewACIdentifier generates a new ACIdentifier from a string. If the given string is
 | 
					 | 
				
			||||||
// not a valid ACIdentifier, nil and an error are returned.
 | 
					 | 
				
			||||||
func NewACIdentifier(s string) (*ACIdentifier, error) {
 | 
					 | 
				
			||||||
	n := ACIdentifier(s)
 | 
					 | 
				
			||||||
	if err := n.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &n, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MustACIdentifier generates a new ACIdentifier from a string, If the given string is
 | 
					 | 
				
			||||||
// not a valid ACIdentifier, it panics.
 | 
					 | 
				
			||||||
func MustACIdentifier(s string) *ACIdentifier {
 | 
					 | 
				
			||||||
	n, err := NewACIdentifier(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n ACIdentifier) assertValid() error {
 | 
					 | 
				
			||||||
	s := string(n)
 | 
					 | 
				
			||||||
	if len(s) == 0 {
 | 
					 | 
				
			||||||
		return ErrEmptyACIdentifier
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if invalidACIdentifierChars.MatchString(s) {
 | 
					 | 
				
			||||||
		return ErrInvalidCharInACIdentifier
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if invalidACIdentifierEdges.MatchString(s) {
 | 
					 | 
				
			||||||
		return ErrInvalidEdgeInACIdentifier
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON implements the json.Unmarshaler interface
 | 
					 | 
				
			||||||
func (n *ACIdentifier) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nn, err := NewACIdentifier(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*n = *nn
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MarshalJSON implements the json.Marshaler interface
 | 
					 | 
				
			||||||
func (n ACIdentifier) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := n.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(n.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SanitizeACIdentifier replaces every invalid ACIdentifier character in s with an underscore
 | 
					 | 
				
			||||||
// making it a legal ACIdentifier string. If the character is an upper case letter it
 | 
					 | 
				
			||||||
// replaces it with its lower case. It also removes illegal edge characters
 | 
					 | 
				
			||||||
// (hyphens, period, underscore, tilde and slash).
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This is a helper function and its algorithm is not part of the spec. It
 | 
					 | 
				
			||||||
// should not be called without the user explicitly asking for a suggestion.
 | 
					 | 
				
			||||||
func SanitizeACIdentifier(s string) (string, error) {
 | 
					 | 
				
			||||||
	s = strings.ToLower(s)
 | 
					 | 
				
			||||||
	s = invalidACIdentifierChars.ReplaceAllString(s, "_")
 | 
					 | 
				
			||||||
	s = invalidACIdentifierEdges.ReplaceAllString(s, "")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if s == "" {
 | 
					 | 
				
			||||||
		return "", errors.New("must contain at least one valid character")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return s, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										67
									
								
								vendor/github.com/appc/spec/schema/types/ackind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/appc/spec/schema/types/ackind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,67 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrNoACKind = ACKindError("ACKind must be set")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ACKind wraps a string to define a field which must be set with one of
 | 
					 | 
				
			||||||
// several ACKind values. If it is unset, or has an invalid value, the field
 | 
					 | 
				
			||||||
// will refuse to marshal/unmarshal.
 | 
					 | 
				
			||||||
type ACKind string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a ACKind) String() string {
 | 
					 | 
				
			||||||
	return string(a)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a ACKind) assertValid() error {
 | 
					 | 
				
			||||||
	s := a.String()
 | 
					 | 
				
			||||||
	switch s {
 | 
					 | 
				
			||||||
	case "ImageManifest", "PodManifest":
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case "":
 | 
					 | 
				
			||||||
		return ErrNoACKind
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		msg := fmt.Sprintf("bad ACKind: %s", s)
 | 
					 | 
				
			||||||
		return ACKindError(msg)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a ACKind) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := a.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(a.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a *ACKind) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	na := ACKind(s)
 | 
					 | 
				
			||||||
	if err := na.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*a = na
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										145
									
								
								vendor/github.com/appc/spec/schema/types/acname.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/appc/spec/schema/types/acname.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,145 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// ValidACName is a regular expression that defines a valid ACName
 | 
					 | 
				
			||||||
	ValidACName = regexp.MustCompile("^[a-z0-9]+([-][a-z0-9]+)*$")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	invalidACNameChars = regexp.MustCompile("[^a-z0-9-]")
 | 
					 | 
				
			||||||
	invalidACNameEdges = regexp.MustCompile("(^[-]+)|([-]+$)")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ErrEmptyACName         = ACNameError("ACName cannot be empty")
 | 
					 | 
				
			||||||
	ErrInvalidEdgeInACName = ACNameError("ACName must start and end with only lower case " +
 | 
					 | 
				
			||||||
		"alphanumeric characters")
 | 
					 | 
				
			||||||
	ErrInvalidCharInACName = ACNameError("ACName must contain only lower case " +
 | 
					 | 
				
			||||||
		`alphanumeric characters plus "-"`)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ACName (an App-Container Name) is a format used by keys in different formats
 | 
					 | 
				
			||||||
// of the App Container Standard. An ACName is restricted to numeric and lowercase
 | 
					 | 
				
			||||||
// characters accepted by the DNS RFC[1] plus "-"; all alphabetical characters must
 | 
					 | 
				
			||||||
// be lowercase only. Furthermore, the first and last character ("edges") must be
 | 
					 | 
				
			||||||
// alphanumeric, and an ACName cannot be empty. Programmatically, an ACName must
 | 
					 | 
				
			||||||
// conform to the regular expression ValidACName.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// [1] http://tools.ietf.org/html/rfc1123#page-13
 | 
					 | 
				
			||||||
type ACName string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n ACName) String() string {
 | 
					 | 
				
			||||||
	return string(n)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set sets the ACName to the given value, if it is valid; if not,
 | 
					 | 
				
			||||||
// an error is returned.
 | 
					 | 
				
			||||||
func (n *ACName) Set(s string) error {
 | 
					 | 
				
			||||||
	nn, err := NewACName(s)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		*n = *nn
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Equals checks whether a given ACName is equal to this one.
 | 
					 | 
				
			||||||
func (n ACName) Equals(o ACName) bool {
 | 
					 | 
				
			||||||
	return strings.ToLower(string(n)) == strings.ToLower(string(o))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Empty returns a boolean indicating whether this ACName is empty.
 | 
					 | 
				
			||||||
func (n ACName) Empty() bool {
 | 
					 | 
				
			||||||
	return n.String() == ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewACName generates a new ACName from a string. If the given string is
 | 
					 | 
				
			||||||
// not a valid ACName, nil and an error are returned.
 | 
					 | 
				
			||||||
func NewACName(s string) (*ACName, error) {
 | 
					 | 
				
			||||||
	n := ACName(s)
 | 
					 | 
				
			||||||
	if err := n.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &n, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MustACName generates a new ACName from a string, If the given string is
 | 
					 | 
				
			||||||
// not a valid ACName, it panics.
 | 
					 | 
				
			||||||
func MustACName(s string) *ACName {
 | 
					 | 
				
			||||||
	n, err := NewACName(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n ACName) assertValid() error {
 | 
					 | 
				
			||||||
	s := string(n)
 | 
					 | 
				
			||||||
	if len(s) == 0 {
 | 
					 | 
				
			||||||
		return ErrEmptyACName
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if invalidACNameChars.MatchString(s) {
 | 
					 | 
				
			||||||
		return ErrInvalidCharInACName
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if invalidACNameEdges.MatchString(s) {
 | 
					 | 
				
			||||||
		return ErrInvalidEdgeInACName
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON implements the json.Unmarshaler interface
 | 
					 | 
				
			||||||
func (n *ACName) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nn, err := NewACName(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*n = *nn
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MarshalJSON implements the json.Marshaler interface
 | 
					 | 
				
			||||||
func (n ACName) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := n.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(n.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SanitizeACName replaces every invalid ACName character in s with a dash
 | 
					 | 
				
			||||||
// making it a legal ACName string. If the character is an upper case letter it
 | 
					 | 
				
			||||||
// replaces it with its lower case. It also removes illegal edge characters
 | 
					 | 
				
			||||||
// (hyphens).
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This is a helper function and its algorithm is not part of the spec. It
 | 
					 | 
				
			||||||
// should not be called without the user explicitly asking for a suggestion.
 | 
					 | 
				
			||||||
func SanitizeACName(s string) (string, error) {
 | 
					 | 
				
			||||||
	s = strings.ToLower(s)
 | 
					 | 
				
			||||||
	s = invalidACNameChars.ReplaceAllString(s, "-")
 | 
					 | 
				
			||||||
	s = invalidACNameEdges.ReplaceAllString(s, "")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if s == "" {
 | 
					 | 
				
			||||||
		return "", errors.New("must contain at least one valid character")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return s, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										106
									
								
								vendor/github.com/appc/spec/schema/types/annotations.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/appc/spec/schema/types/annotations.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,106 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Annotations []Annotation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type annotations Annotations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Annotation struct {
 | 
					 | 
				
			||||||
	Name  ACIdentifier `json:"name"`
 | 
					 | 
				
			||||||
	Value string       `json:"value"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a Annotations) assertValid() error {
 | 
					 | 
				
			||||||
	seen := map[ACIdentifier]string{}
 | 
					 | 
				
			||||||
	for _, anno := range a {
 | 
					 | 
				
			||||||
		_, ok := seen[anno.Name]
 | 
					 | 
				
			||||||
		if ok {
 | 
					 | 
				
			||||||
			return fmt.Errorf(`duplicate annotations of name %q`, anno.Name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		seen[anno.Name] = anno.Value
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if c, ok := seen["created"]; ok {
 | 
					 | 
				
			||||||
		if _, err := NewDate(c); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if h, ok := seen["homepage"]; ok {
 | 
					 | 
				
			||||||
		if _, err := NewURL(h); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if d, ok := seen["documentation"]; ok {
 | 
					 | 
				
			||||||
		if _, err := NewURL(d); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a Annotations) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := a.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(annotations(a))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a *Annotations) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var ja annotations
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &ja); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	na := Annotations(ja)
 | 
					 | 
				
			||||||
	if err := na.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*a = na
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Retrieve the value of an annotation by the given name from Annotations, if
 | 
					 | 
				
			||||||
// it exists.
 | 
					 | 
				
			||||||
func (a Annotations) Get(name string) (val string, ok bool) {
 | 
					 | 
				
			||||||
	for _, anno := range a {
 | 
					 | 
				
			||||||
		if anno.Name.String() == name {
 | 
					 | 
				
			||||||
			return anno.Value, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "", false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set sets the value of an annotation by the given name, overwriting if one already exists.
 | 
					 | 
				
			||||||
func (a *Annotations) Set(name ACIdentifier, value string) {
 | 
					 | 
				
			||||||
	for i, anno := range *a {
 | 
					 | 
				
			||||||
		if anno.Name.Equals(name) {
 | 
					 | 
				
			||||||
			(*a)[i] = Annotation{
 | 
					 | 
				
			||||||
				Name:  name,
 | 
					 | 
				
			||||||
				Value: value,
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	anno := Annotation{
 | 
					 | 
				
			||||||
		Name:  name,
 | 
					 | 
				
			||||||
		Value: value,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*a = append(*a, anno)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										95
									
								
								vendor/github.com/appc/spec/schema/types/app.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/appc/spec/schema/types/app.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,95 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"path"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type App struct {
 | 
					 | 
				
			||||||
	Exec              Exec            `json:"exec"`
 | 
					 | 
				
			||||||
	EventHandlers     []EventHandler  `json:"eventHandlers,omitempty"`
 | 
					 | 
				
			||||||
	User              string          `json:"user"`
 | 
					 | 
				
			||||||
	Group             string          `json:"group"`
 | 
					 | 
				
			||||||
	SupplementaryGIDs []int           `json:"supplementaryGIDs,omitempty"`
 | 
					 | 
				
			||||||
	WorkingDirectory  string          `json:"workingDirectory,omitempty"`
 | 
					 | 
				
			||||||
	Environment       Environment     `json:"environment,omitempty"`
 | 
					 | 
				
			||||||
	MountPoints       []MountPoint    `json:"mountPoints,omitempty"`
 | 
					 | 
				
			||||||
	Ports             []Port          `json:"ports,omitempty"`
 | 
					 | 
				
			||||||
	Isolators         Isolators       `json:"isolators,omitempty"`
 | 
					 | 
				
			||||||
	UserAnnotations   UserAnnotations `json:"userAnnotations,omitempty"`
 | 
					 | 
				
			||||||
	UserLabels        UserLabels      `json:"userLabels,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// app is a model to facilitate extra validation during the
 | 
					 | 
				
			||||||
// unmarshalling of the App
 | 
					 | 
				
			||||||
type app App
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a *App) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	ja := app(*a)
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &ja)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	na := App(ja)
 | 
					 | 
				
			||||||
	if err := na.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if na.Environment == nil {
 | 
					 | 
				
			||||||
		na.Environment = make(Environment, 0)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*a = na
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a App) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := a.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(app(a))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a *App) assertValid() error {
 | 
					 | 
				
			||||||
	if err := a.Exec.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a.User == "" {
 | 
					 | 
				
			||||||
		return errors.New(`user is required`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a.Group == "" {
 | 
					 | 
				
			||||||
		return errors.New(`group is required`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !path.IsAbs(a.WorkingDirectory) && a.WorkingDirectory != "" {
 | 
					 | 
				
			||||||
		return errors.New("workingDirectory must be an absolute path")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	eh := make(map[string]bool)
 | 
					 | 
				
			||||||
	for _, e := range a.EventHandlers {
 | 
					 | 
				
			||||||
		name := e.Name
 | 
					 | 
				
			||||||
		if eh[name] {
 | 
					 | 
				
			||||||
			return fmt.Errorf("Only one eventHandler of name %q allowed", name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		eh[name] = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := a.Environment.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := a.Isolators.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										60
									
								
								vendor/github.com/appc/spec/schema/types/date.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/appc/spec/schema/types/date.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,60 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Date wraps time.Time to marshal/unmarshal to/from JSON strings in strict
 | 
					 | 
				
			||||||
// accordance with RFC3339
 | 
					 | 
				
			||||||
// TODO(jonboulle): golang's implementation seems slightly buggy here;
 | 
					 | 
				
			||||||
// according to http://tools.ietf.org/html/rfc3339#section-5.6 , applications
 | 
					 | 
				
			||||||
// may choose to separate the date and time with a space instead of a T
 | 
					 | 
				
			||||||
// character (for example, `date --rfc-3339` on GNU coreutils) - but this is
 | 
					 | 
				
			||||||
// considered an error by go's parser. File a bug?
 | 
					 | 
				
			||||||
type Date time.Time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewDate(s string) (*Date, error) {
 | 
					 | 
				
			||||||
	t, err := time.Parse(time.RFC3339, s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("bad Date: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	d := Date(t)
 | 
					 | 
				
			||||||
	return &d, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d Date) String() string {
 | 
					 | 
				
			||||||
	return time.Time(d).Format(time.RFC3339)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d *Date) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nd, err := NewDate(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*d = *nd
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d Date) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	return json.Marshal(d.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										58
									
								
								vendor/github.com/appc/spec/schema/types/dependencies.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/appc/spec/schema/types/dependencies.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,58 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Dependencies []Dependency
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Dependency struct {
 | 
					 | 
				
			||||||
	ImageName ACIdentifier `json:"imageName"`
 | 
					 | 
				
			||||||
	ImageID   *Hash        `json:"imageID,omitempty"`
 | 
					 | 
				
			||||||
	Labels    Labels       `json:"labels,omitempty"`
 | 
					 | 
				
			||||||
	Size      uint         `json:"size,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type dependency Dependency
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d Dependency) assertValid() error {
 | 
					 | 
				
			||||||
	if len(d.ImageName) < 1 {
 | 
					 | 
				
			||||||
		return errors.New(`imageName cannot be empty`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d Dependency) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := d.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(dependency(d))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d *Dependency) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var jd dependency
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &jd); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nd := Dependency(jd)
 | 
					 | 
				
			||||||
	if err := nd.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*d = nd
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,18 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types contains structs representing the various types in the app
 | 
					 | 
				
			||||||
// container specification. It is used by the [schema manifest types](../)
 | 
					 | 
				
			||||||
// to enforce validation.
 | 
					 | 
				
			||||||
package types
 | 
					 | 
				
			||||||
							
								
								
									
										110
									
								
								vendor/github.com/appc/spec/schema/types/environment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/appc/spec/schema/types/environment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,110 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	envPattern = regexp.MustCompile("^[A-Za-z_][A-Za-z_0-9]*$")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Environment []EnvironmentVariable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type environment Environment
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type EnvironmentVariable struct {
 | 
					 | 
				
			||||||
	Name  string `json:"name"`
 | 
					 | 
				
			||||||
	Value string `json:"value"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ev EnvironmentVariable) assertValid() error {
 | 
					 | 
				
			||||||
	if len(ev.Name) == 0 {
 | 
					 | 
				
			||||||
		return fmt.Errorf(`environment variable name must not be empty`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !envPattern.MatchString(ev.Name) {
 | 
					 | 
				
			||||||
		return fmt.Errorf(`environment variable does not have valid identifier %q`, ev.Name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e Environment) assertValid() error {
 | 
					 | 
				
			||||||
	seen := map[string]bool{}
 | 
					 | 
				
			||||||
	for _, env := range e {
 | 
					 | 
				
			||||||
		if err := env.assertValid(); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, ok := seen[env.Name]
 | 
					 | 
				
			||||||
		if ok {
 | 
					 | 
				
			||||||
			return fmt.Errorf(`duplicate environment variable of name %q`, env.Name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		seen[env.Name] = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e Environment) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := e.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(environment(e))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *Environment) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var je environment
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &je); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ne := Environment(je)
 | 
					 | 
				
			||||||
	if err := ne.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*e = ne
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Retrieve the value of an environment variable by the given name from
 | 
					 | 
				
			||||||
// Environment, if it exists.
 | 
					 | 
				
			||||||
func (e Environment) Get(name string) (value string, ok bool) {
 | 
					 | 
				
			||||||
	for _, env := range e {
 | 
					 | 
				
			||||||
		if env.Name == name {
 | 
					 | 
				
			||||||
			return env.Value, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "", false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set sets the value of an environment variable by the given name,
 | 
					 | 
				
			||||||
// overwriting if one already exists.
 | 
					 | 
				
			||||||
func (e *Environment) Set(name string, value string) {
 | 
					 | 
				
			||||||
	for i, env := range *e {
 | 
					 | 
				
			||||||
		if env.Name == name {
 | 
					 | 
				
			||||||
			(*e)[i] = EnvironmentVariable{
 | 
					 | 
				
			||||||
				Name:  name,
 | 
					 | 
				
			||||||
				Value: value,
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	env := EnvironmentVariable{
 | 
					 | 
				
			||||||
		Name:  name,
 | 
					 | 
				
			||||||
		Value: value,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*e = append(*e, env)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										49
									
								
								vendor/github.com/appc/spec/schema/types/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/github.com/appc/spec/schema/types/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,49 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// An ACKindError is returned when the wrong ACKind is set in a manifest
 | 
					 | 
				
			||||||
type ACKindError string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e ACKindError) Error() string {
 | 
					 | 
				
			||||||
	return string(e)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func InvalidACKindError(kind ACKind) ACKindError {
 | 
					 | 
				
			||||||
	return ACKindError(fmt.Sprintf("missing or bad ACKind (must be %#v)", kind))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// An ACVersionError is returned when a bad ACVersion is set in a manifest
 | 
					 | 
				
			||||||
type ACVersionError string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e ACVersionError) Error() string {
 | 
					 | 
				
			||||||
	return string(e)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// An ACIdentifierError is returned when a bad value is used for an ACIdentifier
 | 
					 | 
				
			||||||
type ACIdentifierError string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e ACIdentifierError) Error() string {
 | 
					 | 
				
			||||||
	return string(e)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// An ACNameError is returned when a bad value is used for an ACName
 | 
					 | 
				
			||||||
type ACNameError string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e ACNameError) Error() string {
 | 
					 | 
				
			||||||
	return string(e)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										61
									
								
								vendor/github.com/appc/spec/schema/types/event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/appc/spec/schema/types/event_handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,61 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type EventHandler struct {
 | 
					 | 
				
			||||||
	Name string `json:"name"`
 | 
					 | 
				
			||||||
	Exec Exec   `json:"exec"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type eventHandler EventHandler
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e EventHandler) assertValid() error {
 | 
					 | 
				
			||||||
	s := e.Name
 | 
					 | 
				
			||||||
	switch s {
 | 
					 | 
				
			||||||
	case "pre-start", "post-stop":
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case "":
 | 
					 | 
				
			||||||
		return errors.New(`eventHandler "name" cannot be empty`)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return fmt.Errorf(`bad eventHandler "name": %q`, s)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e EventHandler) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := e.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(eventHandler(e))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *EventHandler) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var je eventHandler
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &je)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ne := EventHandler(je)
 | 
					 | 
				
			||||||
	if err := ne.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*e = ne
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										46
									
								
								vendor/github.com/appc/spec/schema/types/exec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/appc/spec/schema/types/exec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,46 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "encoding/json"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Exec []string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type exec Exec
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e Exec) assertValid() error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e Exec) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := e.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(exec(e))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e *Exec) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var je exec
 | 
					 | 
				
			||||||
	err := json.Unmarshal(data, &je)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ne := Exec(je)
 | 
					 | 
				
			||||||
	if err := ne.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*e = ne
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										118
									
								
								vendor/github.com/appc/spec/schema/types/hash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										118
									
								
								vendor/github.com/appc/spec/schema/types/hash.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,118 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/sha512"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"reflect"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	maxHashSize = (sha512.Size / 2) + len("sha512-")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Hash encodes a hash specified in a string of the form:
 | 
					 | 
				
			||||||
//    "<type>-<value>"
 | 
					 | 
				
			||||||
// for example
 | 
					 | 
				
			||||||
//    "sha512-06c733b1838136838e6d2d3e8fa5aea4c7905e92[...]"
 | 
					 | 
				
			||||||
// Valid types are currently:
 | 
					 | 
				
			||||||
//  * sha512
 | 
					 | 
				
			||||||
type Hash struct {
 | 
					 | 
				
			||||||
	typ string
 | 
					 | 
				
			||||||
	Val string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewHash(s string) (*Hash, error) {
 | 
					 | 
				
			||||||
	elems := strings.Split(s, "-")
 | 
					 | 
				
			||||||
	if len(elems) != 2 {
 | 
					 | 
				
			||||||
		return nil, errors.New("badly formatted hash string")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nh := Hash{
 | 
					 | 
				
			||||||
		typ: elems[0],
 | 
					 | 
				
			||||||
		Val: elems[1],
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := nh.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &nh, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h Hash) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%s-%s", h.typ, h.Val)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *Hash) Set(s string) error {
 | 
					 | 
				
			||||||
	nh, err := NewHash(s)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		*h = *nh
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h Hash) Empty() bool {
 | 
					 | 
				
			||||||
	return reflect.DeepEqual(h, Hash{})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h Hash) assertValid() error {
 | 
					 | 
				
			||||||
	switch h.typ {
 | 
					 | 
				
			||||||
	case "sha512":
 | 
					 | 
				
			||||||
	case "":
 | 
					 | 
				
			||||||
		return fmt.Errorf("unexpected empty hash type")
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return fmt.Errorf("unrecognized hash type: %v", h.typ)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if h.Val == "" {
 | 
					 | 
				
			||||||
		return fmt.Errorf("unexpected empty hash value")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *Hash) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nh, err := NewHash(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*h = *nh
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h Hash) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := h.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(h.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewHashSHA512(b []byte) *Hash {
 | 
					 | 
				
			||||||
	h := sha512.New()
 | 
					 | 
				
			||||||
	h.Write(b)
 | 
					 | 
				
			||||||
	nh, _ := NewHash(fmt.Sprintf("sha512-%x", h.Sum(nil)))
 | 
					 | 
				
			||||||
	return nh
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ShortHash(hash string) string {
 | 
					 | 
				
			||||||
	if len(hash) > maxHashSize {
 | 
					 | 
				
			||||||
		return hash[:maxHashSize]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return hash
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										190
									
								
								vendor/github.com/appc/spec/schema/types/isolator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										190
									
								
								vendor/github.com/appc/spec/schema/types/isolator.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,190 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	isolatorMap map[ACIdentifier]IsolatorValueConstructor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// ErrIncompatibleIsolator is returned whenever an Isolators set contains
 | 
					 | 
				
			||||||
	// conflicting IsolatorValue instances
 | 
					 | 
				
			||||||
	ErrIncompatibleIsolator = errors.New("isolators set contains incompatible types")
 | 
					 | 
				
			||||||
	// ErrInvalidIsolator is returned upon validation failures due to improper
 | 
					 | 
				
			||||||
	// or partially constructed Isolator instances (eg. from incomplete direct construction)
 | 
					 | 
				
			||||||
	ErrInvalidIsolator = errors.New("invalid isolator")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	isolatorMap = make(map[ACIdentifier]IsolatorValueConstructor)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type IsolatorValueConstructor func() IsolatorValue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func AddIsolatorValueConstructor(n ACIdentifier, i IsolatorValueConstructor) {
 | 
					 | 
				
			||||||
	isolatorMap[n] = i
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func AddIsolatorName(n ACIdentifier, ns map[ACIdentifier]struct{}) {
 | 
					 | 
				
			||||||
	ns[n] = struct{}{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Isolators encapsulates a list of individual Isolators for the ImageManifest
 | 
					 | 
				
			||||||
// and PodManifest schemas.
 | 
					 | 
				
			||||||
type Isolators []Isolator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// assertValid checks that every single isolator is valid and that
 | 
					 | 
				
			||||||
// the whole set is well built
 | 
					 | 
				
			||||||
func (isolators Isolators) assertValid() error {
 | 
					 | 
				
			||||||
	typesMap := make(map[ACIdentifier]bool)
 | 
					 | 
				
			||||||
	for _, i := range isolators {
 | 
					 | 
				
			||||||
		v := i.Value()
 | 
					 | 
				
			||||||
		if v == nil {
 | 
					 | 
				
			||||||
			return ErrInvalidIsolator
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err := v.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if _, ok := typesMap[i.Name]; ok {
 | 
					 | 
				
			||||||
			if !v.multipleAllowed() {
 | 
					 | 
				
			||||||
				return fmt.Errorf(`isolators set contains too many instances of type %s"`, i.Name)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		for _, c := range v.Conflicts() {
 | 
					 | 
				
			||||||
			if _, found := typesMap[c]; found {
 | 
					 | 
				
			||||||
				return ErrIncompatibleIsolator
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		typesMap[i.Name] = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetByName returns the last isolator in the list by the given name.
 | 
					 | 
				
			||||||
func (is *Isolators) GetByName(name ACIdentifier) *Isolator {
 | 
					 | 
				
			||||||
	var i Isolator
 | 
					 | 
				
			||||||
	for j := len(*is) - 1; j >= 0; j-- {
 | 
					 | 
				
			||||||
		i = []Isolator(*is)[j]
 | 
					 | 
				
			||||||
		if i.Name == name {
 | 
					 | 
				
			||||||
			return &i
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReplaceIsolatorsByName overrides matching isolator types with a new
 | 
					 | 
				
			||||||
// isolator, deleting them all and appending the new one instead
 | 
					 | 
				
			||||||
func (is *Isolators) ReplaceIsolatorsByName(newIs Isolator, oldNames []ACIdentifier) {
 | 
					 | 
				
			||||||
	var i Isolator
 | 
					 | 
				
			||||||
	for j := len(*is) - 1; j >= 0; j-- {
 | 
					 | 
				
			||||||
		i = []Isolator(*is)[j]
 | 
					 | 
				
			||||||
		for _, name := range oldNames {
 | 
					 | 
				
			||||||
			if i.Name == name {
 | 
					 | 
				
			||||||
				*is = append((*is)[:j], (*is)[j+1:]...)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*is = append((*is)[:], newIs)
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Unrecognized returns a set of isolators that are not recognized.
 | 
					 | 
				
			||||||
// An isolator is not recognized if it has not had an associated
 | 
					 | 
				
			||||||
// constructor registered with AddIsolatorValueConstructor.
 | 
					 | 
				
			||||||
func (is *Isolators) Unrecognized() Isolators {
 | 
					 | 
				
			||||||
	u := Isolators{}
 | 
					 | 
				
			||||||
	for _, i := range *is {
 | 
					 | 
				
			||||||
		if i.value == nil {
 | 
					 | 
				
			||||||
			u = append(u, i)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return u
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IsolatorValue encapsulates the actual value of an Isolator which may be
 | 
					 | 
				
			||||||
// serialized as any arbitrary JSON blob. Specific Isolator types should
 | 
					 | 
				
			||||||
// implement this interface to facilitate unmarshalling and validation.
 | 
					 | 
				
			||||||
type IsolatorValue interface {
 | 
					 | 
				
			||||||
	// UnmarshalJSON unserialize a JSON-encoded isolator
 | 
					 | 
				
			||||||
	UnmarshalJSON(b []byte) error
 | 
					 | 
				
			||||||
	// AssertValid returns a non-nil error value if an IsolatorValue is not valid
 | 
					 | 
				
			||||||
	// according to appc spec
 | 
					 | 
				
			||||||
	AssertValid() error
 | 
					 | 
				
			||||||
	// Conflicts returns a list of conflicting isolators types, which cannot co-exist
 | 
					 | 
				
			||||||
	// together with this IsolatorValue
 | 
					 | 
				
			||||||
	Conflicts() []ACIdentifier
 | 
					 | 
				
			||||||
	// multipleAllowed specifies whether multiple isolator instances are allowed
 | 
					 | 
				
			||||||
	// for this isolator type
 | 
					 | 
				
			||||||
	multipleAllowed() bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Isolator is a model for unmarshalling isolator types from their JSON-encoded
 | 
					 | 
				
			||||||
// representation.
 | 
					 | 
				
			||||||
type Isolator struct {
 | 
					 | 
				
			||||||
	// Name is the name of the Isolator type as defined in the specification.
 | 
					 | 
				
			||||||
	Name ACIdentifier `json:"name"`
 | 
					 | 
				
			||||||
	// ValueRaw captures the raw JSON value of an Isolator that was
 | 
					 | 
				
			||||||
	// unmarshalled. This field is used for unmarshalling only. It MUST NOT
 | 
					 | 
				
			||||||
	// be referenced by external users of the Isolator struct. It is
 | 
					 | 
				
			||||||
	// exported only to satisfy Go's unfortunate requirement that fields
 | 
					 | 
				
			||||||
	// must be capitalized to be unmarshalled successfully.
 | 
					 | 
				
			||||||
	ValueRaw *json.RawMessage `json:"value"`
 | 
					 | 
				
			||||||
	// value captures the "true" value of the isolator.
 | 
					 | 
				
			||||||
	value IsolatorValue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// isolator is a shadow type used for unmarshalling.
 | 
					 | 
				
			||||||
type isolator Isolator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Value returns the raw Value of this Isolator. Users should perform a type
 | 
					 | 
				
			||||||
// switch/assertion on this value to extract the underlying isolator type.
 | 
					 | 
				
			||||||
func (i *Isolator) Value() IsolatorValue {
 | 
					 | 
				
			||||||
	return i.value
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON populates this Isolator from a JSON-encoded representation. To
 | 
					 | 
				
			||||||
// unmarshal the Value of the Isolator, it will use the appropriate constructor
 | 
					 | 
				
			||||||
// as registered by AddIsolatorValueConstructor.
 | 
					 | 
				
			||||||
func (i *Isolator) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var ii isolator
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &ii)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var dst IsolatorValue
 | 
					 | 
				
			||||||
	con, ok := isolatorMap[ii.Name]
 | 
					 | 
				
			||||||
	if ok {
 | 
					 | 
				
			||||||
		dst = con()
 | 
					 | 
				
			||||||
		err = dst.UnmarshalJSON(*ii.ValueRaw)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		err = dst.AssertValid()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i.value = dst
 | 
					 | 
				
			||||||
	i.ValueRaw = ii.ValueRaw
 | 
					 | 
				
			||||||
	i.Name = ii.Name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										529
									
								
								vendor/github.com/appc/spec/schema/types/isolator_linux_specific.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										529
									
								
								vendor/github.com/appc/spec/schema/types/isolator_linux_specific.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,529 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"unicode"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	LinuxCapabilitiesRetainSetName = "os/linux/capabilities-retain-set"
 | 
					 | 
				
			||||||
	LinuxCapabilitiesRevokeSetName = "os/linux/capabilities-remove-set"
 | 
					 | 
				
			||||||
	LinuxNoNewPrivilegesName       = "os/linux/no-new-privileges"
 | 
					 | 
				
			||||||
	LinuxSeccompRemoveSetName      = "os/linux/seccomp-remove-set"
 | 
					 | 
				
			||||||
	LinuxSeccompRetainSetName      = "os/linux/seccomp-retain-set"
 | 
					 | 
				
			||||||
	LinuxOOMScoreAdjName           = "os/linux/oom-score-adj"
 | 
					 | 
				
			||||||
	LinuxCPUSharesName             = "os/linux/cpu-shares"
 | 
					 | 
				
			||||||
	LinuxSELinuxContextName        = "os/linux/selinux-context"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var LinuxIsolatorNames = make(map[ACIdentifier]struct{})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	for name, con := range map[ACIdentifier]IsolatorValueConstructor{
 | 
					 | 
				
			||||||
		LinuxCapabilitiesRevokeSetName: func() IsolatorValue { return &LinuxCapabilitiesRevokeSet{} },
 | 
					 | 
				
			||||||
		LinuxCapabilitiesRetainSetName: func() IsolatorValue { return &LinuxCapabilitiesRetainSet{} },
 | 
					 | 
				
			||||||
		LinuxNoNewPrivilegesName:       func() IsolatorValue { v := LinuxNoNewPrivileges(false); return &v },
 | 
					 | 
				
			||||||
		LinuxOOMScoreAdjName:           func() IsolatorValue { v := LinuxOOMScoreAdj(0); return &v },
 | 
					 | 
				
			||||||
		LinuxCPUSharesName:             func() IsolatorValue { v := LinuxCPUShares(1024); return &v },
 | 
					 | 
				
			||||||
		LinuxSeccompRemoveSetName:      func() IsolatorValue { return &LinuxSeccompRemoveSet{} },
 | 
					 | 
				
			||||||
		LinuxSeccompRetainSetName:      func() IsolatorValue { return &LinuxSeccompRetainSet{} },
 | 
					 | 
				
			||||||
		LinuxSELinuxContextName:        func() IsolatorValue { return &LinuxSELinuxContext{} },
 | 
					 | 
				
			||||||
	} {
 | 
					 | 
				
			||||||
		AddIsolatorName(name, LinuxIsolatorNames)
 | 
					 | 
				
			||||||
		AddIsolatorValueConstructor(name, con)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxNoNewPrivileges bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxNoNewPrivileges) AssertValid() error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(lucab): both need to be clarified in spec,
 | 
					 | 
				
			||||||
// see https://github.com/appc/spec/issues/625
 | 
					 | 
				
			||||||
func (l LinuxNoNewPrivileges) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (l LinuxNoNewPrivileges) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *LinuxNoNewPrivileges) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v bool
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*l = LinuxNoNewPrivileges(v)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type AsIsolator interface {
 | 
					 | 
				
			||||||
	AsIsolator() (*Isolator, error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxCapabilitiesSet interface {
 | 
					 | 
				
			||||||
	Set() []LinuxCapability
 | 
					 | 
				
			||||||
	AssertValid() error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxCapability string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type linuxCapabilitiesSetValue struct {
 | 
					 | 
				
			||||||
	Set []LinuxCapability `json:"set"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type linuxCapabilitiesSetBase struct {
 | 
					 | 
				
			||||||
	val linuxCapabilitiesSetValue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxCapabilitiesSetBase) AssertValid() error {
 | 
					 | 
				
			||||||
	if len(l.val.Set) == 0 {
 | 
					 | 
				
			||||||
		return errors.New("set must be non-empty")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(lucab): both need to be clarified in spec,
 | 
					 | 
				
			||||||
// see https://github.com/appc/spec/issues/625
 | 
					 | 
				
			||||||
func (l linuxCapabilitiesSetBase) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (l linuxCapabilitiesSetBase) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *linuxCapabilitiesSetBase) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v linuxCapabilitiesSetValue
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	l.val = v
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxCapabilitiesSetBase) Set() []LinuxCapability {
 | 
					 | 
				
			||||||
	return l.val.Set
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxCapabilitiesRetainSet struct {
 | 
					 | 
				
			||||||
	linuxCapabilitiesSetBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxCapabilitiesRetainSet(caps ...string) (*LinuxCapabilitiesRetainSet, error) {
 | 
					 | 
				
			||||||
	l := LinuxCapabilitiesRetainSet{
 | 
					 | 
				
			||||||
		linuxCapabilitiesSetBase{
 | 
					 | 
				
			||||||
			linuxCapabilitiesSetValue{
 | 
					 | 
				
			||||||
				make([]LinuxCapability, len(caps)),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i, c := range caps {
 | 
					 | 
				
			||||||
		l.linuxCapabilitiesSetBase.val.Set[i] = LinuxCapability(c)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCapabilitiesRetainSet) AsIsolator() (*Isolator, error) {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l.linuxCapabilitiesSetBase.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return &Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxCapabilitiesRetainSetName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxCapabilitiesRevokeSet struct {
 | 
					 | 
				
			||||||
	linuxCapabilitiesSetBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxCapabilitiesRevokeSet(caps ...string) (*LinuxCapabilitiesRevokeSet, error) {
 | 
					 | 
				
			||||||
	l := LinuxCapabilitiesRevokeSet{
 | 
					 | 
				
			||||||
		linuxCapabilitiesSetBase{
 | 
					 | 
				
			||||||
			linuxCapabilitiesSetValue{
 | 
					 | 
				
			||||||
				make([]LinuxCapability, len(caps)),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i, c := range caps {
 | 
					 | 
				
			||||||
		l.linuxCapabilitiesSetBase.val.Set[i] = LinuxCapability(c)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCapabilitiesRevokeSet) AsIsolator() (*Isolator, error) {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l.linuxCapabilitiesSetBase.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return &Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxCapabilitiesRevokeSetName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSeccompSet interface {
 | 
					 | 
				
			||||||
	Set() []LinuxSeccompEntry
 | 
					 | 
				
			||||||
	Errno() LinuxSeccompErrno
 | 
					 | 
				
			||||||
	AssertValid() error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSeccompEntry string
 | 
					 | 
				
			||||||
type LinuxSeccompErrno string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type linuxSeccompValue struct {
 | 
					 | 
				
			||||||
	Set   []LinuxSeccompEntry `json:"set"`
 | 
					 | 
				
			||||||
	Errno LinuxSeccompErrno   `json:"errno"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type linuxSeccompBase struct {
 | 
					 | 
				
			||||||
	val linuxSeccompValue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxSeccompBase) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxSeccompBase) AssertValid() error {
 | 
					 | 
				
			||||||
	if len(l.val.Set) == 0 {
 | 
					 | 
				
			||||||
		return errors.New("set must be non-empty")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if l.val.Errno == "" {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, c := range l.val.Errno {
 | 
					 | 
				
			||||||
		if !unicode.IsUpper(c) {
 | 
					 | 
				
			||||||
			return errors.New("errno must be an upper case string")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *linuxSeccompBase) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v linuxSeccompValue
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	l.val = v
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxSeccompBase) Set() []LinuxSeccompEntry {
 | 
					 | 
				
			||||||
	return l.val.Set
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l linuxSeccompBase) Errno() LinuxSeccompErrno {
 | 
					 | 
				
			||||||
	return l.val.Errno
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSeccompRetainSet struct {
 | 
					 | 
				
			||||||
	linuxSeccompBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSeccompRetainSet) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return []ACIdentifier{LinuxSeccompRemoveSetName}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxSeccompRetainSet(errno string, syscall ...string) (*LinuxSeccompRetainSet, error) {
 | 
					 | 
				
			||||||
	l := LinuxSeccompRetainSet{
 | 
					 | 
				
			||||||
		linuxSeccompBase{
 | 
					 | 
				
			||||||
			linuxSeccompValue{
 | 
					 | 
				
			||||||
				make([]LinuxSeccompEntry, len(syscall)),
 | 
					 | 
				
			||||||
				LinuxSeccompErrno(errno),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i, c := range syscall {
 | 
					 | 
				
			||||||
		l.linuxSeccompBase.val.Set[i] = LinuxSeccompEntry(c)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSeccompRetainSet) AsIsolator() (*Isolator, error) {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l.linuxSeccompBase.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return &Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxSeccompRetainSetName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSeccompRemoveSet struct {
 | 
					 | 
				
			||||||
	linuxSeccompBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSeccompRemoveSet) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return []ACIdentifier{LinuxSeccompRetainSetName}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxSeccompRemoveSet(errno string, syscall ...string) (*LinuxSeccompRemoveSet, error) {
 | 
					 | 
				
			||||||
	l := LinuxSeccompRemoveSet{
 | 
					 | 
				
			||||||
		linuxSeccompBase{
 | 
					 | 
				
			||||||
			linuxSeccompValue{
 | 
					 | 
				
			||||||
				make([]LinuxSeccompEntry, len(syscall)),
 | 
					 | 
				
			||||||
				LinuxSeccompErrno(errno),
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i, c := range syscall {
 | 
					 | 
				
			||||||
		l.linuxSeccompBase.val.Set[i] = LinuxSeccompEntry(c)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSeccompRemoveSet) AsIsolator() (*Isolator, error) {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l.linuxSeccompBase.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return &Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxSeccompRemoveSetName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LinuxCPUShares assigns the CPU time share weight to the processes executed.
 | 
					 | 
				
			||||||
// See https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#CPUShares=weight,
 | 
					 | 
				
			||||||
// https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt
 | 
					 | 
				
			||||||
type LinuxCPUShares int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxCPUShares(val int) (*LinuxCPUShares, error) {
 | 
					 | 
				
			||||||
	l := LinuxCPUShares(val)
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCPUShares) AssertValid() error {
 | 
					 | 
				
			||||||
	if l < 2 || l > 262144 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("%s must be between 2 and 262144, got %d", LinuxCPUSharesName, l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCPUShares) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCPUShares) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *LinuxCPUShares) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v int
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*l = LinuxCPUShares(v)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxCPUShares) AsIsolator() Isolator {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxCPUSharesName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LinuxOOMScoreAdj is equivalent to /proc/[pid]/oom_score_adj
 | 
					 | 
				
			||||||
type LinuxOOMScoreAdj int // -1000 to 1000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxOOMScoreAdj(val int) (*LinuxOOMScoreAdj, error) {
 | 
					 | 
				
			||||||
	l := LinuxOOMScoreAdj(val)
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxOOMScoreAdj) AssertValid() error {
 | 
					 | 
				
			||||||
	if l < -1000 || l > 1000 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("%s must be between -1000 and 1000, got %d", LinuxOOMScoreAdjName, l)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxOOMScoreAdj) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxOOMScoreAdj) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *LinuxOOMScoreAdj) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v int
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*l = LinuxOOMScoreAdj(v)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxOOMScoreAdj) AsIsolator() Isolator {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxOOMScoreAdjName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSELinuxUser string
 | 
					 | 
				
			||||||
type LinuxSELinuxRole string
 | 
					 | 
				
			||||||
type LinuxSELinuxType string
 | 
					 | 
				
			||||||
type LinuxSELinuxLevel string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type linuxSELinuxValue struct {
 | 
					 | 
				
			||||||
	User  LinuxSELinuxUser  `json:"user"`
 | 
					 | 
				
			||||||
	Role  LinuxSELinuxRole  `json:"role"`
 | 
					 | 
				
			||||||
	Type  LinuxSELinuxType  `json:"type"`
 | 
					 | 
				
			||||||
	Level LinuxSELinuxLevel `json:"level"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LinuxSELinuxContext struct {
 | 
					 | 
				
			||||||
	val linuxSELinuxValue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) AssertValid() error {
 | 
					 | 
				
			||||||
	if l.val.User == "" || strings.Contains(string(l.val.User), ":") {
 | 
					 | 
				
			||||||
		return fmt.Errorf("invalid user value %q", l.val.User)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if l.val.Role == "" || strings.Contains(string(l.val.Role), ":") {
 | 
					 | 
				
			||||||
		return fmt.Errorf("invalid role value %q", l.val.Role)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if l.val.Type == "" || strings.Contains(string(l.val.Type), ":") {
 | 
					 | 
				
			||||||
		return fmt.Errorf("invalid type value %q", l.val.Type)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if l.val.Level == "" {
 | 
					 | 
				
			||||||
		return fmt.Errorf("invalid level value %q", l.val.Level)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *LinuxSELinuxContext) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v linuxSELinuxValue
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	l.val = v
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) User() LinuxSELinuxUser {
 | 
					 | 
				
			||||||
	return l.val.User
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) Role() LinuxSELinuxRole {
 | 
					 | 
				
			||||||
	return l.val.Role
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) Type() LinuxSELinuxType {
 | 
					 | 
				
			||||||
	return l.val.Type
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) Level() LinuxSELinuxLevel {
 | 
					 | 
				
			||||||
	return l.val.Level
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewLinuxSELinuxContext(selinuxUser, selinuxRole, selinuxType, selinuxLevel string) (*LinuxSELinuxContext, error) {
 | 
					 | 
				
			||||||
	l := LinuxSELinuxContext{
 | 
					 | 
				
			||||||
		linuxSELinuxValue{
 | 
					 | 
				
			||||||
			LinuxSELinuxUser(selinuxUser),
 | 
					 | 
				
			||||||
			LinuxSELinuxRole(selinuxRole),
 | 
					 | 
				
			||||||
			LinuxSELinuxType(selinuxType),
 | 
					 | 
				
			||||||
			LinuxSELinuxLevel(selinuxLevel),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := l.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &l, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l LinuxSELinuxContext) AsIsolator() (*Isolator, error) {
 | 
					 | 
				
			||||||
	b, err := json.Marshal(l.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	rm := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return &Isolator{
 | 
					 | 
				
			||||||
		Name:     LinuxSELinuxContextName,
 | 
					 | 
				
			||||||
		ValueRaw: &rm,
 | 
					 | 
				
			||||||
		value:    &l,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										245
									
								
								vendor/github.com/appc/spec/schema/types/isolator_resources.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										245
									
								
								vendor/github.com/appc/spec/schema/types/isolator_resources.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,245 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/types/resource"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrDefaultTrue     = errors.New("default must be false")
 | 
					 | 
				
			||||||
	ErrDefaultRequired = errors.New("default must be true")
 | 
					 | 
				
			||||||
	ErrRequestNonEmpty = errors.New("request not supported by this resource, must be empty")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ResourceIsolatorNames = make(map[ACIdentifier]struct{})
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ResourceBlockBandwidthName   = "resource/block-bandwidth"
 | 
					 | 
				
			||||||
	ResourceBlockIOPSName        = "resource/block-iops"
 | 
					 | 
				
			||||||
	ResourceCPUName              = "resource/cpu"
 | 
					 | 
				
			||||||
	ResourceMemoryName           = "resource/memory"
 | 
					 | 
				
			||||||
	ResourceNetworkBandwidthName = "resource/network-bandwidth"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	for name, con := range map[ACIdentifier]IsolatorValueConstructor{
 | 
					 | 
				
			||||||
		ResourceBlockBandwidthName:   func() IsolatorValue { return &ResourceBlockBandwidth{} },
 | 
					 | 
				
			||||||
		ResourceBlockIOPSName:        func() IsolatorValue { return &ResourceBlockIOPS{} },
 | 
					 | 
				
			||||||
		ResourceCPUName:              func() IsolatorValue { return &ResourceCPU{} },
 | 
					 | 
				
			||||||
		ResourceMemoryName:           func() IsolatorValue { return &ResourceMemory{} },
 | 
					 | 
				
			||||||
		ResourceNetworkBandwidthName: func() IsolatorValue { return &ResourceNetworkBandwidth{} },
 | 
					 | 
				
			||||||
	} {
 | 
					 | 
				
			||||||
		AddIsolatorName(name, ResourceIsolatorNames)
 | 
					 | 
				
			||||||
		AddIsolatorValueConstructor(name, con)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Resource interface {
 | 
					 | 
				
			||||||
	Limit() *resource.Quantity
 | 
					 | 
				
			||||||
	Request() *resource.Quantity
 | 
					 | 
				
			||||||
	Default() bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceBase struct {
 | 
					 | 
				
			||||||
	val resourceValue
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type resourceValue struct {
 | 
					 | 
				
			||||||
	Default bool               `json:"default"`
 | 
					 | 
				
			||||||
	Request *resource.Quantity `json:"request"`
 | 
					 | 
				
			||||||
	Limit   *resource.Quantity `json:"limit"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceBase) Limit() *resource.Quantity {
 | 
					 | 
				
			||||||
	return r.val.Limit
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (r ResourceBase) Request() *resource.Quantity {
 | 
					 | 
				
			||||||
	return r.val.Request
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (r ResourceBase) Default() bool {
 | 
					 | 
				
			||||||
	return r.val.Default
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r *ResourceBase) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	return json.Unmarshal(b, &r.val)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceBase) AssertValid() error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TODO(lucab): both need to be clarified in spec,
 | 
					 | 
				
			||||||
// see https://github.com/appc/spec/issues/625
 | 
					 | 
				
			||||||
func (l ResourceBase) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (l ResourceBase) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceBlockBandwidth struct {
 | 
					 | 
				
			||||||
	ResourceBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceBlockBandwidth) AssertValid() error {
 | 
					 | 
				
			||||||
	if r.Default() != true {
 | 
					 | 
				
			||||||
		return ErrDefaultRequired
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Request() != nil {
 | 
					 | 
				
			||||||
		return ErrRequestNonEmpty
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceBlockIOPS struct {
 | 
					 | 
				
			||||||
	ResourceBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceBlockIOPS) AssertValid() error {
 | 
					 | 
				
			||||||
	if r.Default() != true {
 | 
					 | 
				
			||||||
		return ErrDefaultRequired
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Request() != nil {
 | 
					 | 
				
			||||||
		return ErrRequestNonEmpty
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceCPU struct {
 | 
					 | 
				
			||||||
	ResourceBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceCPU) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("ResourceCPU(request=%s, limit=%s)", r.Request(), r.Limit())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceCPU) AssertValid() error {
 | 
					 | 
				
			||||||
	if r.Default() != false {
 | 
					 | 
				
			||||||
		return ErrDefaultTrue
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceCPU) AsIsolator() Isolator {
 | 
					 | 
				
			||||||
	isol := isolatorMap[ResourceCPUName]()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	b, err := json.Marshal(r.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	valRaw := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return Isolator{
 | 
					 | 
				
			||||||
		Name:     ResourceCPUName,
 | 
					 | 
				
			||||||
		ValueRaw: &valRaw,
 | 
					 | 
				
			||||||
		value:    isol,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewResourceCPUIsolator(request, limit string) (*ResourceCPU, error) {
 | 
					 | 
				
			||||||
	req, err := resource.ParseQuantity(request)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("error parsing request: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	lim, err := resource.ParseQuantity(limit)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("error parsing limit: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res := &ResourceCPU{
 | 
					 | 
				
			||||||
		ResourceBase{
 | 
					 | 
				
			||||||
			resourceValue{
 | 
					 | 
				
			||||||
				Request: &req,
 | 
					 | 
				
			||||||
				Limit:   &lim,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := res.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		// should never happen
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return res, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceMemory struct {
 | 
					 | 
				
			||||||
	ResourceBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceMemory) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("ResourceMemory(request=%s, limit=%s)", r.Request(), r.Limit())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceMemory) AssertValid() error {
 | 
					 | 
				
			||||||
	if r.Default() != false {
 | 
					 | 
				
			||||||
		return ErrDefaultTrue
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceMemory) AsIsolator() Isolator {
 | 
					 | 
				
			||||||
	isol := isolatorMap[ResourceMemoryName]()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	b, err := json.Marshal(r.val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	valRaw := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return Isolator{
 | 
					 | 
				
			||||||
		Name:     ResourceMemoryName,
 | 
					 | 
				
			||||||
		ValueRaw: &valRaw,
 | 
					 | 
				
			||||||
		value:    isol,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewResourceMemoryIsolator(request, limit string) (*ResourceMemory, error) {
 | 
					 | 
				
			||||||
	req, err := resource.ParseQuantity(request)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("error parsing request: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	lim, err := resource.ParseQuantity(limit)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("error parsing limit: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res := &ResourceMemory{
 | 
					 | 
				
			||||||
		ResourceBase{
 | 
					 | 
				
			||||||
			resourceValue{
 | 
					 | 
				
			||||||
				Request: &req,
 | 
					 | 
				
			||||||
				Limit:   &lim,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := res.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		// should never happen
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return res, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type ResourceNetworkBandwidth struct {
 | 
					 | 
				
			||||||
	ResourceBase
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (r ResourceNetworkBandwidth) AssertValid() error {
 | 
					 | 
				
			||||||
	if r.Default() != true {
 | 
					 | 
				
			||||||
		return ErrDefaultRequired
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if r.Request() != nil {
 | 
					 | 
				
			||||||
		return ErrRequestNonEmpty
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										83
									
								
								vendor/github.com/appc/spec/schema/types/isolator_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										83
									
								
								vendor/github.com/appc/spec/schema/types/isolator_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,83 +0,0 @@
 | 
				
			|||||||
// Copyright 2016 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	UnixIsolatorNames = make(map[ACIdentifier]struct{})
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	//TODO(lucab): add "ulimit" isolators
 | 
					 | 
				
			||||||
	UnixSysctlName = "os/unix/sysctl"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	for name, con := range map[ACIdentifier]IsolatorValueConstructor{
 | 
					 | 
				
			||||||
		UnixSysctlName: func() IsolatorValue { return &UnixSysctl{} },
 | 
					 | 
				
			||||||
	} {
 | 
					 | 
				
			||||||
		AddIsolatorName(name, UnixIsolatorNames)
 | 
					 | 
				
			||||||
		AddIsolatorValueConstructor(name, con)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type UnixSysctl map[string]string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *UnixSysctl) UnmarshalJSON(b []byte) error {
 | 
					 | 
				
			||||||
	var v map[string]string
 | 
					 | 
				
			||||||
	err := json.Unmarshal(b, &v)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*s = UnixSysctl(v)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s UnixSysctl) AssertValid() error {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s UnixSysctl) multipleAllowed() bool {
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (s UnixSysctl) Conflicts() []ACIdentifier {
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s UnixSysctl) AsIsolator() Isolator {
 | 
					 | 
				
			||||||
	isol := isolatorMap[UnixSysctlName]()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	b, err := json.Marshal(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	valRaw := json.RawMessage(b)
 | 
					 | 
				
			||||||
	return Isolator{
 | 
					 | 
				
			||||||
		Name:     UnixSysctlName,
 | 
					 | 
				
			||||||
		ValueRaw: &valRaw,
 | 
					 | 
				
			||||||
		value:    isol,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewUnixSysctlIsolator(cfg map[string]string) (*UnixSysctl, error) {
 | 
					 | 
				
			||||||
	s := UnixSysctl(cfg)
 | 
					 | 
				
			||||||
	if err := s.AssertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &s, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										206
									
								
								vendor/github.com/appc/spec/schema/types/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										206
									
								
								vendor/github.com/appc/spec/schema/types/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,206 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var ValidOSArch = map[string][]string{
 | 
					 | 
				
			||||||
	"linux":   {"amd64", "i386", "aarch64", "aarch64_be", "armv6l", "armv7l", "armv7b", "ppc64", "ppc64le", "s390x"},
 | 
					 | 
				
			||||||
	"freebsd": {"amd64", "i386", "arm"},
 | 
					 | 
				
			||||||
	"darwin":  {"x86_64", "i386"},
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Labels []Label
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type labels Labels
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Label struct {
 | 
					 | 
				
			||||||
	Name  ACIdentifier `json:"name"`
 | 
					 | 
				
			||||||
	Value string       `json:"value"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// {appc,go}ArchTuple are internal helper types used to translate arch tuple between go and appc
 | 
					 | 
				
			||||||
type appcArchTuple struct {
 | 
					 | 
				
			||||||
	appcOs   string
 | 
					 | 
				
			||||||
	appcArch string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
type goArchTuple struct {
 | 
					 | 
				
			||||||
	goOs         string
 | 
					 | 
				
			||||||
	goArch       string
 | 
					 | 
				
			||||||
	goArchFlavor string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IsValidOsArch checks if a OS-architecture combination is valid given a map
 | 
					 | 
				
			||||||
// of valid OS-architectures
 | 
					 | 
				
			||||||
func IsValidOSArch(labels map[ACIdentifier]string, validOSArch map[string][]string) error {
 | 
					 | 
				
			||||||
	if os, ok := labels["os"]; ok {
 | 
					 | 
				
			||||||
		if validArchs, ok := validOSArch[os]; !ok {
 | 
					 | 
				
			||||||
			// Not a whitelisted OS. TODO: how to warn rather than fail?
 | 
					 | 
				
			||||||
			validOses := make([]string, 0, len(validOSArch))
 | 
					 | 
				
			||||||
			for validOs := range validOSArch {
 | 
					 | 
				
			||||||
				validOses = append(validOses, validOs)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			sort.Strings(validOses)
 | 
					 | 
				
			||||||
			return fmt.Errorf(`bad os %#v (must be one of: %v)`, os, validOses)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			// Whitelisted OS. We check arch here, as arch makes sense only
 | 
					 | 
				
			||||||
			// when os is defined.
 | 
					 | 
				
			||||||
			if arch, ok := labels["arch"]; ok {
 | 
					 | 
				
			||||||
				found := false
 | 
					 | 
				
			||||||
				for _, validArch := range validArchs {
 | 
					 | 
				
			||||||
					if arch == validArch {
 | 
					 | 
				
			||||||
						found = true
 | 
					 | 
				
			||||||
						break
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if !found {
 | 
					 | 
				
			||||||
					return fmt.Errorf(`bad arch %#v for %v (must be one of: %v)`, arch, os, validArchs)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l Labels) assertValid() error {
 | 
					 | 
				
			||||||
	seen := map[ACIdentifier]string{}
 | 
					 | 
				
			||||||
	for _, lbl := range l {
 | 
					 | 
				
			||||||
		if lbl.Name == "name" {
 | 
					 | 
				
			||||||
			return fmt.Errorf(`invalid label name: "name"`)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, ok := seen[lbl.Name]
 | 
					 | 
				
			||||||
		if ok {
 | 
					 | 
				
			||||||
			return fmt.Errorf(`duplicate labels of name %q`, lbl.Name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		seen[lbl.Name] = lbl.Value
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return IsValidOSArch(seen, ValidOSArch)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l Labels) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := l.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(labels(l))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *Labels) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var jl labels
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &jl); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nl := Labels(jl)
 | 
					 | 
				
			||||||
	if err := nl.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*l = nl
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get retrieves the value of the label by the given name from Labels, if it exists
 | 
					 | 
				
			||||||
func (l Labels) Get(name string) (val string, ok bool) {
 | 
					 | 
				
			||||||
	for _, lbl := range l {
 | 
					 | 
				
			||||||
		if lbl.Name.String() == name {
 | 
					 | 
				
			||||||
			return lbl.Value, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "", false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ToMap creates a map[ACIdentifier]string.
 | 
					 | 
				
			||||||
func (l Labels) ToMap() map[ACIdentifier]string {
 | 
					 | 
				
			||||||
	labelsMap := make(map[ACIdentifier]string)
 | 
					 | 
				
			||||||
	for _, lbl := range l {
 | 
					 | 
				
			||||||
		labelsMap[lbl.Name] = lbl.Value
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return labelsMap
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LabelsFromMap creates Labels from a map[ACIdentifier]string
 | 
					 | 
				
			||||||
func LabelsFromMap(labelsMap map[ACIdentifier]string) (Labels, error) {
 | 
					 | 
				
			||||||
	labels := Labels{}
 | 
					 | 
				
			||||||
	for n, v := range labelsMap {
 | 
					 | 
				
			||||||
		labels = append(labels, Label{Name: n, Value: v})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := labels.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return labels, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ToAppcOSArch translates a Golang arch tuple (OS, architecture, flavor) into
 | 
					 | 
				
			||||||
// an appc arch tuple (OS, architecture)
 | 
					 | 
				
			||||||
func ToAppcOSArch(goOs string, goArch string, goArchFlavor string) (appcOs string, appcArch string, e error) {
 | 
					 | 
				
			||||||
	tabularAppcToGo := map[goArchTuple]appcArchTuple{
 | 
					 | 
				
			||||||
		{"linux", "amd64", ""}:   {"linux", "amd64"},
 | 
					 | 
				
			||||||
		{"linux", "386", ""}:     {"linux", "i386"},
 | 
					 | 
				
			||||||
		{"linux", "arm64", ""}:   {"linux", "aarch64"},
 | 
					 | 
				
			||||||
		{"linux", "arm", ""}:     {"linux", "armv6l"},
 | 
					 | 
				
			||||||
		{"linux", "arm", "6"}:    {"linux", "armv6l"},
 | 
					 | 
				
			||||||
		{"linux", "arm", "7"}:    {"linux", "armv7l"},
 | 
					 | 
				
			||||||
		{"linux", "ppc64", ""}:   {"linux", "ppc64"},
 | 
					 | 
				
			||||||
		{"linux", "ppc64le", ""}: {"linux", "ppc64le"},
 | 
					 | 
				
			||||||
		{"linux", "s390x", ""}:   {"linux", "s390x"},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{"freebsd", "amd64", ""}: {"freebsd", "amd64"},
 | 
					 | 
				
			||||||
		{"freebsd", "386", ""}:   {"freebsd", "i386"},
 | 
					 | 
				
			||||||
		{"freebsd", "arm", ""}:   {"freebsd", "arm"},
 | 
					 | 
				
			||||||
		{"freebsd", "arm", "5"}:  {"freebsd", "arm"},
 | 
					 | 
				
			||||||
		{"freebsd", "arm", "6"}:  {"freebsd", "arm"},
 | 
					 | 
				
			||||||
		{"freebsd", "arm", "7"}:  {"freebsd", "arm"},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{"darwin", "amd64", ""}: {"darwin", "x86_64"},
 | 
					 | 
				
			||||||
		{"darwin", "386", ""}:   {"darwin", "i386"},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	archTuple, ok := tabularAppcToGo[goArchTuple{goOs, goArch, goArchFlavor}]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return "", "", fmt.Errorf("unknown arch tuple: %q - %q - %q", goOs, goArch, goArchFlavor)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return archTuple.appcOs, archTuple.appcArch, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ToGoOSArch translates an appc arch tuple (OS, architecture) into
 | 
					 | 
				
			||||||
// a Golang arch tuple (OS, architecture, flavor)
 | 
					 | 
				
			||||||
func ToGoOSArch(appcOs string, appcArch string) (goOs string, goArch string, goArchFlavor string, e error) {
 | 
					 | 
				
			||||||
	tabularGoToAppc := map[appcArchTuple]goArchTuple{
 | 
					 | 
				
			||||||
		// {"linux", "aarch64_be"}: nil,
 | 
					 | 
				
			||||||
		// {"linux", "armv7b"}: nil,
 | 
					 | 
				
			||||||
		{"linux", "aarch64"}: {"linux", "arm64", ""},
 | 
					 | 
				
			||||||
		{"linux", "amd64"}:   {"linux", "amd64", ""},
 | 
					 | 
				
			||||||
		{"linux", "armv6l"}:  {"linux", "arm", "6"},
 | 
					 | 
				
			||||||
		{"linux", "armv7l"}:  {"linux", "arm", "7"},
 | 
					 | 
				
			||||||
		{"linux", "i386"}:    {"linux", "386", ""},
 | 
					 | 
				
			||||||
		{"linux", "ppc64"}:   {"linux", "ppc64", ""},
 | 
					 | 
				
			||||||
		{"linux", "ppc64le"}: {"linux", "ppc64le", ""},
 | 
					 | 
				
			||||||
		{"linux", "s390x"}:   {"linux", "s390x", ""},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{"freebsd", "amd64"}: {"freebsd", "amd64", ""},
 | 
					 | 
				
			||||||
		{"freebsd", "arm"}:   {"freebsd", "arm", "6"},
 | 
					 | 
				
			||||||
		{"freebsd", "386"}:   {"freebsd", "i386", ""},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{"darwin", "amd64"}: {"darwin", "x86_64", ""},
 | 
					 | 
				
			||||||
		{"darwin", "386"}:   {"darwin", "i386", ""},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	archTuple, ok := tabularGoToAppc[appcArchTuple{appcOs, appcArch}]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return "", "", "", fmt.Errorf("unknown arch tuple: %q - %q", appcOs, appcArch)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return archTuple.goOs, archTuple.goArch, archTuple.goArchFlavor, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										92
									
								
								vendor/github.com/appc/spec/schema/types/mountpoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/appc/spec/schema/types/mountpoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,92 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/common"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MountPoint is the application-side manifestation of a Volume.
 | 
					 | 
				
			||||||
type MountPoint struct {
 | 
					 | 
				
			||||||
	Name     ACName `json:"name"`
 | 
					 | 
				
			||||||
	Path     string `json:"path"`
 | 
					 | 
				
			||||||
	ReadOnly bool   `json:"readOnly,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (mount MountPoint) assertValid() error {
 | 
					 | 
				
			||||||
	if mount.Name.Empty() {
 | 
					 | 
				
			||||||
		return errors.New("name must be set")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(mount.Path) == 0 {
 | 
					 | 
				
			||||||
		return errors.New("path must be set")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MountPointFromString takes a command line mountpoint parameter and returns a mountpoint
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// It is useful for actool patch-manifest --mounts
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Example mountpoint parameters:
 | 
					 | 
				
			||||||
// 	database,path=/tmp,readOnly=true
 | 
					 | 
				
			||||||
func MountPointFromString(mp string) (*MountPoint, error) {
 | 
					 | 
				
			||||||
	var mount MountPoint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mp = "name=" + mp
 | 
					 | 
				
			||||||
	mpQuery, err := common.MakeQueryString(mp)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	v, err := url.ParseQuery(mpQuery)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for key, val := range v {
 | 
					 | 
				
			||||||
		if len(val) > 1 {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("label %s with multiple values %q", key, val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch key {
 | 
					 | 
				
			||||||
		case "name":
 | 
					 | 
				
			||||||
			acn, err := NewACName(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			mount.Name = *acn
 | 
					 | 
				
			||||||
		case "path":
 | 
					 | 
				
			||||||
			mount.Path = val[0]
 | 
					 | 
				
			||||||
		case "readOnly":
 | 
					 | 
				
			||||||
			ro, err := strconv.ParseBool(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			mount.ReadOnly = ro
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("unknown mountpoint parameter %q", key)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	err = mount.assertValid()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &mount, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										147
									
								
								vendor/github.com/appc/spec/schema/types/port.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										147
									
								
								vendor/github.com/appc/spec/schema/types/port.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,147 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/common"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Port represents a port as offered by an application *inside*
 | 
					 | 
				
			||||||
// the pod.
 | 
					 | 
				
			||||||
type Port struct {
 | 
					 | 
				
			||||||
	Name            ACName `json:"name"`
 | 
					 | 
				
			||||||
	Protocol        string `json:"protocol"`
 | 
					 | 
				
			||||||
	Port            uint   `json:"port"`
 | 
					 | 
				
			||||||
	Count           uint   `json:"count"`
 | 
					 | 
				
			||||||
	SocketActivated bool   `json:"socketActivated"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ExposedPort represents a port listening on the host side.
 | 
					 | 
				
			||||||
// The PodPort is optional -- if missing, then try and find the pod-side
 | 
					 | 
				
			||||||
// information by matching names
 | 
					 | 
				
			||||||
type ExposedPort struct {
 | 
					 | 
				
			||||||
	Name     ACName `json:"name"`
 | 
					 | 
				
			||||||
	HostPort uint   `json:"hostPort"`
 | 
					 | 
				
			||||||
	HostIP   net.IP `json:"hostIP,omitempty"`  // optional
 | 
					 | 
				
			||||||
	PodPort  *Port  `json:"podPort,omitempty"` // optional. If missing, try and find a corresponding App's port
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type port Port
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (p *Port) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var pp port
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &pp); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	np := Port(pp)
 | 
					 | 
				
			||||||
	if err := np.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if np.Count == 0 {
 | 
					 | 
				
			||||||
		np.Count = 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*p = np
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (p Port) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := p.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(port(p))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (p Port) assertValid() error {
 | 
					 | 
				
			||||||
	// Although there are no guarantees, most (if not all)
 | 
					 | 
				
			||||||
	// transport protocols use 16 bit ports
 | 
					 | 
				
			||||||
	if p.Port > 65535 || p.Port < 1 {
 | 
					 | 
				
			||||||
		return errors.New("port must be in 1-65535 range")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if p.Port+p.Count > 65536 {
 | 
					 | 
				
			||||||
		return errors.New("end of port range must be in 1-65535 range")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PortFromString takes a command line port parameter and returns a port
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// It is useful for actool patch-manifest --ports
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Example port parameters:
 | 
					 | 
				
			||||||
//      health-check,protocol=udp,port=8000
 | 
					 | 
				
			||||||
// 	query,protocol=tcp,port=8080,count=1,socketActivated=true
 | 
					 | 
				
			||||||
func PortFromString(pt string) (*Port, error) {
 | 
					 | 
				
			||||||
	var port Port
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pt = "name=" + pt
 | 
					 | 
				
			||||||
	ptQuery, err := common.MakeQueryString(pt)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	v, err := url.ParseQuery(ptQuery)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for key, val := range v {
 | 
					 | 
				
			||||||
		if len(val) > 1 {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("label %s with multiple values %q", key, val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch key {
 | 
					 | 
				
			||||||
		case "name":
 | 
					 | 
				
			||||||
			acn, err := NewACName(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			port.Name = *acn
 | 
					 | 
				
			||||||
		case "protocol":
 | 
					 | 
				
			||||||
			port.Protocol = val[0]
 | 
					 | 
				
			||||||
		case "port":
 | 
					 | 
				
			||||||
			p, err := strconv.ParseUint(val[0], 10, 16)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			port.Port = uint(p)
 | 
					 | 
				
			||||||
		case "count":
 | 
					 | 
				
			||||||
			cnt, err := strconv.ParseUint(val[0], 10, 16)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			port.Count = uint(cnt)
 | 
					 | 
				
			||||||
		case "socketActivated":
 | 
					 | 
				
			||||||
			sa, err := strconv.ParseBool(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			port.SocketActivated = sa
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("unknown port parameter %q", key)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	err = port.assertValid()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &port, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										32
									
								
								vendor/github.com/appc/spec/schema/types/resource/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/appc/spec/schema/types/resource/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,32 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "amount.go",
 | 
					 | 
				
			||||||
        "math.go",
 | 
					 | 
				
			||||||
        "quantity.go",
 | 
					 | 
				
			||||||
        "scale_int.go",
 | 
					 | 
				
			||||||
        "suffix.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    importpath = "github.com/appc/spec/schema/types/resource",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
    deps = [
 | 
					 | 
				
			||||||
        "//vendor/github.com/spf13/pflag:go_default_library",
 | 
					 | 
				
			||||||
        "//vendor/gopkg.in/inf.v0:go_default_library",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/appc/spec/schema/types/resource/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/appc/spec/schema/types/resource/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,4 +0,0 @@
 | 
				
			|||||||
This package was copied in from the Kubernetes repo to avoid a cyclic
 | 
					 | 
				
			||||||
dependency. These files were taken from master from
 | 
					 | 
				
			||||||
github.com/kubernetes/kubernetes at commit hash
 | 
					 | 
				
			||||||
b0deb2eb8f4037421077f77cb163dbb4c0a2a9f5.
 | 
					 | 
				
			||||||
							
								
								
									
										298
									
								
								vendor/github.com/appc/spec/schema/types/resource/amount.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										298
									
								
								vendor/github.com/appc/spec/schema/types/resource/amount.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,298 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package resource
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inf "gopkg.in/inf.v0"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Scale is used for getting and setting the base-10 scaled value.
 | 
					 | 
				
			||||||
// Base-2 scales are omitted for mathematical simplicity.
 | 
					 | 
				
			||||||
// See Quantity.ScaledValue for more details.
 | 
					 | 
				
			||||||
type Scale int32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// infScale adapts a Scale value to an inf.Scale value.
 | 
					 | 
				
			||||||
func (s Scale) infScale() inf.Scale {
 | 
					 | 
				
			||||||
	return inf.Scale(-s) // inf.Scale is upside-down
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	Nano  Scale = -9
 | 
					 | 
				
			||||||
	Micro Scale = -6
 | 
					 | 
				
			||||||
	Milli Scale = -3
 | 
					 | 
				
			||||||
	Kilo  Scale = 3
 | 
					 | 
				
			||||||
	Mega  Scale = 6
 | 
					 | 
				
			||||||
	Giga  Scale = 9
 | 
					 | 
				
			||||||
	Tera  Scale = 12
 | 
					 | 
				
			||||||
	Peta  Scale = 15
 | 
					 | 
				
			||||||
	Exa   Scale = 18
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	Zero = int64Amount{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Used by quantity strings - treat as read only
 | 
					 | 
				
			||||||
	zeroBytes = []byte("0")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64Amount represents a fixed precision numerator and arbitrary scale exponent. It is faster
 | 
					 | 
				
			||||||
// than operations on inf.Dec for values that can be represented as int64.
 | 
					 | 
				
			||||||
type int64Amount struct {
 | 
					 | 
				
			||||||
	value int64
 | 
					 | 
				
			||||||
	scale Scale
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sign returns 0 if the value is zero, -1 if it is less than 0, or 1 if it is greater than 0.
 | 
					 | 
				
			||||||
func (a int64Amount) Sign() int {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case a.value == 0:
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	case a.value > 0:
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsInt64 returns the current amount as an int64 at scale 0, or false if the value cannot be
 | 
					 | 
				
			||||||
// represented in an int64 OR would result in a loss of precision. This method is intended as
 | 
					 | 
				
			||||||
// an optimization to avoid calling AsDec.
 | 
					 | 
				
			||||||
func (a int64Amount) AsInt64() (int64, bool) {
 | 
					 | 
				
			||||||
	if a.scale == 0 {
 | 
					 | 
				
			||||||
		return a.value, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a.scale < 0 {
 | 
					 | 
				
			||||||
		// TODO: attempt to reduce factors, although it is assumed that factors are reduced prior
 | 
					 | 
				
			||||||
		// to the int64Amount being created.
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return positiveScaleInt64(a.value, a.scale)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsScaledInt64 returns an int64 representing the value of this amount at the specified scale,
 | 
					 | 
				
			||||||
// rounding up, or false if that would result in overflow. (1e20).AsScaledInt64(1) would result
 | 
					 | 
				
			||||||
// in overflow because 1e19 is not representable as an int64. Note that setting a scale larger
 | 
					 | 
				
			||||||
// than the current value may result in loss of precision - i.e. (1e-6).AsScaledInt64(0) would
 | 
					 | 
				
			||||||
// return 1, because 0.000001 is rounded up to 1.
 | 
					 | 
				
			||||||
func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) {
 | 
					 | 
				
			||||||
	if a.scale < scale {
 | 
					 | 
				
			||||||
		result, _ = negativeScaleInt64(a.value, scale-a.scale)
 | 
					 | 
				
			||||||
		return result, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return positiveScaleInt64(a.value, a.scale-scale)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsDec returns an inf.Dec representation of this value.
 | 
					 | 
				
			||||||
func (a int64Amount) AsDec() *inf.Dec {
 | 
					 | 
				
			||||||
	var base inf.Dec
 | 
					 | 
				
			||||||
	base.SetUnscaled(a.value)
 | 
					 | 
				
			||||||
	base.SetScale(inf.Scale(-a.scale))
 | 
					 | 
				
			||||||
	return &base
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Cmp returns 0 if a and b are equal, 1 if a is greater than b, or -1 if a is less than b.
 | 
					 | 
				
			||||||
func (a int64Amount) Cmp(b int64Amount) int {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case a.scale == b.scale:
 | 
					 | 
				
			||||||
		// compare only the unscaled portion
 | 
					 | 
				
			||||||
	case a.scale > b.scale:
 | 
					 | 
				
			||||||
		result, remainder, exact := divideByScaleInt64(b.value, a.scale-b.scale)
 | 
					 | 
				
			||||||
		if !exact {
 | 
					 | 
				
			||||||
			return a.AsDec().Cmp(b.AsDec())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if result == a.value {
 | 
					 | 
				
			||||||
			switch {
 | 
					 | 
				
			||||||
			case remainder == 0:
 | 
					 | 
				
			||||||
				return 0
 | 
					 | 
				
			||||||
			case remainder > 0:
 | 
					 | 
				
			||||||
				return -1
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				return 1
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b.value = result
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		result, remainder, exact := divideByScaleInt64(a.value, b.scale-a.scale)
 | 
					 | 
				
			||||||
		if !exact {
 | 
					 | 
				
			||||||
			return a.AsDec().Cmp(b.AsDec())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if result == b.value {
 | 
					 | 
				
			||||||
			switch {
 | 
					 | 
				
			||||||
			case remainder == 0:
 | 
					 | 
				
			||||||
				return 0
 | 
					 | 
				
			||||||
			case remainder > 0:
 | 
					 | 
				
			||||||
				return 1
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				return -1
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		a.value = result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case a.value == b.value:
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	case a.value < b.value:
 | 
					 | 
				
			||||||
		return -1
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Add adds two int64Amounts together, matching scales. It will return false and not mutate
 | 
					 | 
				
			||||||
// a if overflow or underflow would result.
 | 
					 | 
				
			||||||
func (a *int64Amount) Add(b int64Amount) bool {
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case b.value == 0:
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	case a.value == 0:
 | 
					 | 
				
			||||||
		a.value = b.value
 | 
					 | 
				
			||||||
		a.scale = b.scale
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	case a.scale == b.scale:
 | 
					 | 
				
			||||||
		c, ok := int64Add(a.value, b.value)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		a.value = c
 | 
					 | 
				
			||||||
	case a.scale > b.scale:
 | 
					 | 
				
			||||||
		c, ok := positiveScaleInt64(a.value, a.scale-b.scale)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		c, ok = int64Add(c, b.value)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		a.scale = b.scale
 | 
					 | 
				
			||||||
		a.value = c
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		c, ok := positiveScaleInt64(b.value, b.scale-a.scale)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		c, ok = int64Add(a.value, c)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		a.value = c
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sub removes the value of b from the current amount, or returns false if underflow would result.
 | 
					 | 
				
			||||||
func (a *int64Amount) Sub(b int64Amount) bool {
 | 
					 | 
				
			||||||
	return a.Add(int64Amount{value: -b.value, scale: b.scale})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
 | 
					 | 
				
			||||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
 | 
					 | 
				
			||||||
func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
 | 
					 | 
				
			||||||
	if a.scale >= scale {
 | 
					 | 
				
			||||||
		return a, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result, exact := negativeScaleInt64(a.value, scale-a.scale)
 | 
					 | 
				
			||||||
	return int64Amount{value: result, scale: scale}, exact
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
 | 
					 | 
				
			||||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
 | 
					 | 
				
			||||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
 | 
					 | 
				
			||||||
func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
 | 
					 | 
				
			||||||
	mantissa := a.value
 | 
					 | 
				
			||||||
	exponent = int32(a.scale)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	amount, times := removeInt64Factors(mantissa, 10)
 | 
					 | 
				
			||||||
	exponent += int32(times)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// make sure exponent is a multiple of 3
 | 
					 | 
				
			||||||
	var ok bool
 | 
					 | 
				
			||||||
	switch exponent % 3 {
 | 
					 | 
				
			||||||
	case 1, -2:
 | 
					 | 
				
			||||||
		amount, ok = int64MultiplyScale10(amount)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		exponent = exponent - 1
 | 
					 | 
				
			||||||
	case 2, -1:
 | 
					 | 
				
			||||||
		amount, ok = int64MultiplyScale100(amount)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		exponent = exponent - 2
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strconv.AppendInt(out, amount, 10), exponent
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
 | 
					 | 
				
			||||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
 | 
					 | 
				
			||||||
// return []byte("2048"), 1.
 | 
					 | 
				
			||||||
func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
 | 
					 | 
				
			||||||
	value, ok := a.AsScaledInt64(0)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return infDecAmount{a.AsDec()}.AsCanonicalBase1024Bytes(out)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	amount, exponent := removeInt64Factors(value, 1024)
 | 
					 | 
				
			||||||
	return strconv.AppendInt(out, amount, 10), exponent
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// infDecAmount implements common operations over an inf.Dec that are specific to the quantity
 | 
					 | 
				
			||||||
// representation.
 | 
					 | 
				
			||||||
type infDecAmount struct {
 | 
					 | 
				
			||||||
	*inf.Dec
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
 | 
					 | 
				
			||||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
 | 
					 | 
				
			||||||
func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) {
 | 
					 | 
				
			||||||
	tmp := &inf.Dec{}
 | 
					 | 
				
			||||||
	tmp.Round(a.Dec, scale.infScale(), inf.RoundUp)
 | 
					 | 
				
			||||||
	return infDecAmount{tmp}, tmp.Cmp(a.Dec) == 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
 | 
					 | 
				
			||||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
 | 
					 | 
				
			||||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
 | 
					 | 
				
			||||||
func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
 | 
					 | 
				
			||||||
	mantissa := a.Dec.UnscaledBig()
 | 
					 | 
				
			||||||
	exponent = int32(-a.Dec.Scale())
 | 
					 | 
				
			||||||
	amount := big.NewInt(0).Set(mantissa)
 | 
					 | 
				
			||||||
	// move all factors of 10 into the exponent for easy reasoning
 | 
					 | 
				
			||||||
	amount, times := removeBigIntFactors(amount, bigTen)
 | 
					 | 
				
			||||||
	exponent += times
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// make sure exponent is a multiple of 3
 | 
					 | 
				
			||||||
	for exponent%3 != 0 {
 | 
					 | 
				
			||||||
		amount.Mul(amount, bigTen)
 | 
					 | 
				
			||||||
		exponent--
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return append(out, amount.String()...), exponent
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
 | 
					 | 
				
			||||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
 | 
					 | 
				
			||||||
// return []byte("2048"), 1.
 | 
					 | 
				
			||||||
func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
 | 
					 | 
				
			||||||
	tmp := &inf.Dec{}
 | 
					 | 
				
			||||||
	tmp.Round(a.Dec, 0, inf.RoundUp)
 | 
					 | 
				
			||||||
	amount, exponent := removeBigIntFactors(tmp.UnscaledBig(), big1024)
 | 
					 | 
				
			||||||
	return append(out, amount.String()...), exponent
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										327
									
								
								vendor/github.com/appc/spec/schema/types/resource/math.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										327
									
								
								vendor/github.com/appc/spec/schema/types/resource/math.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,327 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package resource
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inf "gopkg.in/inf.v0"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64.
 | 
					 | 
				
			||||||
	// It is also the maximum decimal digits that can be represented with an int64.
 | 
					 | 
				
			||||||
	maxInt64Factors = 18
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// Commonly needed big.Int values-- treat as read only!
 | 
					 | 
				
			||||||
	bigTen      = big.NewInt(10)
 | 
					 | 
				
			||||||
	bigZero     = big.NewInt(0)
 | 
					 | 
				
			||||||
	bigOne      = big.NewInt(1)
 | 
					 | 
				
			||||||
	bigThousand = big.NewInt(1000)
 | 
					 | 
				
			||||||
	big1024     = big.NewInt(1024)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Commonly needed inf.Dec values-- treat as read only!
 | 
					 | 
				
			||||||
	decZero      = inf.NewDec(0, 0)
 | 
					 | 
				
			||||||
	decOne       = inf.NewDec(1, 0)
 | 
					 | 
				
			||||||
	decMinusOne  = inf.NewDec(-1, 0)
 | 
					 | 
				
			||||||
	decThousand  = inf.NewDec(1000, 0)
 | 
					 | 
				
			||||||
	dec1024      = inf.NewDec(1024, 0)
 | 
					 | 
				
			||||||
	decMinus1024 = inf.NewDec(-1024, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Largest (in magnitude) number allowed.
 | 
					 | 
				
			||||||
	maxAllowed = infDecAmount{inf.NewDec((1<<63)-1, 0)} // == max int64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// The maximum value we can represent milli-units for.
 | 
					 | 
				
			||||||
	// Compare with the return value of Quantity.Value() to
 | 
					 | 
				
			||||||
	// see if it's safe to use Quantity.MilliValue().
 | 
					 | 
				
			||||||
	MaxMilliValue = int64(((1 << 63) - 1) / 1000)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const mostNegative = -(mostPositive + 1)
 | 
					 | 
				
			||||||
const mostPositive = 1<<63 - 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64Add returns a+b, or false if that would overflow int64.
 | 
					 | 
				
			||||||
func int64Add(a, b int64) (int64, bool) {
 | 
					 | 
				
			||||||
	c := a + b
 | 
					 | 
				
			||||||
	switch {
 | 
					 | 
				
			||||||
	case a > 0 && b > 0:
 | 
					 | 
				
			||||||
		if c < 0 {
 | 
					 | 
				
			||||||
			return 0, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	case a < 0 && b < 0:
 | 
					 | 
				
			||||||
		if c > 0 {
 | 
					 | 
				
			||||||
			return 0, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if a == mostNegative && b == mostNegative {
 | 
					 | 
				
			||||||
			return 0, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return c, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64Multiply returns a*b, or false if that would overflow or underflow int64.
 | 
					 | 
				
			||||||
func int64Multiply(a, b int64) (int64, bool) {
 | 
					 | 
				
			||||||
	if a == 0 || b == 0 || a == 1 || b == 1 {
 | 
					 | 
				
			||||||
		return a * b, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a == mostNegative || b == mostNegative {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := a * b
 | 
					 | 
				
			||||||
	return c, c/b == a
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64MultiplyScale returns a*b, assuming b is greater than one, or false if that would overflow or underflow int64.
 | 
					 | 
				
			||||||
// Use when b is known to be greater than one.
 | 
					 | 
				
			||||||
func int64MultiplyScale(a int64, b int64) (int64, bool) {
 | 
					 | 
				
			||||||
	if a == 0 || a == 1 {
 | 
					 | 
				
			||||||
		return a * b, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a == mostNegative && b != 1 {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := a * b
 | 
					 | 
				
			||||||
	return c, c/b == a
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64MultiplyScale10 multiplies a by 10, or returns false if that would overflow. This method is faster than
 | 
					 | 
				
			||||||
// int64Multiply(a, 10) because the compiler can optimize constant factor multiplication.
 | 
					 | 
				
			||||||
func int64MultiplyScale10(a int64) (int64, bool) {
 | 
					 | 
				
			||||||
	if a == 0 || a == 1 {
 | 
					 | 
				
			||||||
		return a * 10, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a == mostNegative {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := a * 10
 | 
					 | 
				
			||||||
	return c, c/10 == a
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64MultiplyScale100 multiplies a by 100, or returns false if that would overflow. This method is faster than
 | 
					 | 
				
			||||||
// int64Multiply(a, 100) because the compiler can optimize constant factor multiplication.
 | 
					 | 
				
			||||||
func int64MultiplyScale100(a int64) (int64, bool) {
 | 
					 | 
				
			||||||
	if a == 0 || a == 1 {
 | 
					 | 
				
			||||||
		return a * 100, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a == mostNegative {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := a * 100
 | 
					 | 
				
			||||||
	return c, c/100 == a
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64MultiplyScale1000 multiplies a by 1000, or returns false if that would overflow. This method is faster than
 | 
					 | 
				
			||||||
// int64Multiply(a, 1000) because the compiler can optimize constant factor multiplication.
 | 
					 | 
				
			||||||
func int64MultiplyScale1000(a int64) (int64, bool) {
 | 
					 | 
				
			||||||
	if a == 0 || a == 1 {
 | 
					 | 
				
			||||||
		return a * 1000, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a == mostNegative {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c := a * 1000
 | 
					 | 
				
			||||||
	return c, c/1000 == a
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// positiveScaleInt64 multiplies base by 10^scale, returning false if the
 | 
					 | 
				
			||||||
// value overflows. Passing a negative scale is undefined.
 | 
					 | 
				
			||||||
func positiveScaleInt64(base int64, scale Scale) (int64, bool) {
 | 
					 | 
				
			||||||
	switch scale {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		return base, true
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		return int64MultiplyScale10(base)
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		return int64MultiplyScale100(base)
 | 
					 | 
				
			||||||
	case 3:
 | 
					 | 
				
			||||||
		return int64MultiplyScale1000(base)
 | 
					 | 
				
			||||||
	case 6:
 | 
					 | 
				
			||||||
		return int64MultiplyScale(base, 1000000)
 | 
					 | 
				
			||||||
	case 9:
 | 
					 | 
				
			||||||
		return int64MultiplyScale(base, 1000000000)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		value := base
 | 
					 | 
				
			||||||
		var ok bool
 | 
					 | 
				
			||||||
		for i := Scale(0); i < scale; i++ {
 | 
					 | 
				
			||||||
			if value, ok = int64MultiplyScale(value, 10); !ok {
 | 
					 | 
				
			||||||
				return 0, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return value, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// negativeScaleInt64 reduces base by the provided scale, rounding up, until the
 | 
					 | 
				
			||||||
// value is zero or the scale is reached. Passing a negative scale is undefined.
 | 
					 | 
				
			||||||
// The value returned, if not exact, is rounded away from zero.
 | 
					 | 
				
			||||||
func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) {
 | 
					 | 
				
			||||||
	if scale == 0 {
 | 
					 | 
				
			||||||
		return base, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	value := base
 | 
					 | 
				
			||||||
	var fraction bool
 | 
					 | 
				
			||||||
	for i := Scale(0); i < scale; i++ {
 | 
					 | 
				
			||||||
		if !fraction && value%10 != 0 {
 | 
					 | 
				
			||||||
			fraction = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		value = value / 10
 | 
					 | 
				
			||||||
		if value == 0 {
 | 
					 | 
				
			||||||
			if fraction {
 | 
					 | 
				
			||||||
				if base > 0 {
 | 
					 | 
				
			||||||
					return 1, false
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return -1, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return 0, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if fraction {
 | 
					 | 
				
			||||||
		if base > 0 {
 | 
					 | 
				
			||||||
			value += 1
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			value += -1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return value, !fraction
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func pow10Int64(b int64) int64 {
 | 
					 | 
				
			||||||
	switch b {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		return 10
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		return 100
 | 
					 | 
				
			||||||
	case 3:
 | 
					 | 
				
			||||||
		return 1000
 | 
					 | 
				
			||||||
	case 4:
 | 
					 | 
				
			||||||
		return 10000
 | 
					 | 
				
			||||||
	case 5:
 | 
					 | 
				
			||||||
		return 100000
 | 
					 | 
				
			||||||
	case 6:
 | 
					 | 
				
			||||||
		return 1000000
 | 
					 | 
				
			||||||
	case 7:
 | 
					 | 
				
			||||||
		return 10000000
 | 
					 | 
				
			||||||
	case 8:
 | 
					 | 
				
			||||||
		return 100000000
 | 
					 | 
				
			||||||
	case 9:
 | 
					 | 
				
			||||||
		return 1000000000
 | 
					 | 
				
			||||||
	case 10:
 | 
					 | 
				
			||||||
		return 10000000000
 | 
					 | 
				
			||||||
	case 11:
 | 
					 | 
				
			||||||
		return 100000000000
 | 
					 | 
				
			||||||
	case 12:
 | 
					 | 
				
			||||||
		return 1000000000000
 | 
					 | 
				
			||||||
	case 13:
 | 
					 | 
				
			||||||
		return 10000000000000
 | 
					 | 
				
			||||||
	case 14:
 | 
					 | 
				
			||||||
		return 100000000000000
 | 
					 | 
				
			||||||
	case 15:
 | 
					 | 
				
			||||||
		return 1000000000000000
 | 
					 | 
				
			||||||
	case 16:
 | 
					 | 
				
			||||||
		return 10000000000000000
 | 
					 | 
				
			||||||
	case 17:
 | 
					 | 
				
			||||||
		return 100000000000000000
 | 
					 | 
				
			||||||
	case 18:
 | 
					 | 
				
			||||||
		return 1000000000000000000
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// powInt64 raises a to the bth power. Is not overflow aware.
 | 
					 | 
				
			||||||
func powInt64(a, b int64) int64 {
 | 
					 | 
				
			||||||
	p := int64(1)
 | 
					 | 
				
			||||||
	for b > 0 {
 | 
					 | 
				
			||||||
		if b&1 != 0 {
 | 
					 | 
				
			||||||
			p *= a
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		b >>= 1
 | 
					 | 
				
			||||||
		a *= a
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return p
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// negativeScaleInt64 returns the result of dividing base by scale * 10 and the remainder, or
 | 
					 | 
				
			||||||
// false if no such division is possible. Dividing by negative scales is undefined.
 | 
					 | 
				
			||||||
func divideByScaleInt64(base int64, scale Scale) (result, remainder int64, exact bool) {
 | 
					 | 
				
			||||||
	if scale == 0 {
 | 
					 | 
				
			||||||
		return base, 0, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// the max scale representable in base 10 in an int64 is 18 decimal places
 | 
					 | 
				
			||||||
	if scale >= 18 {
 | 
					 | 
				
			||||||
		return 0, base, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	divisor := pow10Int64(int64(scale))
 | 
					 | 
				
			||||||
	return base / divisor, base % divisor, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// removeInt64Factors divides in a loop; the return values have the property that
 | 
					 | 
				
			||||||
// value == result * base ^ scale
 | 
					 | 
				
			||||||
func removeInt64Factors(value int64, base int64) (result int64, times int32) {
 | 
					 | 
				
			||||||
	times = 0
 | 
					 | 
				
			||||||
	result = value
 | 
					 | 
				
			||||||
	negative := result < 0
 | 
					 | 
				
			||||||
	if negative {
 | 
					 | 
				
			||||||
		result = -result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	switch base {
 | 
					 | 
				
			||||||
	// allow the compiler to optimize the common cases
 | 
					 | 
				
			||||||
	case 10:
 | 
					 | 
				
			||||||
		for result >= 10 && result%10 == 0 {
 | 
					 | 
				
			||||||
			times++
 | 
					 | 
				
			||||||
			result = result / 10
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	// allow the compiler to optimize the common cases
 | 
					 | 
				
			||||||
	case 1024:
 | 
					 | 
				
			||||||
		for result >= 1024 && result%1024 == 0 {
 | 
					 | 
				
			||||||
			times++
 | 
					 | 
				
			||||||
			result = result / 1024
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		for result >= base && result%base == 0 {
 | 
					 | 
				
			||||||
			times++
 | 
					 | 
				
			||||||
			result = result / base
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if negative {
 | 
					 | 
				
			||||||
		result = -result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result, times
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// removeBigIntFactors divides in a loop; the return values have the property that
 | 
					 | 
				
			||||||
// d == result * factor ^ times
 | 
					 | 
				
			||||||
// d may be modified in place.
 | 
					 | 
				
			||||||
// If d == 0, then the return values will be (0, 0)
 | 
					 | 
				
			||||||
func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int32) {
 | 
					 | 
				
			||||||
	q := big.NewInt(0)
 | 
					 | 
				
			||||||
	m := big.NewInt(0)
 | 
					 | 
				
			||||||
	for d.Cmp(bigZero) != 0 {
 | 
					 | 
				
			||||||
		q.DivMod(d, factor, m)
 | 
					 | 
				
			||||||
		if m.Cmp(bigZero) != 0 {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		times++
 | 
					 | 
				
			||||||
		d, q = q, d
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return d, times
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										768
									
								
								vendor/github.com/appc/spec/schema/types/resource/quantity.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										768
									
								
								vendor/github.com/appc/spec/schema/types/resource/quantity.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,768 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package resource
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	flag "github.com/spf13/pflag"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inf "gopkg.in/inf.v0"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Quantity is a fixed-point representation of a number.
 | 
					 | 
				
			||||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
 | 
					 | 
				
			||||||
// in addition to String() and Int64() accessors.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The serialization format is:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// <quantity>        ::= <signedNumber><suffix>
 | 
					 | 
				
			||||||
//   (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
 | 
					 | 
				
			||||||
// <digit>           ::= 0 | 1 | ... | 9
 | 
					 | 
				
			||||||
// <digits>          ::= <digit> | <digit><digits>
 | 
					 | 
				
			||||||
// <number>          ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
 | 
					 | 
				
			||||||
// <sign>            ::= "+" | "-"
 | 
					 | 
				
			||||||
// <signedNumber>    ::= <number> | <sign><number>
 | 
					 | 
				
			||||||
// <suffix>          ::= <binarySI> | <decimalExponent> | <decimalSI>
 | 
					 | 
				
			||||||
// <binarySI>        ::= Ki | Mi | Gi | Ti | Pi | Ei
 | 
					 | 
				
			||||||
//   (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
 | 
					 | 
				
			||||||
// <decimalSI>       ::= m | "" | k | M | G | T | P | E
 | 
					 | 
				
			||||||
//   (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
 | 
					 | 
				
			||||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// No matter which of the three exponent forms is used, no quantity may represent
 | 
					 | 
				
			||||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
 | 
					 | 
				
			||||||
// places. Numbers larger or more precise will be capped or rounded up.
 | 
					 | 
				
			||||||
// (E.g.: 0.1m will rounded up to 1m.)
 | 
					 | 
				
			||||||
// This may be extended in the future if we require larger or smaller quantities.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// When a Quantity is parsed from a string, it will remember the type of suffix
 | 
					 | 
				
			||||||
// it had, and will use the same type again when it is serialized.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Before serializing, Quantity will be put in "canonical form".
 | 
					 | 
				
			||||||
// This means that Exponent/suffix will be adjusted up or down (with a
 | 
					 | 
				
			||||||
// corresponding increase or decrease in Mantissa) such that:
 | 
					 | 
				
			||||||
//   a. No precision is lost
 | 
					 | 
				
			||||||
//   b. No fractional digits will be emitted
 | 
					 | 
				
			||||||
//   c. The exponent (or suffix) is as large as possible.
 | 
					 | 
				
			||||||
// The sign will be omitted unless the number is negative.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Examples:
 | 
					 | 
				
			||||||
//   1.5 will be serialized as "1500m"
 | 
					 | 
				
			||||||
//   1.5Gi will be serialized as "1536Mi"
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// NOTE: We reserve the right to amend this canonical format, perhaps to
 | 
					 | 
				
			||||||
//   allow 1.5 to be canonical.
 | 
					 | 
				
			||||||
// TODO: Remove above disclaimer after all bikeshedding about format is over,
 | 
					 | 
				
			||||||
//   or after March 2015.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Note that the quantity will NEVER be internally represented by a
 | 
					 | 
				
			||||||
// floating point number. That is the whole point of this exercise.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Non-canonical values will still parse as long as they are well formed,
 | 
					 | 
				
			||||||
// but will be re-emitted in their canonical form. (So always use canonical
 | 
					 | 
				
			||||||
// form, or don't diff.)
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This format is intended to make it difficult to use these numbers without
 | 
					 | 
				
			||||||
// writing some sort of special handling code in the hopes that that will
 | 
					 | 
				
			||||||
// cause implementors to also use a fixed point implementation.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// +gencopy=false
 | 
					 | 
				
			||||||
// +protobuf=true
 | 
					 | 
				
			||||||
// +protobuf.embed=string
 | 
					 | 
				
			||||||
// +protobuf.options.marshal=false
 | 
					 | 
				
			||||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
 | 
					 | 
				
			||||||
type Quantity struct {
 | 
					 | 
				
			||||||
	// i is the quantity in int64 scaled form, if d.Dec == nil
 | 
					 | 
				
			||||||
	i int64Amount
 | 
					 | 
				
			||||||
	// d is the quantity in inf.Dec form if d.Dec != nil
 | 
					 | 
				
			||||||
	d infDecAmount
 | 
					 | 
				
			||||||
	// s is the generated value of this quantity to avoid recalculation
 | 
					 | 
				
			||||||
	s string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Change Format at will. See the comment for Canonicalize for
 | 
					 | 
				
			||||||
	// more details.
 | 
					 | 
				
			||||||
	Format
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CanonicalValue allows a quantity amount to be converted to a string.
 | 
					 | 
				
			||||||
type CanonicalValue interface {
 | 
					 | 
				
			||||||
	// AsCanonicalBytes returns a byte array representing the string representation
 | 
					 | 
				
			||||||
	// of the value mantissa and an int32 representing its exponent in base-10. Callers may
 | 
					 | 
				
			||||||
	// pass a byte slice to the method to avoid allocations.
 | 
					 | 
				
			||||||
	AsCanonicalBytes(out []byte) ([]byte, int32)
 | 
					 | 
				
			||||||
	// AsCanonicalBase1024Bytes returns a byte array representing the string representation
 | 
					 | 
				
			||||||
	// of the value mantissa and an int32 representing its exponent in base-1024. Callers
 | 
					 | 
				
			||||||
	// may pass a byte slice to the method to avoid allocations.
 | 
					 | 
				
			||||||
	AsCanonicalBase1024Bytes(out []byte) ([]byte, int32)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Format lists the three possible formattings of a quantity.
 | 
					 | 
				
			||||||
type Format string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	DecimalExponent = Format("DecimalExponent") // e.g., 12e6
 | 
					 | 
				
			||||||
	BinarySI        = Format("BinarySI")        // e.g., 12Mi (12 * 2^20)
 | 
					 | 
				
			||||||
	DecimalSI       = Format("DecimalSI")       // e.g., 12M  (12 * 10^6)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MustParse turns the given string into a quantity or panics; for tests
 | 
					 | 
				
			||||||
// or others cases where you know the string is valid.
 | 
					 | 
				
			||||||
func MustParse(str string) Quantity {
 | 
					 | 
				
			||||||
	q, err := ParseQuantity(str)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(fmt.Errorf("cannot parse '%v': %v", str, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// splitREString is used to separate a number from its suffix; as such,
 | 
					 | 
				
			||||||
	// this is overly permissive, but that's OK-- it will be checked later.
 | 
					 | 
				
			||||||
	splitREString = "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// splitRE is used to get the various parts of a number.
 | 
					 | 
				
			||||||
	splitRE = regexp.MustCompile(splitREString)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Errors that could happen while parsing a string.
 | 
					 | 
				
			||||||
	ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
 | 
					 | 
				
			||||||
	ErrNumeric     = errors.New("unable to parse numeric part of quantity")
 | 
					 | 
				
			||||||
	ErrSuffix      = errors.New("unable to parse quantity's suffix")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// parseQuantityString is a fast scanner for quantity values.
 | 
					 | 
				
			||||||
func parseQuantityString(str string) (positive bool, value, num, denom, suffix string, err error) {
 | 
					 | 
				
			||||||
	positive = true
 | 
					 | 
				
			||||||
	pos := 0
 | 
					 | 
				
			||||||
	end := len(str)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// handle leading sign
 | 
					 | 
				
			||||||
	if pos < end {
 | 
					 | 
				
			||||||
		switch str[0] {
 | 
					 | 
				
			||||||
		case '-':
 | 
					 | 
				
			||||||
			positive = false
 | 
					 | 
				
			||||||
			pos++
 | 
					 | 
				
			||||||
		case '+':
 | 
					 | 
				
			||||||
			pos++
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// strip leading zeros
 | 
					 | 
				
			||||||
Zeroes:
 | 
					 | 
				
			||||||
	for i := pos; ; i++ {
 | 
					 | 
				
			||||||
		if i >= end {
 | 
					 | 
				
			||||||
			num = "0"
 | 
					 | 
				
			||||||
			value = num
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch str[i] {
 | 
					 | 
				
			||||||
		case '0':
 | 
					 | 
				
			||||||
			pos++
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			break Zeroes
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// extract the numerator
 | 
					 | 
				
			||||||
Num:
 | 
					 | 
				
			||||||
	for i := pos; ; i++ {
 | 
					 | 
				
			||||||
		if i >= end {
 | 
					 | 
				
			||||||
			num = str[pos:end]
 | 
					 | 
				
			||||||
			value = str[0:end]
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch str[i] {
 | 
					 | 
				
			||||||
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			num = str[pos:i]
 | 
					 | 
				
			||||||
			pos = i
 | 
					 | 
				
			||||||
			break Num
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// if we stripped all numerator positions, always return 0
 | 
					 | 
				
			||||||
	if len(num) == 0 {
 | 
					 | 
				
			||||||
		num = "0"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// handle a denominator
 | 
					 | 
				
			||||||
	if pos < end && str[pos] == '.' {
 | 
					 | 
				
			||||||
		pos++
 | 
					 | 
				
			||||||
	Denom:
 | 
					 | 
				
			||||||
		for i := pos; ; i++ {
 | 
					 | 
				
			||||||
			if i >= end {
 | 
					 | 
				
			||||||
				denom = str[pos:end]
 | 
					 | 
				
			||||||
				value = str[0:end]
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			switch str[i] {
 | 
					 | 
				
			||||||
			case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				denom = str[pos:i]
 | 
					 | 
				
			||||||
				pos = i
 | 
					 | 
				
			||||||
				break Denom
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// TODO: we currently allow 1.G, but we may not want to in the future.
 | 
					 | 
				
			||||||
		// if len(denom) == 0 {
 | 
					 | 
				
			||||||
		// 	err = ErrFormatWrong
 | 
					 | 
				
			||||||
		// 	return
 | 
					 | 
				
			||||||
		// }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	value = str[0:pos]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// grab the elements of the suffix
 | 
					 | 
				
			||||||
	suffixStart := pos
 | 
					 | 
				
			||||||
	for i := pos; ; i++ {
 | 
					 | 
				
			||||||
		if i >= end {
 | 
					 | 
				
			||||||
			suffix = str[suffixStart:end]
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if !strings.ContainsAny(str[i:i+1], "eEinumkKMGTP") {
 | 
					 | 
				
			||||||
			pos = i
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if pos < end {
 | 
					 | 
				
			||||||
		switch str[pos] {
 | 
					 | 
				
			||||||
		case '-', '+':
 | 
					 | 
				
			||||||
			pos++
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
Suffix:
 | 
					 | 
				
			||||||
	for i := pos; ; i++ {
 | 
					 | 
				
			||||||
		if i >= end {
 | 
					 | 
				
			||||||
			suffix = str[suffixStart:end]
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch str[i] {
 | 
					 | 
				
			||||||
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			break Suffix
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// we encountered a non decimal in the Suffix loop, but the last character
 | 
					 | 
				
			||||||
	// was not a valid exponent
 | 
					 | 
				
			||||||
	err = ErrFormatWrong
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ParseQuantity turns str into a Quantity, or returns an error.
 | 
					 | 
				
			||||||
func ParseQuantity(str string) (Quantity, error) {
 | 
					 | 
				
			||||||
	if len(str) == 0 {
 | 
					 | 
				
			||||||
		return Quantity{}, ErrFormatWrong
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if str == "0" {
 | 
					 | 
				
			||||||
		return Quantity{Format: DecimalSI, s: str}, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	positive, value, num, denom, suf, err := parseQuantityString(str)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return Quantity{}, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf))
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return Quantity{}, ErrSuffix
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	precision := int32(0)
 | 
					 | 
				
			||||||
	scale := int32(0)
 | 
					 | 
				
			||||||
	mantissa := int64(1)
 | 
					 | 
				
			||||||
	switch format {
 | 
					 | 
				
			||||||
	case DecimalExponent, DecimalSI:
 | 
					 | 
				
			||||||
		scale = exponent
 | 
					 | 
				
			||||||
		precision = maxInt64Factors - int32(len(num)+len(denom))
 | 
					 | 
				
			||||||
	case BinarySI:
 | 
					 | 
				
			||||||
		scale = 0
 | 
					 | 
				
			||||||
		switch {
 | 
					 | 
				
			||||||
		case exponent >= 0 && len(denom) == 0:
 | 
					 | 
				
			||||||
			// only handle positive binary numbers with the fast path
 | 
					 | 
				
			||||||
			mantissa = int64(int64(mantissa) << uint64(exponent))
 | 
					 | 
				
			||||||
			// 1Mi (2^20) has ~6 digits of decimal precision, so exponent*3/10 -1 is roughly the precision
 | 
					 | 
				
			||||||
			precision = 15 - int32(len(num)) - int32(float32(exponent)*3/10) - 1
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			precision = -1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if precision >= 0 {
 | 
					 | 
				
			||||||
		// if we have a denominator, shift the entire value to the left by the number of places in the
 | 
					 | 
				
			||||||
		// denominator
 | 
					 | 
				
			||||||
		scale -= int32(len(denom))
 | 
					 | 
				
			||||||
		if scale >= int32(Nano) {
 | 
					 | 
				
			||||||
			shifted := num + denom
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var value int64
 | 
					 | 
				
			||||||
			value, err := strconv.ParseInt(shifted, 10, 64)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return Quantity{}, ErrNumeric
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if result, ok := int64Multiply(value, int64(mantissa)); ok {
 | 
					 | 
				
			||||||
				if !positive {
 | 
					 | 
				
			||||||
					result = -result
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// if the number is in canonical form, reuse the string
 | 
					 | 
				
			||||||
				switch format {
 | 
					 | 
				
			||||||
				case BinarySI:
 | 
					 | 
				
			||||||
					if exponent%10 == 0 && (value&0x07 != 0) {
 | 
					 | 
				
			||||||
						return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				default:
 | 
					 | 
				
			||||||
					if scale%3 == 0 && !strings.HasSuffix(shifted, "000") && shifted[0] != '0' {
 | 
					 | 
				
			||||||
						return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	amount := new(inf.Dec)
 | 
					 | 
				
			||||||
	if _, ok := amount.SetString(value); !ok {
 | 
					 | 
				
			||||||
		return Quantity{}, ErrNumeric
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// So that no one but us has to think about suffixes, remove it.
 | 
					 | 
				
			||||||
	if base == 10 {
 | 
					 | 
				
			||||||
		amount.SetScale(amount.Scale() + Scale(exponent).infScale())
 | 
					 | 
				
			||||||
	} else if base == 2 {
 | 
					 | 
				
			||||||
		// numericSuffix = 2 ** exponent
 | 
					 | 
				
			||||||
		numericSuffix := big.NewInt(1).Lsh(bigOne, uint(exponent))
 | 
					 | 
				
			||||||
		ub := amount.UnscaledBig()
 | 
					 | 
				
			||||||
		amount.SetUnscaledBig(ub.Mul(ub, numericSuffix))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Cap at min/max bounds.
 | 
					 | 
				
			||||||
	sign := amount.Sign()
 | 
					 | 
				
			||||||
	if sign == -1 {
 | 
					 | 
				
			||||||
		amount.Neg(amount)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// This rounds non-zero values up to the minimum representable value, under the theory that
 | 
					 | 
				
			||||||
	// if you want some resources, you should get some resources, even if you asked for way too small
 | 
					 | 
				
			||||||
	// of an amount.  Arguably, this should be inf.RoundHalfUp (normal rounding), but that would have
 | 
					 | 
				
			||||||
	// the side effect of rounding values < .5n to zero.
 | 
					 | 
				
			||||||
	if v, ok := amount.Unscaled(); v != int64(0) || !ok {
 | 
					 | 
				
			||||||
		amount.Round(amount, Nano.infScale(), inf.RoundUp)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// The max is just a simple cap.
 | 
					 | 
				
			||||||
	// TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster
 | 
					 | 
				
			||||||
	if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 {
 | 
					 | 
				
			||||||
		amount.Set(maxAllowed.Dec)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
 | 
					 | 
				
			||||||
		// This avoids rounding and hopefully confusion, too.
 | 
					 | 
				
			||||||
		format = DecimalSI
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if sign == -1 {
 | 
					 | 
				
			||||||
		amount.Neg(amount)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return Quantity{d: infDecAmount{amount}, Format: format}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Note about BinarySI:
 | 
					 | 
				
			||||||
// * If q.Format is set to BinarySI and q.Amount represents a non-zero value between
 | 
					 | 
				
			||||||
//   -1 and +1, it will be emitted as if q.Format were DecimalSI.
 | 
					 | 
				
			||||||
// * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be
 | 
					 | 
				
			||||||
//   rounded up. (1.1i becomes 2i.)
 | 
					 | 
				
			||||||
func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
 | 
					 | 
				
			||||||
	if q.IsZero() {
 | 
					 | 
				
			||||||
		return zeroBytes, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var rounded CanonicalValue
 | 
					 | 
				
			||||||
	format := q.Format
 | 
					 | 
				
			||||||
	switch format {
 | 
					 | 
				
			||||||
	case DecimalExponent, DecimalSI:
 | 
					 | 
				
			||||||
	case BinarySI:
 | 
					 | 
				
			||||||
		if q.CmpInt64(-1024) > 0 && q.CmpInt64(1024) < 0 {
 | 
					 | 
				
			||||||
			// This avoids rounding and hopefully confusion, too.
 | 
					 | 
				
			||||||
			format = DecimalSI
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			var exact bool
 | 
					 | 
				
			||||||
			if rounded, exact = q.AsScale(0); !exact {
 | 
					 | 
				
			||||||
				// Don't lose precision-- show as DecimalSI
 | 
					 | 
				
			||||||
				format = DecimalSI
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		format = DecimalExponent
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO: If BinarySI formatting is requested but would cause rounding, upgrade to
 | 
					 | 
				
			||||||
	// one of the other formats.
 | 
					 | 
				
			||||||
	switch format {
 | 
					 | 
				
			||||||
	case DecimalExponent, DecimalSI:
 | 
					 | 
				
			||||||
		number, exponent := q.AsCanonicalBytes(out)
 | 
					 | 
				
			||||||
		suffix, _ := quantitySuffixer.constructBytes(10, exponent, format)
 | 
					 | 
				
			||||||
		return number, suffix
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		// format must be BinarySI
 | 
					 | 
				
			||||||
		number, exponent := rounded.AsCanonicalBase1024Bytes(out)
 | 
					 | 
				
			||||||
		suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format)
 | 
					 | 
				
			||||||
		return number, suffix
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsInt64 returns a representation of the current value as an int64 if a fast conversion
 | 
					 | 
				
			||||||
// is possible. If false is returned, callers must use the inf.Dec form of this quantity.
 | 
					 | 
				
			||||||
func (q *Quantity) AsInt64() (int64, bool) {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.AsInt64()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ToDec promotes the quantity in place to use an inf.Dec representation and returns itself.
 | 
					 | 
				
			||||||
func (q *Quantity) ToDec() *Quantity {
 | 
					 | 
				
			||||||
	if q.d.Dec == nil {
 | 
					 | 
				
			||||||
		q.d.Dec = q.i.AsDec()
 | 
					 | 
				
			||||||
		q.i = int64Amount{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsDec returns the quantity as represented by a scaled inf.Dec.
 | 
					 | 
				
			||||||
func (q *Quantity) AsDec() *inf.Dec {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.Dec
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	q.d.Dec = q.i.AsDec()
 | 
					 | 
				
			||||||
	q.i = int64Amount{}
 | 
					 | 
				
			||||||
	return q.d.Dec
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsCanonicalBytes returns the canonical byte representation of this quantity as a mantissa
 | 
					 | 
				
			||||||
// and base 10 exponent. The out byte slice may be passed to the method to avoid an extra
 | 
					 | 
				
			||||||
// allocation.
 | 
					 | 
				
			||||||
func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.AsCanonicalBytes(out)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.AsCanonicalBytes(out)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// IsZero returns true if the quantity is equal to zero.
 | 
					 | 
				
			||||||
func (q *Quantity) IsZero() bool {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.Dec.Sign() == 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.value == 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sign returns 0 if the quantity is zero, -1 if the quantity is less than zero, or 1 if the
 | 
					 | 
				
			||||||
// quantity is greater than zero.
 | 
					 | 
				
			||||||
func (q *Quantity) Sign() int {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.Dec.Sign()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.Sign()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AsScaled returns the current value, rounded up to the provided scale, and returns
 | 
					 | 
				
			||||||
// false if the scale resulted in a loss of precision.
 | 
					 | 
				
			||||||
func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.AsScale(scale)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.AsScale(scale)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RoundUp updates the quantity to the provided scale, ensuring that the value is at
 | 
					 | 
				
			||||||
// least 1. False is returned if the rounding operation resulted in a loss of precision.
 | 
					 | 
				
			||||||
// Negative numbers are rounded away from zero (-9 scale 1 rounds to -10).
 | 
					 | 
				
			||||||
func (q *Quantity) RoundUp(scale Scale) bool {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		q.s = ""
 | 
					 | 
				
			||||||
		d, exact := q.d.AsScale(scale)
 | 
					 | 
				
			||||||
		q.d = d
 | 
					 | 
				
			||||||
		return exact
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// avoid clearing the string value if we have already calculated it
 | 
					 | 
				
			||||||
	if q.i.scale >= scale {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	q.s = ""
 | 
					 | 
				
			||||||
	i, exact := q.i.AsScale(scale)
 | 
					 | 
				
			||||||
	q.i = i
 | 
					 | 
				
			||||||
	return exact
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Add adds the provide y quantity to the current value. If the current value is zero,
 | 
					 | 
				
			||||||
// the format of the quantity will be updated to the format of y.
 | 
					 | 
				
			||||||
func (q *Quantity) Add(y Quantity) {
 | 
					 | 
				
			||||||
	q.s = ""
 | 
					 | 
				
			||||||
	if q.d.Dec == nil && y.d.Dec == nil {
 | 
					 | 
				
			||||||
		if q.i.value == 0 {
 | 
					 | 
				
			||||||
			q.Format = y.Format
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if q.i.Add(y.i) {
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if q.IsZero() {
 | 
					 | 
				
			||||||
		q.Format = y.Format
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sub subtracts the provided quantity from the current value in place. If the current
 | 
					 | 
				
			||||||
// value is zero, the format of the quantity will be updated to the format of y.
 | 
					 | 
				
			||||||
func (q *Quantity) Sub(y Quantity) {
 | 
					 | 
				
			||||||
	q.s = ""
 | 
					 | 
				
			||||||
	if q.IsZero() {
 | 
					 | 
				
			||||||
		q.Format = y.Format
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if q.d.Dec == nil && y.d.Dec == nil && q.i.Sub(y.i) {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
 | 
					 | 
				
			||||||
// quantity is greater than y.
 | 
					 | 
				
			||||||
func (q *Quantity) Cmp(y Quantity) int {
 | 
					 | 
				
			||||||
	if q.d.Dec == nil && y.d.Dec == nil {
 | 
					 | 
				
			||||||
		return q.i.Cmp(y.i)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.AsDec().Cmp(y.AsDec())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CmpInt64 returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
 | 
					 | 
				
			||||||
// quantity is greater than y.
 | 
					 | 
				
			||||||
func (q *Quantity) CmpInt64(y int64) int {
 | 
					 | 
				
			||||||
	if q.d.Dec != nil {
 | 
					 | 
				
			||||||
		return q.d.Dec.Cmp(inf.NewDec(y, inf.Scale(0)))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.i.Cmp(int64Amount{value: y})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Neg sets quantity to be the negative value of itself.
 | 
					 | 
				
			||||||
func (q *Quantity) Neg() {
 | 
					 | 
				
			||||||
	q.s = ""
 | 
					 | 
				
			||||||
	if q.d.Dec == nil {
 | 
					 | 
				
			||||||
		q.i.value = -q.i.value
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	q.d.Dec.Neg(q.d.Dec)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation
 | 
					 | 
				
			||||||
// of most Quantity values.
 | 
					 | 
				
			||||||
const int64QuantityExpectedBytes = 18
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// String formats the Quantity as a string, caching the result if not calculated.
 | 
					 | 
				
			||||||
// String is an expensive operation and caching this result significantly reduces the cost of
 | 
					 | 
				
			||||||
// normal parse / marshal operations on Quantity.
 | 
					 | 
				
			||||||
func (q *Quantity) String() string {
 | 
					 | 
				
			||||||
	if len(q.s) == 0 {
 | 
					 | 
				
			||||||
		result := make([]byte, 0, int64QuantityExpectedBytes)
 | 
					 | 
				
			||||||
		number, suffix := q.CanonicalizeBytes(result)
 | 
					 | 
				
			||||||
		number = append(number, suffix...)
 | 
					 | 
				
			||||||
		q.s = string(number)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return q.s
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MarshalJSON implements the json.Marshaller interface.
 | 
					 | 
				
			||||||
func (q Quantity) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if len(q.s) > 0 {
 | 
					 | 
				
			||||||
		out := make([]byte, len(q.s)+2)
 | 
					 | 
				
			||||||
		out[0], out[len(out)-1] = '"', '"'
 | 
					 | 
				
			||||||
		copy(out[1:], q.s)
 | 
					 | 
				
			||||||
		return out, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes)
 | 
					 | 
				
			||||||
	result[0] = '"'
 | 
					 | 
				
			||||||
	number, suffix := q.CanonicalizeBytes(result[1:1])
 | 
					 | 
				
			||||||
	// if the same slice was returned to us that we passed in, avoid another allocation by copying number into
 | 
					 | 
				
			||||||
	// the source slice and returning that
 | 
					 | 
				
			||||||
	if len(number) > 0 && &number[0] == &result[1] && (len(number)+len(suffix)+2) <= int64QuantityExpectedBytes {
 | 
					 | 
				
			||||||
		number = append(number, suffix...)
 | 
					 | 
				
			||||||
		number = append(number, '"')
 | 
					 | 
				
			||||||
		return result[:1+len(number)], nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use
 | 
					 | 
				
			||||||
	// append
 | 
					 | 
				
			||||||
	result = result[:1]
 | 
					 | 
				
			||||||
	result = append(result, number...)
 | 
					 | 
				
			||||||
	result = append(result, suffix...)
 | 
					 | 
				
			||||||
	result = append(result, '"')
 | 
					 | 
				
			||||||
	return result, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON implements the json.Unmarshaller interface.
 | 
					 | 
				
			||||||
// TODO: Remove support for leading/trailing whitespace
 | 
					 | 
				
			||||||
func (q *Quantity) UnmarshalJSON(value []byte) error {
 | 
					 | 
				
			||||||
	l := len(value)
 | 
					 | 
				
			||||||
	if l == 4 && bytes.Equal(value, []byte("null")) {
 | 
					 | 
				
			||||||
		q.d.Dec = nil
 | 
					 | 
				
			||||||
		q.i = int64Amount{}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if l >= 2 && value[0] == '"' && value[l-1] == '"' {
 | 
					 | 
				
			||||||
		value = value[1 : l-1]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	parsed, err := ParseQuantity(strings.TrimSpace(string(value)))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// This copy is safe because parsed will not be referred to again.
 | 
					 | 
				
			||||||
	*q = parsed
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewQuantity returns a new Quantity representing the given
 | 
					 | 
				
			||||||
// value in the given format.
 | 
					 | 
				
			||||||
func NewQuantity(value int64, format Format) *Quantity {
 | 
					 | 
				
			||||||
	return &Quantity{
 | 
					 | 
				
			||||||
		i:      int64Amount{value: value},
 | 
					 | 
				
			||||||
		Format: format,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewMilliQuantity returns a new Quantity representing the given
 | 
					 | 
				
			||||||
// value * 1/1000 in the given format. Note that BinarySI formatting
 | 
					 | 
				
			||||||
// will round fractional values, and will be changed to DecimalSI for
 | 
					 | 
				
			||||||
// values x where (-1 < x < 1) && (x != 0).
 | 
					 | 
				
			||||||
func NewMilliQuantity(value int64, format Format) *Quantity {
 | 
					 | 
				
			||||||
	return &Quantity{
 | 
					 | 
				
			||||||
		i:      int64Amount{value: value, scale: -3},
 | 
					 | 
				
			||||||
		Format: format,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewScaledQuantity returns a new Quantity representing the given
 | 
					 | 
				
			||||||
// value * 10^scale in DecimalSI format.
 | 
					 | 
				
			||||||
func NewScaledQuantity(value int64, scale Scale) *Quantity {
 | 
					 | 
				
			||||||
	return &Quantity{
 | 
					 | 
				
			||||||
		i:      int64Amount{value: value, scale: scale},
 | 
					 | 
				
			||||||
		Format: DecimalSI,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Value returns the value of q; any fractional part will be lost.
 | 
					 | 
				
			||||||
func (q *Quantity) Value() int64 {
 | 
					 | 
				
			||||||
	return q.ScaledValue(0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MilliValue returns the value of ceil(q * 1000); this could overflow an int64;
 | 
					 | 
				
			||||||
// if that's a concern, call Value() first to verify the number is small enough.
 | 
					 | 
				
			||||||
func (q *Quantity) MilliValue() int64 {
 | 
					 | 
				
			||||||
	return q.ScaledValue(Milli)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
 | 
					 | 
				
			||||||
// To detect overflow, call Value() first and verify the expected magnitude.
 | 
					 | 
				
			||||||
func (q *Quantity) ScaledValue(scale Scale) int64 {
 | 
					 | 
				
			||||||
	if q.d.Dec == nil {
 | 
					 | 
				
			||||||
		i, _ := q.i.AsScaledInt64(scale)
 | 
					 | 
				
			||||||
		return i
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dec := q.d.Dec
 | 
					 | 
				
			||||||
	return scaledValue(dec.UnscaledBig(), int(dec.Scale()), int(scale.infScale()))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set sets q's value to be value.
 | 
					 | 
				
			||||||
func (q *Quantity) Set(value int64) {
 | 
					 | 
				
			||||||
	q.SetScaled(value, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetMilli sets q's value to be value * 1/1000.
 | 
					 | 
				
			||||||
func (q *Quantity) SetMilli(value int64) {
 | 
					 | 
				
			||||||
	q.SetScaled(value, Milli)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetScaled sets q's value to be value * 10^scale
 | 
					 | 
				
			||||||
func (q *Quantity) SetScaled(value int64, scale Scale) {
 | 
					 | 
				
			||||||
	q.s = ""
 | 
					 | 
				
			||||||
	q.d.Dec = nil
 | 
					 | 
				
			||||||
	q.i = int64Amount{value: value, scale: scale}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Copy is a convenience function that makes a deep copy for you. Non-deep
 | 
					 | 
				
			||||||
// copies of quantities share pointers and you will regret that.
 | 
					 | 
				
			||||||
func (q *Quantity) Copy() *Quantity {
 | 
					 | 
				
			||||||
	if q.d.Dec == nil {
 | 
					 | 
				
			||||||
		return &Quantity{
 | 
					 | 
				
			||||||
			s:      q.s,
 | 
					 | 
				
			||||||
			i:      q.i,
 | 
					 | 
				
			||||||
			Format: q.Format,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	tmp := &inf.Dec{}
 | 
					 | 
				
			||||||
	return &Quantity{
 | 
					 | 
				
			||||||
		s:      q.s,
 | 
					 | 
				
			||||||
		d:      infDecAmount{tmp.Set(q.d.Dec)},
 | 
					 | 
				
			||||||
		Format: q.Format,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// qFlag is a helper type for the Flag function
 | 
					 | 
				
			||||||
type qFlag struct {
 | 
					 | 
				
			||||||
	dest *Quantity
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Sets the value of the internal Quantity. (used by flag & pflag)
 | 
					 | 
				
			||||||
func (qf qFlag) Set(val string) error {
 | 
					 | 
				
			||||||
	q, err := ParseQuantity(val)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// This copy is OK because q will not be referenced again.
 | 
					 | 
				
			||||||
	*qf.dest = q
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Converts the value of the internal Quantity to a string. (used by flag & pflag)
 | 
					 | 
				
			||||||
func (qf qFlag) String() string {
 | 
					 | 
				
			||||||
	return qf.dest.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// States the type of flag this is (Quantity). (used by pflag)
 | 
					 | 
				
			||||||
func (qf qFlag) Type() string {
 | 
					 | 
				
			||||||
	return "quantity"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// QuantityFlag is a helper that makes a quantity flag (using standard flag package).
 | 
					 | 
				
			||||||
// Will panic if defaultValue is not a valid quantity.
 | 
					 | 
				
			||||||
func QuantityFlag(flagName, defaultValue, description string) *Quantity {
 | 
					 | 
				
			||||||
	q := MustParse(defaultValue)
 | 
					 | 
				
			||||||
	flag.Var(NewQuantityFlagValue(&q), flagName, description)
 | 
					 | 
				
			||||||
	return &q
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewQuantityFlagValue returns an object that can be used to back a flag,
 | 
					 | 
				
			||||||
// pointing at the given Quantity variable.
 | 
					 | 
				
			||||||
func NewQuantityFlagValue(q *Quantity) flag.Value {
 | 
					 | 
				
			||||||
	return qFlag{q}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										95
									
								
								vendor/github.com/appc/spec/schema/types/resource/scale_int.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/appc/spec/schema/types/resource/scale_int.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,95 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2015 The Kubernetes Authors All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package resource
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"math"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// A sync pool to reduce allocation.
 | 
					 | 
				
			||||||
	intPool  sync.Pool
 | 
					 | 
				
			||||||
	maxInt64 = big.NewInt(math.MaxInt64)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	intPool.New = func() interface{} {
 | 
					 | 
				
			||||||
		return &big.Int{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// scaledValue scales given unscaled value from scale to new Scale and returns
 | 
					 | 
				
			||||||
// an int64. It ALWAYS rounds up the result when scale down. The final result might
 | 
					 | 
				
			||||||
// overflow.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// scale, newScale represents the scale of the unscaled decimal.
 | 
					 | 
				
			||||||
// The mathematical value of the decimal is unscaled * 10**(-scale).
 | 
					 | 
				
			||||||
func scaledValue(unscaled *big.Int, scale, newScale int) int64 {
 | 
					 | 
				
			||||||
	dif := scale - newScale
 | 
					 | 
				
			||||||
	if dif == 0 {
 | 
					 | 
				
			||||||
		return unscaled.Int64()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Handle scale up
 | 
					 | 
				
			||||||
	// This is an easy case, we do not need to care about rounding and overflow.
 | 
					 | 
				
			||||||
	// If any intermediate operation causes overflow, the result will overflow.
 | 
					 | 
				
			||||||
	if dif < 0 {
 | 
					 | 
				
			||||||
		return unscaled.Int64() * int64(math.Pow10(-dif))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Handle scale down
 | 
					 | 
				
			||||||
	// We have to be careful about the intermediate operations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// fast path when unscaled < max.Int64 and exp(10,dif) < max.Int64
 | 
					 | 
				
			||||||
	const log10MaxInt64 = 19
 | 
					 | 
				
			||||||
	if unscaled.Cmp(maxInt64) < 0 && dif < log10MaxInt64 {
 | 
					 | 
				
			||||||
		divide := int64(math.Pow10(dif))
 | 
					 | 
				
			||||||
		result := unscaled.Int64() / divide
 | 
					 | 
				
			||||||
		mod := unscaled.Int64() % divide
 | 
					 | 
				
			||||||
		if mod != 0 {
 | 
					 | 
				
			||||||
			return result + 1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We should only convert back to int64 when getting the result.
 | 
					 | 
				
			||||||
	divisor := intPool.Get().(*big.Int)
 | 
					 | 
				
			||||||
	exp := intPool.Get().(*big.Int)
 | 
					 | 
				
			||||||
	result := intPool.Get().(*big.Int)
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		intPool.Put(divisor)
 | 
					 | 
				
			||||||
		intPool.Put(exp)
 | 
					 | 
				
			||||||
		intPool.Put(result)
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// divisor = 10^(dif)
 | 
					 | 
				
			||||||
	// TODO: create loop up table if exp costs too much.
 | 
					 | 
				
			||||||
	divisor.Exp(bigTen, exp.SetInt64(int64(dif)), nil)
 | 
					 | 
				
			||||||
	// reuse exp
 | 
					 | 
				
			||||||
	remainder := exp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// result = unscaled / divisor
 | 
					 | 
				
			||||||
	// remainder = unscaled % divisor
 | 
					 | 
				
			||||||
	result.DivMod(unscaled, divisor, remainder)
 | 
					 | 
				
			||||||
	if remainder.Sign() != 0 {
 | 
					 | 
				
			||||||
		return result.Int64() + 1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result.Int64()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										198
									
								
								vendor/github.com/appc/spec/schema/types/resource/suffix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										198
									
								
								vendor/github.com/appc/spec/schema/types/resource/suffix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,198 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2014 The Kubernetes Authors All rights reserved.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package resource
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type suffix string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// suffixer can interpret and construct suffixes.
 | 
					 | 
				
			||||||
type suffixer interface {
 | 
					 | 
				
			||||||
	interpret(suffix) (base, exponent int32, fmt Format, ok bool)
 | 
					 | 
				
			||||||
	construct(base, exponent int32, fmt Format) (s suffix, ok bool)
 | 
					 | 
				
			||||||
	constructBytes(base, exponent int32, fmt Format) (s []byte, ok bool)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// quantitySuffixer handles suffixes for all three formats that quantity
 | 
					 | 
				
			||||||
// can handle.
 | 
					 | 
				
			||||||
var quantitySuffixer = newSuffixer()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type bePair struct {
 | 
					 | 
				
			||||||
	base, exponent int32
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type listSuffixer struct {
 | 
					 | 
				
			||||||
	suffixToBE      map[suffix]bePair
 | 
					 | 
				
			||||||
	beToSuffix      map[bePair]suffix
 | 
					 | 
				
			||||||
	beToSuffixBytes map[bePair][]byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
 | 
					 | 
				
			||||||
	if ls.suffixToBE == nil {
 | 
					 | 
				
			||||||
		ls.suffixToBE = map[suffix]bePair{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ls.beToSuffix == nil {
 | 
					 | 
				
			||||||
		ls.beToSuffix = map[bePair]suffix{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ls.beToSuffixBytes == nil {
 | 
					 | 
				
			||||||
		ls.beToSuffixBytes = map[bePair][]byte{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ls.suffixToBE[s] = pair
 | 
					 | 
				
			||||||
	ls.beToSuffix[pair] = s
 | 
					 | 
				
			||||||
	ls.beToSuffixBytes[pair] = []byte(s)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok bool) {
 | 
					 | 
				
			||||||
	pair, ok := ls.suffixToBE[s]
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return 0, 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return pair.base, pair.exponent, true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok bool) {
 | 
					 | 
				
			||||||
	s, ok = ls.beToSuffix[bePair{base, exponent}]
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) {
 | 
					 | 
				
			||||||
	s, ok = ls.beToSuffixBytes[bePair{base, exponent}]
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type suffixHandler struct {
 | 
					 | 
				
			||||||
	decSuffixes listSuffixer
 | 
					 | 
				
			||||||
	binSuffixes listSuffixer
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type fastLookup struct {
 | 
					 | 
				
			||||||
	*suffixHandler
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l fastLookup) interpret(s suffix) (base, exponent int32, format Format, ok bool) {
 | 
					 | 
				
			||||||
	switch s {
 | 
					 | 
				
			||||||
	case "":
 | 
					 | 
				
			||||||
		return 10, 0, DecimalSI, true
 | 
					 | 
				
			||||||
	case "n":
 | 
					 | 
				
			||||||
		return 10, -9, DecimalSI, true
 | 
					 | 
				
			||||||
	case "u":
 | 
					 | 
				
			||||||
		return 10, -6, DecimalSI, true
 | 
					 | 
				
			||||||
	case "m":
 | 
					 | 
				
			||||||
		return 10, -3, DecimalSI, true
 | 
					 | 
				
			||||||
	case "k":
 | 
					 | 
				
			||||||
		return 10, 3, DecimalSI, true
 | 
					 | 
				
			||||||
	case "M":
 | 
					 | 
				
			||||||
		return 10, 6, DecimalSI, true
 | 
					 | 
				
			||||||
	case "G":
 | 
					 | 
				
			||||||
		return 10, 9, DecimalSI, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return l.suffixHandler.interpret(s)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newSuffixer() suffixer {
 | 
					 | 
				
			||||||
	sh := &suffixHandler{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// IMPORTANT: if you change this section you must change fastLookup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Ki", bePair{2, 10})
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Mi", bePair{2, 20})
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Gi", bePair{2, 30})
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Ti", bePair{2, 40})
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Pi", bePair{2, 50})
 | 
					 | 
				
			||||||
	sh.binSuffixes.addSuffix("Ei", bePair{2, 60})
 | 
					 | 
				
			||||||
	// Don't emit an error when trying to produce
 | 
					 | 
				
			||||||
	// a suffix for 2^0.
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("", bePair{2, 0})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("n", bePair{10, -9})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("u", bePair{10, -6})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("m", bePair{10, -3})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("", bePair{10, 0})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("k", bePair{10, 3})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("M", bePair{10, 6})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("G", bePair{10, 9})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("T", bePair{10, 12})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("P", bePair{10, 15})
 | 
					 | 
				
			||||||
	sh.decSuffixes.addSuffix("E", bePair{10, 18})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return fastLookup{sh}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (s suffix, ok bool) {
 | 
					 | 
				
			||||||
	switch fmt {
 | 
					 | 
				
			||||||
	case DecimalSI:
 | 
					 | 
				
			||||||
		return sh.decSuffixes.construct(base, exponent)
 | 
					 | 
				
			||||||
	case BinarySI:
 | 
					 | 
				
			||||||
		return sh.binSuffixes.construct(base, exponent)
 | 
					 | 
				
			||||||
	case DecimalExponent:
 | 
					 | 
				
			||||||
		if base != 10 {
 | 
					 | 
				
			||||||
			return "", false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if exponent == 0 {
 | 
					 | 
				
			||||||
			return "", true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return suffix("e" + strconv.FormatInt(int64(exponent), 10)), true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "", false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s []byte, ok bool) {
 | 
					 | 
				
			||||||
	switch format {
 | 
					 | 
				
			||||||
	case DecimalSI:
 | 
					 | 
				
			||||||
		return sh.decSuffixes.constructBytes(base, exponent)
 | 
					 | 
				
			||||||
	case BinarySI:
 | 
					 | 
				
			||||||
		return sh.binSuffixes.constructBytes(base, exponent)
 | 
					 | 
				
			||||||
	case DecimalExponent:
 | 
					 | 
				
			||||||
		if base != 10 {
 | 
					 | 
				
			||||||
			return nil, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if exponent == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		result := make([]byte, 8, 8)
 | 
					 | 
				
			||||||
		result[0] = 'e'
 | 
					 | 
				
			||||||
		number := strconv.AppendInt(result[1:1], int64(exponent), 10)
 | 
					 | 
				
			||||||
		if &result[1] == &number[0] {
 | 
					 | 
				
			||||||
			return result[:1+len(number)], true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		result = append(result[:1], number...)
 | 
					 | 
				
			||||||
		return result, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil, false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int32, fmt Format, ok bool) {
 | 
					 | 
				
			||||||
	// Try lookup tables first
 | 
					 | 
				
			||||||
	if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
 | 
					 | 
				
			||||||
		return b, e, DecimalSI, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if b, e, ok := sh.binSuffixes.lookup(suffix); ok {
 | 
					 | 
				
			||||||
		return b, e, BinarySI, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(suffix) > 1 && (suffix[0] == 'E' || suffix[0] == 'e') {
 | 
					 | 
				
			||||||
		parsed, err := strconv.ParseInt(string(suffix[1:]), 10, 64)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return 0, 0, DecimalExponent, false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return 10, int32(parsed), DecimalExponent, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0, 0, DecimalExponent, false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										91
									
								
								vendor/github.com/appc/spec/schema/types/semver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										91
									
								
								vendor/github.com/appc/spec/schema/types/semver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,91 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/coreos/go-semver/semver"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrNoZeroSemVer = ACVersionError("SemVer cannot be zero")
 | 
					 | 
				
			||||||
	ErrBadSemVer    = ACVersionError("SemVer is bad")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SemVer implements the Unmarshaler interface to define a field that must be
 | 
					 | 
				
			||||||
// a semantic version string
 | 
					 | 
				
			||||||
// TODO(jonboulle): extend upstream instead of wrapping?
 | 
					 | 
				
			||||||
type SemVer semver.Version
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewSemVer generates a new SemVer from a string. If the given string does
 | 
					 | 
				
			||||||
// not represent a valid SemVer, nil and an error are returned.
 | 
					 | 
				
			||||||
func NewSemVer(s string) (*SemVer, error) {
 | 
					 | 
				
			||||||
	nsv, err := semver.NewVersion(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, ErrBadSemVer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	v := SemVer(*nsv)
 | 
					 | 
				
			||||||
	if v.Empty() {
 | 
					 | 
				
			||||||
		return nil, ErrNoZeroSemVer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &v, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sv SemVer) LessThanMajor(versionB SemVer) bool {
 | 
					 | 
				
			||||||
	majorA := semver.Version(sv).Major
 | 
					 | 
				
			||||||
	majorB := semver.Version(versionB).Major
 | 
					 | 
				
			||||||
	if majorA < majorB {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sv SemVer) LessThanExact(versionB SemVer) bool {
 | 
					 | 
				
			||||||
	vA := semver.Version(sv)
 | 
					 | 
				
			||||||
	vB := semver.Version(versionB)
 | 
					 | 
				
			||||||
	return vA.LessThan(vB)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sv SemVer) String() string {
 | 
					 | 
				
			||||||
	s := semver.Version(sv)
 | 
					 | 
				
			||||||
	return s.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sv SemVer) Empty() bool {
 | 
					 | 
				
			||||||
	return semver.Version(sv) == semver.Version{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnmarshalJSON implements the json.Unmarshaler interface
 | 
					 | 
				
			||||||
func (sv *SemVer) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	v, err := NewSemVer(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*sv = *v
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// MarshalJSON implements the json.Marshaler interface
 | 
					 | 
				
			||||||
func (sv SemVer) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if sv.Empty() {
 | 
					 | 
				
			||||||
		return nil, ErrNoZeroSemVer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(sv.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										71
									
								
								vendor/github.com/appc/spec/schema/types/url.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/appc/spec/schema/types/url.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,71 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// URL wraps url.URL to marshal/unmarshal to/from JSON strings and enforce
 | 
					 | 
				
			||||||
// that the scheme is HTTP/HTTPS only
 | 
					 | 
				
			||||||
type URL url.URL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewURL(s string) (*URL, error) {
 | 
					 | 
				
			||||||
	uu, err := url.Parse(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("bad URL: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nu := URL(*uu)
 | 
					 | 
				
			||||||
	if err := nu.assertValidScheme(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &nu, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u URL) String() string {
 | 
					 | 
				
			||||||
	uu := url.URL(u)
 | 
					 | 
				
			||||||
	return uu.String()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u URL) assertValidScheme() error {
 | 
					 | 
				
			||||||
	switch u.Scheme {
 | 
					 | 
				
			||||||
	case "http", "https":
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return fmt.Errorf("bad URL scheme, must be http/https")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u *URL) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nu, err := NewURL(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*u = *nu
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u URL) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := u.assertValidScheme(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(u.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/user_annotations.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/user_annotations.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,18 +0,0 @@
 | 
				
			|||||||
// Copyright 2016 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UserAnnotations are arbitrary key-value pairs, to be supplied and interpreted by the user
 | 
					 | 
				
			||||||
type UserAnnotations map[string]string
 | 
					 | 
				
			||||||
							
								
								
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/user_labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/appc/spec/schema/types/user_labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,18 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UserLabels are arbitrary key-value pairs, to be supplied and interpreted by the user
 | 
					 | 
				
			||||||
type UserLabels map[string]string
 | 
					 | 
				
			||||||
							
								
								
									
										92
									
								
								vendor/github.com/appc/spec/schema/types/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/appc/spec/schema/types/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,92 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/hex"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"reflect"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrNoEmptyUUID = errors.New("UUID cannot be empty")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UUID encodes an RFC4122-compliant UUID, marshaled to/from a string
 | 
					 | 
				
			||||||
// TODO(jonboulle): vendor a package for this?
 | 
					 | 
				
			||||||
// TODO(jonboulle): consider more flexibility in input string formats.
 | 
					 | 
				
			||||||
// Right now, we only accept:
 | 
					 | 
				
			||||||
//   "6733C088-A507-4694-AABF-EDBE4FC5266F"
 | 
					 | 
				
			||||||
//   "6733C088A5074694AABFEDBE4FC5266F"
 | 
					 | 
				
			||||||
type UUID [16]byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u UUID) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:16])
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u *UUID) Set(s string) error {
 | 
					 | 
				
			||||||
	nu, err := NewUUID(s)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		*u = *nu
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewUUID generates a new UUID from the given string. If the string does not
 | 
					 | 
				
			||||||
// represent a valid UUID, nil and an error are returned.
 | 
					 | 
				
			||||||
func NewUUID(s string) (*UUID, error) {
 | 
					 | 
				
			||||||
	s = strings.Replace(s, "-", "", -1)
 | 
					 | 
				
			||||||
	if len(s) != 32 {
 | 
					 | 
				
			||||||
		return nil, errors.New("bad UUID length != 32")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dec, err := hex.DecodeString(s)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var u UUID
 | 
					 | 
				
			||||||
	for i, b := range dec {
 | 
					 | 
				
			||||||
		u[i] = b
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &u, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u UUID) Empty() bool {
 | 
					 | 
				
			||||||
	return reflect.DeepEqual(u, UUID{})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u *UUID) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var s string
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &s); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	uu, err := NewUUID(s)
 | 
					 | 
				
			||||||
	if uu.Empty() {
 | 
					 | 
				
			||||||
		return ErrNoEmptyUUID
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		*u = *uu
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (u UUID) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if u.Empty() {
 | 
					 | 
				
			||||||
		return nil, ErrNoEmptyUUID
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(u.String())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										249
									
								
								vendor/github.com/appc/spec/schema/types/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										249
									
								
								vendor/github.com/appc/spec/schema/types/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,249 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/common"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	emptyVolumeDefaultMode = "0755"
 | 
					 | 
				
			||||||
	emptyVolumeDefaultUID  = 0
 | 
					 | 
				
			||||||
	emptyVolumeDefaultGID  = 0
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Volume encapsulates a volume which should be mounted into the filesystem
 | 
					 | 
				
			||||||
// of all apps in a PodManifest
 | 
					 | 
				
			||||||
type Volume struct {
 | 
					 | 
				
			||||||
	Name ACName `json:"name"`
 | 
					 | 
				
			||||||
	Kind string `json:"kind"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// currently used only by "host"
 | 
					 | 
				
			||||||
	// TODO(jonboulle): factor out?
 | 
					 | 
				
			||||||
	Source    string `json:"source,omitempty"`
 | 
					 | 
				
			||||||
	ReadOnly  *bool  `json:"readOnly,omitempty"`
 | 
					 | 
				
			||||||
	Recursive *bool  `json:"recursive,omitempty"`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// currently used only by "empty"
 | 
					 | 
				
			||||||
	Mode *string `json:"mode,omitempty"`
 | 
					 | 
				
			||||||
	UID  *int    `json:"uid,omitempty"`
 | 
					 | 
				
			||||||
	GID  *int    `json:"gid,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type volume Volume
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v Volume) assertValid() error {
 | 
					 | 
				
			||||||
	if v.Name.Empty() {
 | 
					 | 
				
			||||||
		return errors.New("name must be set")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch v.Kind {
 | 
					 | 
				
			||||||
	case "empty":
 | 
					 | 
				
			||||||
		if v.Source != "" {
 | 
					 | 
				
			||||||
			return errors.New("source for empty volume must be empty")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.Mode == nil {
 | 
					 | 
				
			||||||
			return errors.New("mode for empty volume must be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.UID == nil {
 | 
					 | 
				
			||||||
			return errors.New("uid for empty volume must be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.GID == nil {
 | 
					 | 
				
			||||||
			return errors.New("gid for empty volume must be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	case "host":
 | 
					 | 
				
			||||||
		if v.Source == "" {
 | 
					 | 
				
			||||||
			return errors.New("source for host volume cannot be empty")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.Mode != nil {
 | 
					 | 
				
			||||||
			return errors.New("mode for host volume cannot be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.UID != nil {
 | 
					 | 
				
			||||||
			return errors.New("uid for host volume cannot be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if v.GID != nil {
 | 
					 | 
				
			||||||
			return errors.New("gid for host volume cannot be set")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if !filepath.IsAbs(v.Source) {
 | 
					 | 
				
			||||||
			return errors.New("source for host volume must be absolute path")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return errors.New(`unrecognized volume kind: should be one of "empty", "host"`)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v *Volume) UnmarshalJSON(data []byte) error {
 | 
					 | 
				
			||||||
	var vv volume
 | 
					 | 
				
			||||||
	if err := json.Unmarshal(data, &vv); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	nv := Volume(vv)
 | 
					 | 
				
			||||||
	maybeSetDefaults(&nv)
 | 
					 | 
				
			||||||
	if err := nv.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*v = nv
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v Volume) MarshalJSON() ([]byte, error) {
 | 
					 | 
				
			||||||
	if err := v.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return json.Marshal(volume(v))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v Volume) String() string {
 | 
					 | 
				
			||||||
	s := []string{
 | 
					 | 
				
			||||||
		v.Name.String(),
 | 
					 | 
				
			||||||
		",kind=",
 | 
					 | 
				
			||||||
		v.Kind,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if v.Source != "" {
 | 
					 | 
				
			||||||
		s = append(s, ",source=")
 | 
					 | 
				
			||||||
		s = append(s, v.Source)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if v.ReadOnly != nil {
 | 
					 | 
				
			||||||
		s = append(s, ",readOnly=")
 | 
					 | 
				
			||||||
		s = append(s, strconv.FormatBool(*v.ReadOnly))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if v.Recursive != nil {
 | 
					 | 
				
			||||||
		s = append(s, ",recursive=")
 | 
					 | 
				
			||||||
		s = append(s, strconv.FormatBool(*v.Recursive))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	switch v.Kind {
 | 
					 | 
				
			||||||
	case "empty":
 | 
					 | 
				
			||||||
		if *v.Mode != emptyVolumeDefaultMode {
 | 
					 | 
				
			||||||
			s = append(s, ",mode=")
 | 
					 | 
				
			||||||
			s = append(s, *v.Mode)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if *v.UID != emptyVolumeDefaultUID {
 | 
					 | 
				
			||||||
			s = append(s, ",uid=")
 | 
					 | 
				
			||||||
			s = append(s, strconv.Itoa(*v.UID))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if *v.GID != emptyVolumeDefaultGID {
 | 
					 | 
				
			||||||
			s = append(s, ",gid=")
 | 
					 | 
				
			||||||
			s = append(s, strconv.Itoa(*v.GID))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(s, "")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// VolumeFromString takes a command line volume parameter and returns a volume
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Example volume parameters:
 | 
					 | 
				
			||||||
// 	database,kind=host,source=/tmp,readOnly=true,recursive=true
 | 
					 | 
				
			||||||
func VolumeFromString(vp string) (*Volume, error) {
 | 
					 | 
				
			||||||
	vp = "name=" + vp
 | 
					 | 
				
			||||||
	vpQuery, err := common.MakeQueryString(vp)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	v, err := url.ParseQuery(vpQuery)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return VolumeFromParams(v)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func VolumeFromParams(params map[string][]string) (*Volume, error) {
 | 
					 | 
				
			||||||
	var vol Volume
 | 
					 | 
				
			||||||
	for key, val := range params {
 | 
					 | 
				
			||||||
		val := val
 | 
					 | 
				
			||||||
		if len(val) > 1 {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("label %s with multiple values %q", key, val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch key {
 | 
					 | 
				
			||||||
		case "name":
 | 
					 | 
				
			||||||
			acn, err := NewACName(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			vol.Name = *acn
 | 
					 | 
				
			||||||
		case "kind":
 | 
					 | 
				
			||||||
			vol.Kind = val[0]
 | 
					 | 
				
			||||||
		case "source":
 | 
					 | 
				
			||||||
			vol.Source = val[0]
 | 
					 | 
				
			||||||
		case "readOnly":
 | 
					 | 
				
			||||||
			ro, err := strconv.ParseBool(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			vol.ReadOnly = &ro
 | 
					 | 
				
			||||||
		case "recursive":
 | 
					 | 
				
			||||||
			rec, err := strconv.ParseBool(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			vol.Recursive = &rec
 | 
					 | 
				
			||||||
		case "mode":
 | 
					 | 
				
			||||||
			vol.Mode = &val[0]
 | 
					 | 
				
			||||||
		case "uid":
 | 
					 | 
				
			||||||
			u, err := strconv.Atoi(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			vol.UID = &u
 | 
					 | 
				
			||||||
		case "gid":
 | 
					 | 
				
			||||||
			g, err := strconv.Atoi(val[0])
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			vol.GID = &g
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("unknown volume parameter %q", key)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	maybeSetDefaults(&vol)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := vol.assertValid(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &vol, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// maybeSetDefaults sets the correct default values for certain fields on a
 | 
					 | 
				
			||||||
// Volume if they are not already been set. These fields are not
 | 
					 | 
				
			||||||
// pre-populated on all Volumes as the Volume type is polymorphic.
 | 
					 | 
				
			||||||
func maybeSetDefaults(vol *Volume) {
 | 
					 | 
				
			||||||
	if vol.Kind == "empty" {
 | 
					 | 
				
			||||||
		if vol.Mode == nil {
 | 
					 | 
				
			||||||
			m := emptyVolumeDefaultMode
 | 
					 | 
				
			||||||
			vol.Mode = &m
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if vol.UID == nil {
 | 
					 | 
				
			||||||
			u := emptyVolumeDefaultUID
 | 
					 | 
				
			||||||
			vol.UID = &u
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if vol.GID == nil {
 | 
					 | 
				
			||||||
			g := emptyVolumeDefaultGID
 | 
					 | 
				
			||||||
			vol.GID = &g
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										39
									
								
								vendor/github.com/appc/spec/schema/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/github.com/appc/spec/schema/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,39 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 The appc Authors
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// 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 schema
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/appc/spec/schema/types"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// version represents the canonical version of the appc spec and tooling.
 | 
					 | 
				
			||||||
	// For now, the schema and tooling is coupled with the spec itself, so
 | 
					 | 
				
			||||||
	// this must be kept in sync with the VERSION file in the root of the repo.
 | 
					 | 
				
			||||||
	version string = "0.8.9+git"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// AppContainerVersion is the SemVer representation of version
 | 
					 | 
				
			||||||
	AppContainerVersion types.SemVer
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	v, err := types.NewSemVer(version)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	AppContainerVersion = *v
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										27
									
								
								vendor/github.com/coreos/go-systemd/unit/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/coreos/go-systemd/unit/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,27 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = [
 | 
					 | 
				
			||||||
        "deserialize.go",
 | 
					 | 
				
			||||||
        "escape.go",
 | 
					 | 
				
			||||||
        "option.go",
 | 
					 | 
				
			||||||
        "serialize.go",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    importpath = "github.com/coreos/go-systemd/unit",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										276
									
								
								vendor/github.com/coreos/go-systemd/unit/deserialize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										276
									
								
								vendor/github.com/coreos/go-systemd/unit/deserialize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,276 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 CoreOS, Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
// you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
// You may obtain a copy of the License at
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
// limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package unit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"unicode"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// SYSTEMD_LINE_MAX mimics the maximum line length that systemd can use.
 | 
					 | 
				
			||||||
	// On typical systemd platforms (i.e. modern Linux), this will most
 | 
					 | 
				
			||||||
	// commonly be 2048, so let's use that as a sanity check.
 | 
					 | 
				
			||||||
	// Technically, we should probably pull this at runtime:
 | 
					 | 
				
			||||||
	//    SYSTEMD_LINE_MAX = int(C.sysconf(C.__SC_LINE_MAX))
 | 
					 | 
				
			||||||
	// but this would introduce an (unfortunate) dependency on cgo
 | 
					 | 
				
			||||||
	SYSTEMD_LINE_MAX = 2048
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// characters that systemd considers indicate a newline
 | 
					 | 
				
			||||||
	SYSTEMD_NEWLINE = "\r\n"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	ErrLineTooLong = fmt.Errorf("line too long (max %d bytes)", SYSTEMD_LINE_MAX)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Deserialize parses a systemd unit file into a list of UnitOption objects.
 | 
					 | 
				
			||||||
func Deserialize(f io.Reader) (opts []*UnitOption, err error) {
 | 
					 | 
				
			||||||
	lexer, optchan, errchan := newLexer(f)
 | 
					 | 
				
			||||||
	go lexer.lex()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for opt := range optchan {
 | 
					 | 
				
			||||||
		opts = append(opts, &(*opt))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = <-errchan
 | 
					 | 
				
			||||||
	return opts, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newLexer(f io.Reader) (*lexer, <-chan *UnitOption, <-chan error) {
 | 
					 | 
				
			||||||
	optchan := make(chan *UnitOption)
 | 
					 | 
				
			||||||
	errchan := make(chan error, 1)
 | 
					 | 
				
			||||||
	buf := bufio.NewReader(f)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &lexer{buf, optchan, errchan, ""}, optchan, errchan
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type lexer struct {
 | 
					 | 
				
			||||||
	buf     *bufio.Reader
 | 
					 | 
				
			||||||
	optchan chan *UnitOption
 | 
					 | 
				
			||||||
	errchan chan error
 | 
					 | 
				
			||||||
	section string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lex() {
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		close(l.optchan)
 | 
					 | 
				
			||||||
		close(l.errchan)
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	next := l.lexNextSection
 | 
					 | 
				
			||||||
	for next != nil {
 | 
					 | 
				
			||||||
		if l.buf.Buffered() >= SYSTEMD_LINE_MAX {
 | 
					 | 
				
			||||||
			// systemd truncates lines longer than LINE_MAX
 | 
					 | 
				
			||||||
			// https://bugs.freedesktop.org/show_bug.cgi?id=85308
 | 
					 | 
				
			||||||
			// Rather than allowing this to pass silently, let's
 | 
					 | 
				
			||||||
			// explicitly gate people from encountering this
 | 
					 | 
				
			||||||
			line, err := l.buf.Peek(SYSTEMD_LINE_MAX)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				l.errchan <- err
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if bytes.IndexAny(line, SYSTEMD_NEWLINE) == -1 {
 | 
					 | 
				
			||||||
				l.errchan <- ErrLineTooLong
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		next, err = next()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			l.errchan <- err
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type lexStep func() (lexStep, error)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexSectionName() (lexStep, error) {
 | 
					 | 
				
			||||||
	sec, err := l.buf.ReadBytes(']')
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, errors.New("unable to find end of section")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return l.lexSectionSuffixFunc(string(sec[:len(sec)-1])), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexSectionSuffixFunc(section string) lexStep {
 | 
					 | 
				
			||||||
	return func() (lexStep, error) {
 | 
					 | 
				
			||||||
		garbage, _, err := l.toEOL()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		garbage = bytes.TrimSpace(garbage)
 | 
					 | 
				
			||||||
		if len(garbage) > 0 {
 | 
					 | 
				
			||||||
			return nil, fmt.Errorf("found garbage after section name %s: %v", l.section, garbage)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return l.lexNextSectionOrOptionFunc(section), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) ignoreLineFunc(next lexStep) lexStep {
 | 
					 | 
				
			||||||
	return func() (lexStep, error) {
 | 
					 | 
				
			||||||
		for {
 | 
					 | 
				
			||||||
			line, _, err := l.toEOL()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			line = bytes.TrimSuffix(line, []byte{' '})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// lack of continuation means this line has been exhausted
 | 
					 | 
				
			||||||
			if !bytes.HasSuffix(line, []byte{'\\'}) {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// reached end of buffer, safe to exit
 | 
					 | 
				
			||||||
		return next, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexNextSection() (lexStep, error) {
 | 
					 | 
				
			||||||
	r, _, err := l.buf.ReadRune()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if err == io.EOF {
 | 
					 | 
				
			||||||
			err = nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if r == '[' {
 | 
					 | 
				
			||||||
		return l.lexSectionName, nil
 | 
					 | 
				
			||||||
	} else if isComment(r) {
 | 
					 | 
				
			||||||
		return l.ignoreLineFunc(l.lexNextSection), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return l.lexNextSection, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexNextSectionOrOptionFunc(section string) lexStep {
 | 
					 | 
				
			||||||
	return func() (lexStep, error) {
 | 
					 | 
				
			||||||
		r, _, err := l.buf.ReadRune()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			if err == io.EOF {
 | 
					 | 
				
			||||||
				err = nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if unicode.IsSpace(r) {
 | 
					 | 
				
			||||||
			return l.lexNextSectionOrOptionFunc(section), nil
 | 
					 | 
				
			||||||
		} else if r == '[' {
 | 
					 | 
				
			||||||
			return l.lexSectionName, nil
 | 
					 | 
				
			||||||
		} else if isComment(r) {
 | 
					 | 
				
			||||||
			return l.ignoreLineFunc(l.lexNextSectionOrOptionFunc(section)), nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		l.buf.UnreadRune()
 | 
					 | 
				
			||||||
		return l.lexOptionNameFunc(section), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexOptionNameFunc(section string) lexStep {
 | 
					 | 
				
			||||||
	return func() (lexStep, error) {
 | 
					 | 
				
			||||||
		var partial bytes.Buffer
 | 
					 | 
				
			||||||
		for {
 | 
					 | 
				
			||||||
			r, _, err := l.buf.ReadRune()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if r == '\n' || r == '\r' {
 | 
					 | 
				
			||||||
				return nil, errors.New("unexpected newline encountered while parsing option name")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if r == '=' {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			partial.WriteRune(r)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		name := strings.TrimSpace(partial.String())
 | 
					 | 
				
			||||||
		return l.lexOptionValueFunc(section, name, bytes.Buffer{}), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (l *lexer) lexOptionValueFunc(section, name string, partial bytes.Buffer) lexStep {
 | 
					 | 
				
			||||||
	return func() (lexStep, error) {
 | 
					 | 
				
			||||||
		for {
 | 
					 | 
				
			||||||
			line, eof, err := l.toEOL()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if len(bytes.TrimSpace(line)) == 0 {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			partial.Write(line)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// lack of continuation means this value has been exhausted
 | 
					 | 
				
			||||||
			idx := bytes.LastIndex(line, []byte{'\\'})
 | 
					 | 
				
			||||||
			if idx == -1 || idx != (len(line)-1) {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if !eof {
 | 
					 | 
				
			||||||
				partial.WriteRune('\n')
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return l.lexOptionValueFunc(section, name, partial), nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		val := partial.String()
 | 
					 | 
				
			||||||
		if strings.HasSuffix(val, "\n") {
 | 
					 | 
				
			||||||
			// A newline was added to the end, so the file didn't end with a backslash.
 | 
					 | 
				
			||||||
			// => Keep the newline
 | 
					 | 
				
			||||||
			val = strings.TrimSpace(val) + "\n"
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			val = strings.TrimSpace(val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		l.optchan <- &UnitOption{Section: section, Name: name, Value: val}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return l.lexNextSectionOrOptionFunc(section), nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// toEOL reads until the end-of-line or end-of-file.
 | 
					 | 
				
			||||||
// Returns (data, EOFfound, error)
 | 
					 | 
				
			||||||
func (l *lexer) toEOL() ([]byte, bool, error) {
 | 
					 | 
				
			||||||
	line, err := l.buf.ReadBytes('\n')
 | 
					 | 
				
			||||||
	// ignore EOF here since it's roughly equivalent to EOL
 | 
					 | 
				
			||||||
	if err != nil && err != io.EOF {
 | 
					 | 
				
			||||||
		return nil, false, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	line = bytes.TrimSuffix(line, []byte{'\r'})
 | 
					 | 
				
			||||||
	line = bytes.TrimSuffix(line, []byte{'\n'})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return line, err == io.EOF, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isComment(r rune) bool {
 | 
					 | 
				
			||||||
	return r == '#' || r == ';'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										116
									
								
								vendor/github.com/coreos/go-systemd/unit/escape.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/coreos/go-systemd/unit/escape.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,116 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 CoreOS, Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
// you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
// You may obtain a copy of the License at
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
// limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Implements systemd-escape [--unescape] [--path]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package unit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	allowed = `:_.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// If isPath is true:
 | 
					 | 
				
			||||||
//   We remove redundant '/'s, the leading '/', and trailing '/'.
 | 
					 | 
				
			||||||
//   If the result is empty, a '/' is inserted.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// We always:
 | 
					 | 
				
			||||||
//  Replace the following characters with `\x%x`:
 | 
					 | 
				
			||||||
//   Leading `.`
 | 
					 | 
				
			||||||
//   `-`, `\`, and anything not in this set: `:-_.\[0-9a-zA-Z]`
 | 
					 | 
				
			||||||
//  Replace '/' with '-'.
 | 
					 | 
				
			||||||
func escape(unescaped string, isPath bool) string {
 | 
					 | 
				
			||||||
	e := []byte{}
 | 
					 | 
				
			||||||
	inSlashes := false
 | 
					 | 
				
			||||||
	start := true
 | 
					 | 
				
			||||||
	for i := 0; i < len(unescaped); i++ {
 | 
					 | 
				
			||||||
		c := unescaped[i]
 | 
					 | 
				
			||||||
		if isPath {
 | 
					 | 
				
			||||||
			if c == '/' {
 | 
					 | 
				
			||||||
				inSlashes = true
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			} else if inSlashes {
 | 
					 | 
				
			||||||
				inSlashes = false
 | 
					 | 
				
			||||||
				if !start {
 | 
					 | 
				
			||||||
					e = append(e, '-')
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if c == '/' {
 | 
					 | 
				
			||||||
			e = append(e, '-')
 | 
					 | 
				
			||||||
		} else if start && c == '.' || strings.IndexByte(allowed, c) == -1 {
 | 
					 | 
				
			||||||
			e = append(e, []byte(fmt.Sprintf(`\x%x`, c))...)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			e = append(e, c)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		start = false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if isPath && len(e) == 0 {
 | 
					 | 
				
			||||||
		e = append(e, '-')
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return string(e)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// If isPath is true:
 | 
					 | 
				
			||||||
//   We always return a string beginning with '/'.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// We always:
 | 
					 | 
				
			||||||
//  Replace '-' with '/'.
 | 
					 | 
				
			||||||
//  Replace `\x%x` with the value represented in hex.
 | 
					 | 
				
			||||||
func unescape(escaped string, isPath bool) string {
 | 
					 | 
				
			||||||
	u := []byte{}
 | 
					 | 
				
			||||||
	for i := 0; i < len(escaped); i++ {
 | 
					 | 
				
			||||||
		c := escaped[i]
 | 
					 | 
				
			||||||
		if c == '-' {
 | 
					 | 
				
			||||||
			c = '/'
 | 
					 | 
				
			||||||
		} else if c == '\\' && len(escaped)-i >= 4 && escaped[i+1] == 'x' {
 | 
					 | 
				
			||||||
			n, err := strconv.ParseInt(escaped[i+2:i+4], 16, 8)
 | 
					 | 
				
			||||||
			if err == nil {
 | 
					 | 
				
			||||||
				c = byte(n)
 | 
					 | 
				
			||||||
				i += 3
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		u = append(u, c)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if isPath && (len(u) == 0 || u[0] != '/') {
 | 
					 | 
				
			||||||
		u = append([]byte("/"), u...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return string(u)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnitNameEscape escapes a string as `systemd-escape` would
 | 
					 | 
				
			||||||
func UnitNameEscape(unescaped string) string {
 | 
					 | 
				
			||||||
	return escape(unescaped, false)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnitNameUnescape unescapes a string as `systemd-escape --unescape` would
 | 
					 | 
				
			||||||
func UnitNameUnescape(escaped string) string {
 | 
					 | 
				
			||||||
	return unescape(escaped, false)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnitNamePathEscape escapes a string as `systemd-escape --path` would
 | 
					 | 
				
			||||||
func UnitNamePathEscape(unescaped string) string {
 | 
					 | 
				
			||||||
	return escape(unescaped, true)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UnitNamePathUnescape unescapes a string as `systemd-escape --path --unescape` would
 | 
					 | 
				
			||||||
func UnitNamePathUnescape(escaped string) string {
 | 
					 | 
				
			||||||
	return unescape(escaped, true)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										54
									
								
								vendor/github.com/coreos/go-systemd/unit/option.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/coreos/go-systemd/unit/option.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,54 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 CoreOS, Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
// you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
// You may obtain a copy of the License at
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
// limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package unit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type UnitOption struct {
 | 
					 | 
				
			||||||
	Section string
 | 
					 | 
				
			||||||
	Name    string
 | 
					 | 
				
			||||||
	Value   string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewUnitOption(section, name, value string) *UnitOption {
 | 
					 | 
				
			||||||
	return &UnitOption{Section: section, Name: name, Value: value}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (uo *UnitOption) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("{Section: %q, Name: %q, Value: %q}", uo.Section, uo.Name, uo.Value)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (uo *UnitOption) Match(other *UnitOption) bool {
 | 
					 | 
				
			||||||
	return uo.Section == other.Section &&
 | 
					 | 
				
			||||||
		uo.Name == other.Name &&
 | 
					 | 
				
			||||||
		uo.Value == other.Value
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func AllMatch(u1 []*UnitOption, u2 []*UnitOption) bool {
 | 
					 | 
				
			||||||
	length := len(u1)
 | 
					 | 
				
			||||||
	if length != len(u2) {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := 0; i < length; i++ {
 | 
					 | 
				
			||||||
		if !u1[i].Match(u2[i]) {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										75
									
								
								vendor/github.com/coreos/go-systemd/unit/serialize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/coreos/go-systemd/unit/serialize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,75 +0,0 @@
 | 
				
			|||||||
// Copyright 2015 CoreOS, Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
// you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
// You may obtain a copy of the License at
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
// limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package unit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Serialize encodes all of the given UnitOption objects into a
 | 
					 | 
				
			||||||
// unit file. When serialized the options are sorted in their
 | 
					 | 
				
			||||||
// supplied order but grouped by section.
 | 
					 | 
				
			||||||
func Serialize(opts []*UnitOption) io.Reader {
 | 
					 | 
				
			||||||
	var buf bytes.Buffer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(opts) == 0 {
 | 
					 | 
				
			||||||
		return &buf
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Index of sections -> ordered options
 | 
					 | 
				
			||||||
	idx := map[string][]*UnitOption{}
 | 
					 | 
				
			||||||
	// Separately preserve order in which sections were seen
 | 
					 | 
				
			||||||
	sections := []string{}
 | 
					 | 
				
			||||||
	for _, opt := range opts {
 | 
					 | 
				
			||||||
		sec := opt.Section
 | 
					 | 
				
			||||||
		if _, ok := idx[sec]; !ok {
 | 
					 | 
				
			||||||
			sections = append(sections, sec)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		idx[sec] = append(idx[sec], opt)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i, sect := range sections {
 | 
					 | 
				
			||||||
		writeSectionHeader(&buf, sect)
 | 
					 | 
				
			||||||
		writeNewline(&buf)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		opts := idx[sect]
 | 
					 | 
				
			||||||
		for _, opt := range opts {
 | 
					 | 
				
			||||||
			writeOption(&buf, opt)
 | 
					 | 
				
			||||||
			writeNewline(&buf)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if i < len(sections)-1 {
 | 
					 | 
				
			||||||
			writeNewline(&buf)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &buf
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeNewline(buf *bytes.Buffer) {
 | 
					 | 
				
			||||||
	buf.WriteRune('\n')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeSectionHeader(buf *bytes.Buffer, section string) {
 | 
					 | 
				
			||||||
	buf.WriteRune('[')
 | 
					 | 
				
			||||||
	buf.WriteString(section)
 | 
					 | 
				
			||||||
	buf.WriteRune(']')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeOption(buf *bytes.Buffer, opt *UnitOption) {
 | 
					 | 
				
			||||||
	buf.WriteString(opt.Name)
 | 
					 | 
				
			||||||
	buf.WriteRune('=')
 | 
					 | 
				
			||||||
	buf.WriteString(opt.Value)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								vendor/go4.org/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/go4.org/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
# This is the official list of go4 authors for copyright purposes.
 | 
					 | 
				
			||||||
# This is distinct from the CONTRIBUTORS file, which is the list of
 | 
					 | 
				
			||||||
# people who have contributed, even if they don't own the copyright on
 | 
					 | 
				
			||||||
# their work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
 | 
					 | 
				
			||||||
Daniel Theophanes <kardianos@gmail.com>
 | 
					 | 
				
			||||||
Google
 | 
					 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/go4.org/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										202
									
								
								vendor/go4.org/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,202 +0,0 @@
 | 
				
			|||||||
                                 Apache License
 | 
					 | 
				
			||||||
                           Version 2.0, January 2004
 | 
					 | 
				
			||||||
                        http://www.apache.org/licenses/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   1. Definitions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
					 | 
				
			||||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
					 | 
				
			||||||
      the copyright owner that is granting the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
					 | 
				
			||||||
      other entities that control, are controlled by, or are under common
 | 
					 | 
				
			||||||
      control with that entity. For the purposes of this definition,
 | 
					 | 
				
			||||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
					 | 
				
			||||||
      direction or management of such entity, whether by contract or
 | 
					 | 
				
			||||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
					 | 
				
			||||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
					 | 
				
			||||||
      exercising permissions granted by this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Source" form shall mean the preferred form for making modifications,
 | 
					 | 
				
			||||||
      including but not limited to software source code, documentation
 | 
					 | 
				
			||||||
      source, and configuration files.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Object" form shall mean any form resulting from mechanical
 | 
					 | 
				
			||||||
      transformation or translation of a Source form, including but
 | 
					 | 
				
			||||||
      not limited to compiled object code, generated documentation,
 | 
					 | 
				
			||||||
      and conversions to other media types.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
					 | 
				
			||||||
      Object form, made available under the License, as indicated by a
 | 
					 | 
				
			||||||
      copyright notice that is included in or attached to the work
 | 
					 | 
				
			||||||
      (an example is provided in the Appendix below).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
					 | 
				
			||||||
      form, that is based on (or derived from) the Work and for which the
 | 
					 | 
				
			||||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
					 | 
				
			||||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
					 | 
				
			||||||
      of this License, Derivative Works shall not include works that remain
 | 
					 | 
				
			||||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
					 | 
				
			||||||
      the Work and Derivative Works thereof.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Contribution" shall mean any work of authorship, including
 | 
					 | 
				
			||||||
      the original version of the Work and any modifications or additions
 | 
					 | 
				
			||||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
					 | 
				
			||||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
					 | 
				
			||||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
					 | 
				
			||||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
					 | 
				
			||||||
      means any form of electronic, verbal, or written communication sent
 | 
					 | 
				
			||||||
      to the Licensor or its representatives, including but not limited to
 | 
					 | 
				
			||||||
      communication on electronic mailing lists, source code control systems,
 | 
					 | 
				
			||||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
					 | 
				
			||||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
					 | 
				
			||||||
      excluding communication that is conspicuously marked or otherwise
 | 
					 | 
				
			||||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
					 | 
				
			||||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
					 | 
				
			||||||
      subsequently incorporated within the Work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
					 | 
				
			||||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
					 | 
				
			||||||
      Work and such Derivative Works in Source or Object form.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
					 | 
				
			||||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
					 | 
				
			||||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
					 | 
				
			||||||
      (except as stated in this section) patent license to make, have made,
 | 
					 | 
				
			||||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
					 | 
				
			||||||
      where such license applies only to those patent claims licensable
 | 
					 | 
				
			||||||
      by such Contributor that are necessarily infringed by their
 | 
					 | 
				
			||||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
					 | 
				
			||||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
					 | 
				
			||||||
      institute patent litigation against any entity (including a
 | 
					 | 
				
			||||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
					 | 
				
			||||||
      or a Contribution incorporated within the Work constitutes direct
 | 
					 | 
				
			||||||
      or contributory patent infringement, then any patent licenses
 | 
					 | 
				
			||||||
      granted to You under this License for that Work shall terminate
 | 
					 | 
				
			||||||
      as of the date such litigation is filed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
					 | 
				
			||||||
      Work or Derivative Works thereof in any medium, with or without
 | 
					 | 
				
			||||||
      modifications, and in Source or Object form, provided that You
 | 
					 | 
				
			||||||
      meet the following conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (a) You must give any other recipients of the Work or
 | 
					 | 
				
			||||||
          Derivative Works a copy of this License; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (b) You must cause any modified files to carry prominent notices
 | 
					 | 
				
			||||||
          stating that You changed the files; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
					 | 
				
			||||||
          that You distribute, all copyright, patent, trademark, and
 | 
					 | 
				
			||||||
          attribution notices from the Source form of the Work,
 | 
					 | 
				
			||||||
          excluding those notices that do not pertain to any part of
 | 
					 | 
				
			||||||
          the Derivative Works; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
					 | 
				
			||||||
          distribution, then any Derivative Works that You distribute must
 | 
					 | 
				
			||||||
          include a readable copy of the attribution notices contained
 | 
					 | 
				
			||||||
          within such NOTICE file, excluding those notices that do not
 | 
					 | 
				
			||||||
          pertain to any part of the Derivative Works, in at least one
 | 
					 | 
				
			||||||
          of the following places: within a NOTICE text file distributed
 | 
					 | 
				
			||||||
          as part of the Derivative Works; within the Source form or
 | 
					 | 
				
			||||||
          documentation, if provided along with the Derivative Works; or,
 | 
					 | 
				
			||||||
          within a display generated by the Derivative Works, if and
 | 
					 | 
				
			||||||
          wherever such third-party notices normally appear. The contents
 | 
					 | 
				
			||||||
          of the NOTICE file are for informational purposes only and
 | 
					 | 
				
			||||||
          do not modify the License. You may add Your own attribution
 | 
					 | 
				
			||||||
          notices within Derivative Works that You distribute, alongside
 | 
					 | 
				
			||||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
					 | 
				
			||||||
          that such additional attribution notices cannot be construed
 | 
					 | 
				
			||||||
          as modifying the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      You may add Your own copyright statement to Your modifications and
 | 
					 | 
				
			||||||
      may provide additional or different license terms and conditions
 | 
					 | 
				
			||||||
      for use, reproduction, or distribution of Your modifications, or
 | 
					 | 
				
			||||||
      for any such Derivative Works as a whole, provided Your use,
 | 
					 | 
				
			||||||
      reproduction, and distribution of the Work otherwise complies with
 | 
					 | 
				
			||||||
      the conditions stated in this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
					 | 
				
			||||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
					 | 
				
			||||||
      by You to the Licensor shall be under the terms and conditions of
 | 
					 | 
				
			||||||
      this License, without any additional terms or conditions.
 | 
					 | 
				
			||||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
					 | 
				
			||||||
      the terms of any separate license agreement you may have executed
 | 
					 | 
				
			||||||
      with Licensor regarding such Contributions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
					 | 
				
			||||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
					 | 
				
			||||||
      except as required for reasonable and customary use in describing the
 | 
					 | 
				
			||||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
					 | 
				
			||||||
      agreed to in writing, Licensor provides the Work (and each
 | 
					 | 
				
			||||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
					 | 
				
			||||||
      implied, including, without limitation, any warranties or conditions
 | 
					 | 
				
			||||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
					 | 
				
			||||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
					 | 
				
			||||||
      appropriateness of using or redistributing the Work and assume any
 | 
					 | 
				
			||||||
      risks associated with Your exercise of permissions under this License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
					 | 
				
			||||||
      whether in tort (including negligence), contract, or otherwise,
 | 
					 | 
				
			||||||
      unless required by applicable law (such as deliberate and grossly
 | 
					 | 
				
			||||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
					 | 
				
			||||||
      liable to You for damages, including any direct, indirect, special,
 | 
					 | 
				
			||||||
      incidental, or consequential damages of any character arising as a
 | 
					 | 
				
			||||||
      result of this License or out of the use or inability to use the
 | 
					 | 
				
			||||||
      Work (including but not limited to damages for loss of goodwill,
 | 
					 | 
				
			||||||
      work stoppage, computer failure or malfunction, or any and all
 | 
					 | 
				
			||||||
      other commercial damages or losses), even if such Contributor
 | 
					 | 
				
			||||||
      has been advised of the possibility of such damages.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
					 | 
				
			||||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
					 | 
				
			||||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
					 | 
				
			||||||
      or other liability obligations and/or rights consistent with this
 | 
					 | 
				
			||||||
      License. However, in accepting such obligations, You may act only
 | 
					 | 
				
			||||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
					 | 
				
			||||||
      of any other Contributor, and only if You agree to indemnify,
 | 
					 | 
				
			||||||
      defend, and hold each Contributor harmless for any liability
 | 
					 | 
				
			||||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
					 | 
				
			||||||
      of your accepting any such warranty or additional liability.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   END OF TERMS AND CONDITIONS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   APPENDIX: How to apply the Apache License to your work.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      To apply the Apache License to your work, attach the following
 | 
					 | 
				
			||||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
					 | 
				
			||||||
      replaced with your own identifying information. (Don't include
 | 
					 | 
				
			||||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
					 | 
				
			||||||
      comment syntax for the file format. We also recommend that a
 | 
					 | 
				
			||||||
      file or class name and description of purpose be included on the
 | 
					 | 
				
			||||||
      same "printed page" as the copyright notice for easier
 | 
					 | 
				
			||||||
      identification within third-party archives.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Copyright {yyyy} {name of copyright owner}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								vendor/go4.org/errorutil/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/go4.org/errorutil/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,22 +0,0 @@
 | 
				
			|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go_library(
 | 
					 | 
				
			||||||
    name = "go_default_library",
 | 
					 | 
				
			||||||
    srcs = ["highlight.go"],
 | 
					 | 
				
			||||||
    importpath = "go4.org/errorutil",
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "package-srcs",
 | 
					 | 
				
			||||||
    srcs = glob(["**"]),
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:private"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
filegroup(
 | 
					 | 
				
			||||||
    name = "all-srcs",
 | 
					 | 
				
			||||||
    srcs = [":package-srcs"],
 | 
					 | 
				
			||||||
    tags = ["automanaged"],
 | 
					 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
							
								
								
									
										58
									
								
								vendor/go4.org/errorutil/highlight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/go4.org/errorutil/highlight.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,58 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2011 Google Inc.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Package errorutil helps make better error messages.
 | 
					 | 
				
			||||||
package errorutil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HighlightBytePosition takes a reader and the location in bytes of a parse
 | 
					 | 
				
			||||||
// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
 | 
					 | 
				
			||||||
// and pretty-printed context around the error with an arrow indicating the exact
 | 
					 | 
				
			||||||
// position of the syntax error.
 | 
					 | 
				
			||||||
func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
 | 
					 | 
				
			||||||
	line = 1
 | 
					 | 
				
			||||||
	br := bufio.NewReader(f)
 | 
					 | 
				
			||||||
	lastLine := ""
 | 
					 | 
				
			||||||
	thisLine := new(bytes.Buffer)
 | 
					 | 
				
			||||||
	for n := int64(0); n < pos; n++ {
 | 
					 | 
				
			||||||
		b, err := br.ReadByte()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if b == '\n' {
 | 
					 | 
				
			||||||
			lastLine = thisLine.String()
 | 
					 | 
				
			||||||
			thisLine.Reset()
 | 
					 | 
				
			||||||
			line++
 | 
					 | 
				
			||||||
			col = 1
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			col++
 | 
					 | 
				
			||||||
			thisLine.WriteByte(b)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if line > 1 {
 | 
					 | 
				
			||||||
		highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
 | 
					 | 
				
			||||||
	highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user