forked from github/multus-cni
Compare commits
2 Commits
release-3.
...
v3.4
Author | SHA1 | Date | |
---|---|---|---|
|
ecc474a264 | ||
|
c7f957194b |
@@ -1,36 +1,15 @@
|
|||||||
# This dockerfile is specific to building Multus for OpenShift
|
# This dockerfile is specific to building Multus for OpenShift
|
||||||
FROM openshift/origin-release:rhel-8-golang-1.12 as rhel8
|
FROM openshift/origin-release:golang-1.10 as builder
|
||||||
ADD . /usr/src/multus-cni
|
|
||||||
WORKDIR /usr/src/multus-cni
|
|
||||||
ENV CGO_ENABLED=1
|
|
||||||
ENV GO111MODULE=off
|
|
||||||
ENV VERSION=rhel8 COMMIT=unset
|
|
||||||
RUN ./build && \
|
|
||||||
cd /usr/src/multus-cni/bin
|
|
||||||
WORKDIR /
|
|
||||||
|
|
||||||
FROM openshift/origin-release:rhel-7-golang-1.12 as rhel7
|
|
||||||
ADD . /usr/src/multus-cni
|
ADD . /usr/src/multus-cni
|
||||||
WORKDIR /usr/src/multus-cni
|
|
||||||
ENV CGO_ENABLED=1
|
|
||||||
ENV GO111MODULE=off
|
|
||||||
RUN ./build && \
|
|
||||||
cd /usr/src/multus-cni/bin
|
|
||||||
|
|
||||||
WORKDIR /usr/src/multus-cni
|
WORKDIR /usr/src/multus-cni
|
||||||
ENV GO111MODULE=off
|
ENV GO111MODULE=off
|
||||||
RUN ./build && \
|
RUN ./build
|
||||||
cd /usr/src/multus-cni/bin
|
|
||||||
WORKDIR /
|
|
||||||
|
|
||||||
FROM openshift/origin-base
|
FROM openshift/origin-base
|
||||||
RUN mkdir -p /usr/src/multus-cni/images && \
|
RUN mkdir -p /usr/src/multus-cni/images && mkdir -p /usr/src/multus-cni/bin
|
||||||
mkdir -p /usr/src/multus-cni/bin && \
|
COPY --from=builder /usr/src/multus-cni/bin/multus /usr/src/multus-cni/bin
|
||||||
mkdir -p /usr/src/multus-cni/rhel7/bin && \
|
|
||||||
mkdir -p /usr/src/multus-cni/rhel8/bin
|
|
||||||
COPY --from=rhel7 /usr/src/multus-cni/bin/multus /usr/src/multus-cni/rhel7/bin
|
|
||||||
COPY --from=rhel7 /usr/src/multus-cni/bin/multus /usr/src/multus-cni/bin
|
|
||||||
COPY --from=rhel8 /usr/src/multus-cni/bin/multus /usr/src/multus-cni/rhel8/bin
|
|
||||||
ADD ./images/entrypoint.sh /
|
ADD ./images/entrypoint.sh /
|
||||||
|
|
||||||
LABEL io.k8s.display-name="Multus CNI" \
|
LABEL io.k8s.display-name="Multus CNI" \
|
||||||
|
15
OWNERS
15
OWNERS
@@ -1,15 +0,0 @@
|
|||||||
reviewers:
|
|
||||||
- dougbtv
|
|
||||||
- dcbw
|
|
||||||
- squeed
|
|
||||||
- zshi
|
|
||||||
- fepan
|
|
||||||
- s1061123
|
|
||||||
approvers:
|
|
||||||
- dougbtv
|
|
||||||
- dcbw
|
|
||||||
- squeed
|
|
||||||
- zshi
|
|
||||||
- fepan
|
|
||||||
- s1061123
|
|
||||||
|
|
6
build
6
build
@@ -22,7 +22,7 @@ fi
|
|||||||
DATE=$(date --iso-8601=seconds)
|
DATE=$(date --iso-8601=seconds)
|
||||||
COMMIT=${COMMIT:-$(git rev-parse --verify HEAD)}
|
COMMIT=${COMMIT:-$(git rev-parse --verify HEAD)}
|
||||||
LDFLAGS="-X main.version=${VERSION:-master} -X main.commit=${COMMIT} -X main.date=${DATE}"
|
LDFLAGS="-X main.version=${VERSION:-master} -X main.commit=${COMMIT} -X main.date=${DATE}"
|
||||||
export CGO_ENABLED=1
|
export CGO_ENABLED=0
|
||||||
|
|
||||||
# this if... will be removed when gomodules goes default
|
# this if... will be removed when gomodules goes default
|
||||||
if [ "$GO111MODULE" == "off" ]; then
|
if [ "$GO111MODULE" == "off" ]; then
|
||||||
@@ -40,11 +40,11 @@ if [ "$GO111MODULE" == "off" ]; then
|
|||||||
export GO15VENDOREXPERIMENT=1
|
export GO15VENDOREXPERIMENT=1
|
||||||
export GOBIN=${PWD}/bin
|
export GOBIN=${PWD}/bin
|
||||||
export GOPATH=${PWD}/gopath
|
export GOPATH=${PWD}/gopath
|
||||||
go install -ldflags "${LDFLAGS}" "$@" ${REPO_PATH}/multus
|
go install -tags no_openssl -ldflags "${LDFLAGS}" "$@" ${REPO_PATH}/multus
|
||||||
else
|
else
|
||||||
# build with go modules
|
# build with go modules
|
||||||
export GO111MODULE=on
|
export GO111MODULE=on
|
||||||
|
|
||||||
echo "Building plugins"
|
echo "Building plugins"
|
||||||
go build -o ${DEST_DIR}/multus -ldflags "${LDFLAGS}" "$@" ./multus
|
go build -o ${DEST_DIR}/multus -tags no_openssl -ldflags "${LDFLAGS}" "$@" ./multus
|
||||||
fi
|
fi
|
||||||
|
@@ -1,95 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copyright (c) 2018 Intel Corporation
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
# create temp dir to store intermediate files
|
|
||||||
tmp=$(mktemp -d)
|
|
||||||
|
|
||||||
# generate private key
|
|
||||||
echo "Generating private RSA key..."
|
|
||||||
openssl genrsa -out ${tmp}/webhook-key.pem 2048 >/dev/null 2>&1
|
|
||||||
|
|
||||||
# generate CSR
|
|
||||||
echo "Generating CSR configuration file..."
|
|
||||||
cat <<EOF >> ${tmp}/webhook.conf
|
|
||||||
[req]
|
|
||||||
req_extensions = v3_req
|
|
||||||
distinguished_name = req_distinguished_name
|
|
||||||
[req_distinguished_name]
|
|
||||||
[ v3_req ]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
|
||||||
extendedKeyUsage = serverAuth
|
|
||||||
subjectAltName = @alt_names
|
|
||||||
[alt_names]
|
|
||||||
DNS.1 = multus-webhook-service
|
|
||||||
DNS.2 = multus-webhook-service.default
|
|
||||||
DNS.3 = multus-webhook-service.default.svc
|
|
||||||
EOF
|
|
||||||
openssl req -new -key ${tmp}/webhook-key.pem -subj "/CN=multus-webhook-service.default.svc" -out ${tmp}/server.csr -config ${tmp}/webhook.conf
|
|
||||||
|
|
||||||
# push CSR to Kubernetes API server
|
|
||||||
echo "Sending CSR to Kubernetes..."
|
|
||||||
csr_name="multus-webhook-service.default"
|
|
||||||
kubectl delete csr ${csr_name} >/dev/null 2>&1
|
|
||||||
cat <<EOF | kubectl create -f -
|
|
||||||
apiVersion: certificates.k8s.io/v1beta1
|
|
||||||
kind: CertificateSigningRequest
|
|
||||||
metadata:
|
|
||||||
name: ${csr_name}
|
|
||||||
spec:
|
|
||||||
request: $(cat ${tmp}/server.csr | base64 -w0)
|
|
||||||
groups:
|
|
||||||
- system:authenticated
|
|
||||||
usages:
|
|
||||||
- digital signature
|
|
||||||
- key encipherment
|
|
||||||
- server auth
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# approve certificate
|
|
||||||
echo "Approving CSR..."
|
|
||||||
kubectl certificate approve ${csr_name}
|
|
||||||
|
|
||||||
# wait for the cert to be issued
|
|
||||||
echo -n "Waiting for the certificate to be issued..."
|
|
||||||
cert=""
|
|
||||||
for sec in $(seq 15); do
|
|
||||||
cert=$(kubectl get csr ${csr_name} -o jsonpath='{.status.certificate}')
|
|
||||||
if [[ $cert != "" ]]; then
|
|
||||||
echo -e "\nCertificate issued succesfully."
|
|
||||||
echo $cert | base64 --decode > ${tmp}/webhook-cert.pem
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo -n "."; sleep 1
|
|
||||||
done
|
|
||||||
if [[ $cert == "" ]]; then
|
|
||||||
echo -e "\nError: certificate not issued. Verify that the API for signing certificates is enabled."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create secret
|
|
||||||
echo "Creating secret..."
|
|
||||||
kubectl delete secret "multus-webhook-secret"
|
|
||||||
kubectl create secret generic --from-file=key.pem=${tmp}/webhook-key.pem --from-file=cert.pem=${tmp}/webhook-cert.pem "multus-webhook-secret"
|
|
||||||
|
|
||||||
# set cert in webhook configuration
|
|
||||||
echo "Patching configuration file with certificate..."
|
|
||||||
if [[ -f configuration-template.yaml ]]; then
|
|
||||||
sed "s/__CERT__/${cert}/" configuration-template.yaml > configuration.yaml
|
|
||||||
echo "File configuration.yaml patched."
|
|
||||||
else
|
|
||||||
echo -e "Error: validating configuration template file 'configuration-template.yaml' is missing. Please update it with cert.pem value from the secret manually."
|
|
||||||
fi
|
|
@@ -1,38 +0,0 @@
|
|||||||
# Copyright (c) 2018 Intel Corporation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
apiVersion: admissionregistration.k8s.io/v1beta1
|
|
||||||
kind: ValidatingWebhookConfiguration
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: multus-webhook
|
|
||||||
name: multus-webhook-config
|
|
||||||
webhooks:
|
|
||||||
- clientConfig:
|
|
||||||
caBundle: __CERT__
|
|
||||||
service:
|
|
||||||
name: multus-webhook-service
|
|
||||||
namespace: default
|
|
||||||
path: /validate
|
|
||||||
failurePolicy: Fail
|
|
||||||
name: multus-webhook.k8s.cni.cncf.io
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- k8s.cni.cncf.io
|
|
||||||
apiVersions:
|
|
||||||
- v1
|
|
||||||
resources:
|
|
||||||
- network-attachment-definitions
|
|
||||||
operations:
|
|
||||||
- CREATE
|
|
@@ -1,50 +0,0 @@
|
|||||||
# Copyright (c) 2018 Intel Corporation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: multus-webhook
|
|
||||||
name: multus-webhook-deployment
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: multus-webhook
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: multus-webhook
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: multus-webhook
|
|
||||||
image: multus-webhook
|
|
||||||
command:
|
|
||||||
- /webhook/webhook
|
|
||||||
args:
|
|
||||||
- --bind-address=0.0.0.0
|
|
||||||
- --port=443
|
|
||||||
- --tls-private-key-file=/webhook/tls/key.pem
|
|
||||||
- --tls-cert-file=/webhook/tls/cert.pem
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /webhook/tls
|
|
||||||
name: multus-webhook-secret
|
|
||||||
readOnly: True
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
volumes:
|
|
||||||
- name: multus-webhook-secret
|
|
||||||
secret:
|
|
||||||
secretName: multus-webhook-secret
|
|
@@ -1,27 +0,0 @@
|
|||||||
# Copyright (c) 2018 Intel Corporation
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: multus-webhook-service
|
|
||||||
labels:
|
|
||||||
app: multus-webhook
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- port: 443
|
|
||||||
targetPort: 443
|
|
||||||
selector:
|
|
||||||
app: multus-webhook
|
|
@@ -619,7 +619,3 @@ When using `--multus-conf-file=auto` you may also care to specify a `binDir` in
|
|||||||
Sometimes, you may wish to not have the entrypoint copy the binary file onto the host. Potentially, you have another way to copy in a specific version of Multus, for example. By default, it's always copied, but you may disable the copy with:
|
Sometimes, you may wish to not have the entrypoint copy the binary file onto the host. Potentially, you have another way to copy in a specific version of Multus, for example. By default, it's always copied, but you may disable the copy with:
|
||||||
|
|
||||||
--skip-multus-binary-copy=true
|
--skip-multus-binary-copy=true
|
||||||
|
|
||||||
If you wish to have auto configuration use the `readinessindicatorfile` in the configuration, you can use the `--readiness-indicator-file` to express which file should be used as the readiness indicator.
|
|
||||||
|
|
||||||
--readiness-indicator-file=/path/to/file
|
|
||||||
|
@@ -1,112 +0,0 @@
|
|||||||
# Validating admission webhook
|
|
||||||
|
|
||||||
## Building Docker image
|
|
||||||
|
|
||||||
From the root directory of Multus execute:
|
|
||||||
```
|
|
||||||
cd webhook
|
|
||||||
./build
|
|
||||||
```
|
|
||||||
|
|
||||||
## Deploying webhook application
|
|
||||||
|
|
||||||
Change working directory. From the root directory of Multus execute:
|
|
||||||
```
|
|
||||||
cd deployment/webhook
|
|
||||||
```
|
|
||||||
|
|
||||||
Create key and certificate pair and patch configuration-template.yaml file with base64-encoded certificate file. Run:
|
|
||||||
```
|
|
||||||
./certs.sh
|
|
||||||
```
|
|
||||||
*Note: Verify that Kubernetes controller manager has --cluster-signing-cert-file and --cluster-signing-key-file parameters set to paths to your CA keypair,
|
|
||||||
to make sure that Certificates API is enabled in order to generate certificate signed by cluster CA.
|
|
||||||
Script generates private key and certificate signing request, which is then pushed to the Kubernetes API server.
|
|
||||||
Then script approves that CSR and API server issues the certificate. Certificate is obtained from the API server and used to create a secret.
|
|
||||||
Script also patches `configuration-template.yaml` file with base64-encoded certificate and creates `configuration.yaml` file containing
|
|
||||||
Validating Webhook Configuration specification, which is deployed in one of the next steps.
|
|
||||||
More details about TLS certificates management in a cluster available [here](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/).*
|
|
||||||
|
|
||||||
Create service:
|
|
||||||
```
|
|
||||||
kubectl create -f service.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Run deployment:
|
|
||||||
```
|
|
||||||
kubectl create -f deployment.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
Create Validating Webhook Configuration:
|
|
||||||
```
|
|
||||||
kubectl create -f configuration.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verifying installation
|
|
||||||
|
|
||||||
Try to create invalid Network Attachment Definition resource:
|
|
||||||
```
|
|
||||||
cat <<EOF | kubectl create -f -
|
|
||||||
apiVersion: "k8s.cni.cncf.io/v1"
|
|
||||||
kind: NetworkAttachmentDefinition
|
|
||||||
metadata:
|
|
||||||
name: invalid-net-attach-def
|
|
||||||
spec:
|
|
||||||
config: '{
|
|
||||||
"invalid": "config"
|
|
||||||
}'
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
Webhook should deny the request:
|
|
||||||
```
|
|
||||||
Error from server: error when creating "STDIN": admission webhook "multus-webhook.k8s.cni.cncf.io" denied the request: Invalid network config spec
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, try to create correctly defined one:
|
|
||||||
```
|
|
||||||
cat <<EOF | kubectl create -f -
|
|
||||||
apiVersion: "k8s.cni.cncf.io/v1"
|
|
||||||
kind: NetworkAttachmentDefinition
|
|
||||||
metadata:
|
|
||||||
name: correct-net-attach-def
|
|
||||||
spec:
|
|
||||||
config: '{
|
|
||||||
"cniVersion": "0.3.0",
|
|
||||||
"name": "a-bridge-network",
|
|
||||||
"type": "bridge",
|
|
||||||
"bridge": "br0",
|
|
||||||
"isGateway": true,
|
|
||||||
"ipam": {
|
|
||||||
"type": "host-local",
|
|
||||||
"subnet": "192.168.5.0/24",
|
|
||||||
"dataDir": "/mnt/cluster-ipam"
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
Resource should be allowed and created:
|
|
||||||
```
|
|
||||||
networkattachmentdefinition.k8s.cni.cncf.io/correct-net-attach-def created
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
Webhook server prints a lot of debug messages that could help to find the root cause of an issue.
|
|
||||||
To display logs run:
|
|
||||||
```
|
|
||||||
kubectl logs -l app=multus-webhook
|
|
||||||
```
|
|
||||||
Example output showing logs for handling requests generated in the "Verifying installation section":
|
|
||||||
```
|
|
||||||
# kubectl logs multus-webhook-pod
|
|
||||||
2018-08-22T13:33:09Z [debug] Starting Multus webhook server
|
|
||||||
2018-08-22T13:33:32Z [debug] Validating network config spec: { "invalid": "config" }
|
|
||||||
2018-08-22T13:33:32Z [debug] Spec is not a valid network config: error parsing configuration list: no name. Trying to parse into config list
|
|
||||||
2018-08-22T13:33:32Z [debug] Spec is not a valid network config list: error parsing configuration: missing 'type'
|
|
||||||
2018-08-22T13:33:32Z [error] Invalid config: error parsing configuration: missing 'type'
|
|
||||||
2018-08-22T13:33:32Z [debug] Sending response to the API server
|
|
||||||
2018-08-22T13:35:29Z [debug] Validating network config spec: { "cniVersion": "0.3.0", "name": "a-bridge-network", "type": "bridge", "bridge": "br0", "isGateway": true, "ipam": { "type": "host-local", "subnet": "192.168.5.0/24", "dataDir": "/mnt/cluster-ipam" } }
|
|
||||||
2018-08-22T13:35:29Z [debug] Spec is not a valid network config: error parsing configuration list: no 'plugins' key. Trying to parse into config list
|
|
||||||
2018-08-22T13:35:29Z [debug] Network Attachment Defintion is valid. Admission Review request allowed
|
|
||||||
2018-08-22T13:35:29Z [debug] Sending response to the API server
|
|
||||||
```
|
|
||||||
|
|
@@ -3,6 +3,20 @@
|
|||||||
# Always exit on errors.
|
# Always exit on errors.
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# Run a clean up when we exit if configured to do so.
|
||||||
|
trap cleanup TERM
|
||||||
|
function cleanup {
|
||||||
|
if [ "$MULTUS_CLEANUP_CONFIG_ON_EXIT" == "true" ]; then
|
||||||
|
CONF=$(cat <<-EOF
|
||||||
|
{Multus configuration intentionally invalidated to prevent pods from being scheduled.}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
echo $CONF > $CNI_CONF_DIR/00-multus.conf
|
||||||
|
log "Multus configuration intentionally invalidated to prevent pods from being scheduled."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Set our known directories.
|
# Set our known directories.
|
||||||
CNI_CONF_DIR="/host/etc/cni/net.d"
|
CNI_CONF_DIR="/host/etc/cni/net.d"
|
||||||
CNI_BIN_DIR="/host/opt/cni/bin"
|
CNI_BIN_DIR="/host/opt/cni/bin"
|
||||||
@@ -14,7 +28,6 @@ MULTUS_KUBECONFIG_FILE_HOST="/etc/cni/net.d/multus.d/multus.kubeconfig"
|
|||||||
MULTUS_NAMESPACE_ISOLATION=false
|
MULTUS_NAMESPACE_ISOLATION=false
|
||||||
MULTUS_LOG_LEVEL=""
|
MULTUS_LOG_LEVEL=""
|
||||||
MULTUS_LOG_FILE=""
|
MULTUS_LOG_FILE=""
|
||||||
MULTUS_READINESS_INDICATOR_FILE=""
|
|
||||||
OVERRIDE_NETWORK_NAME=false
|
OVERRIDE_NETWORK_NAME=false
|
||||||
MULTUS_CLEANUP_CONFIG_ON_EXIT=false
|
MULTUS_CLEANUP_CONFIG_ON_EXIT=false
|
||||||
RESTART_CRIO=false
|
RESTART_CRIO=false
|
||||||
@@ -48,7 +61,6 @@ function usage()
|
|||||||
echo -e "\t--override-network-name=false (used only with --multus-conf-file=auto)"
|
echo -e "\t--override-network-name=false (used only with --multus-conf-file=auto)"
|
||||||
echo -e "\t--cleanup-config-on-exit=false (used only with --multus-conf-file=auto)"
|
echo -e "\t--cleanup-config-on-exit=false (used only with --multus-conf-file=auto)"
|
||||||
echo -e "\t--rename-conf-file=false (used only with --multus-conf-file=auto)"
|
echo -e "\t--rename-conf-file=false (used only with --multus-conf-file=auto)"
|
||||||
echo -e "\t--readiness-indicator-file=$MULTUS_READINESS_INDICATOR_FILE (used only with --multus-conf-file=auto)"
|
|
||||||
echo -e "\t--additional-bin-dir=$ADDITIONAL_BIN_DIR (adds binDir option to configuration, used only with --multus-conf-file=auto)"
|
echo -e "\t--additional-bin-dir=$ADDITIONAL_BIN_DIR (adds binDir option to configuration, used only with --multus-conf-file=auto)"
|
||||||
echo -e "\t--restart-crio=false (restarts CRIO after config file is generated)"
|
echo -e "\t--restart-crio=false (restarts CRIO after config file is generated)"
|
||||||
}
|
}
|
||||||
@@ -125,9 +137,6 @@ while [ "$1" != "" ]; do
|
|||||||
--skip-multus-binary-copy)
|
--skip-multus-binary-copy)
|
||||||
SKIP_BINARY_COPY=$VALUE
|
SKIP_BINARY_COPY=$VALUE
|
||||||
;;
|
;;
|
||||||
--readiness-indicator-file)
|
|
||||||
MULTUS_READINESS_INDICATOR_FILE=$VALUE
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
warn "unknown parameter \"$PARAM\""
|
warn "unknown parameter \"$PARAM\""
|
||||||
;;
|
;;
|
||||||
@@ -241,6 +250,13 @@ if [ "$MULTUS_CONF_FILE" == "auto" ]; then
|
|||||||
log "Attemping to find master plugin configuration, attempt $tries"
|
log "Attemping to find master plugin configuration, attempt $tries"
|
||||||
fi
|
fi
|
||||||
let "tries+=1"
|
let "tries+=1"
|
||||||
|
# See if the Multus configuration file exists, if it does then clean it up.
|
||||||
|
if [ "$MULTUS_CLEANUP_CONFIG_ON_EXIT" == true ] && [ -f "$CNI_CONF_DIR/00-multus.conf" ]; then
|
||||||
|
# But first, check if it has the invalidated configuration in it (otherwise we keep doing this over and over.)
|
||||||
|
if ! grep -q "invalidated" $CNI_CONF_DIR/00-multus.conf; then
|
||||||
|
cleanup
|
||||||
|
fi
|
||||||
|
fi
|
||||||
sleep 1;
|
sleep 1;
|
||||||
else
|
else
|
||||||
error "Multus could not be configured: no master plugin was found."
|
error "Multus could not be configured: no master plugin was found."
|
||||||
@@ -289,12 +305,6 @@ if [ "$MULTUS_CONF_FILE" == "auto" ]; then
|
|||||||
ADDITIONAL_BIN_DIR_STRING="\"binDir\": \"$ADDITIONAL_BIN_DIR\","
|
ADDITIONAL_BIN_DIR_STRING="\"binDir\": \"$ADDITIONAL_BIN_DIR\","
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
READINESS_INDICATOR_FILE_STRING=""
|
|
||||||
if [ ! -z "${MULTUS_READINESS_INDICATOR_FILE// }" ]; then
|
|
||||||
READINESS_INDICATOR_FILE_STRING="\"readinessindicatorfile\": \"$MULTUS_READINESS_INDICATOR_FILE\","
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OVERRIDE_NETWORK_NAME" == "true" ]; then
|
if [ "$OVERRIDE_NETWORK_NAME" == "true" ]; then
|
||||||
MASTER_PLUGIN_NET_NAME="$(cat $MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN | \
|
MASTER_PLUGIN_NET_NAME="$(cat $MULTUS_AUTOCONF_DIR/$MASTER_PLUGIN | \
|
||||||
python -c 'import json,sys;print json.load(sys.stdin)["name"]')"
|
python -c 'import json,sys;print json.load(sys.stdin)["name"]')"
|
||||||
@@ -314,7 +324,6 @@ if [ "$MULTUS_CONF_FILE" == "auto" ]; then
|
|||||||
$LOG_LEVEL_STRING
|
$LOG_LEVEL_STRING
|
||||||
$LOG_FILE_STRING
|
$LOG_FILE_STRING
|
||||||
$ADDITIONAL_BIN_DIR_STRING
|
$ADDITIONAL_BIN_DIR_STRING
|
||||||
$READINESS_INDICATOR_FILE_STRING
|
|
||||||
"kubeconfig": "$MULTUS_KUBECONFIG_FILE_HOST",
|
"kubeconfig": "$MULTUS_KUBECONFIG_FILE_HOST",
|
||||||
"delegates": [
|
"delegates": [
|
||||||
$MASTER_PLUGIN_JSON
|
$MASTER_PLUGIN_JSON
|
||||||
@@ -354,17 +363,8 @@ if [ "$MULTUS_CLEANUP_CONFIG_ON_EXIT" == true ]; then
|
|||||||
while true; do
|
while true; do
|
||||||
# Check and see if the original master plugin configuration exists...
|
# Check and see if the original master plugin configuration exists...
|
||||||
if [ ! -f "$MASTER_PLUGIN_LOCATION" ]; then
|
if [ ! -f "$MASTER_PLUGIN_LOCATION" ]; then
|
||||||
log "Master plugin @ $MASTER_PLUGIN_LOCATION has been deleted. Allowing 45 seconds for its restoration..."
|
log "Master plugin @ $MASTER_PLUGIN_LOCATION has been deleted. Performing cleanup..."
|
||||||
sleep 10
|
cleanup
|
||||||
for i in {1..35}
|
|
||||||
do
|
|
||||||
if [ -f "$MASTER_PLUGIN_LOCATION" ]; then
|
|
||||||
log "Master plugin @ $MASTER_PLUGIN_LOCATION was restored. Regenerating given configuration."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
generateMultusConf
|
generateMultusConf
|
||||||
log "Continuing watch loop after configuration regeneration..."
|
log "Continuing watch loop after configuration regeneration..."
|
||||||
fi
|
fi
|
||||||
|
@@ -48,8 +48,12 @@ var version = "master@git"
|
|||||||
var commit = "unknown commit"
|
var commit = "unknown commit"
|
||||||
var date = "unknown date"
|
var date = "unknown date"
|
||||||
|
|
||||||
var pollDuration = 1000 * time.Millisecond
|
var defaultReadinessBackoff = wait.Backoff{
|
||||||
var pollTimeout = 45 * time.Second
|
Steps: 4,
|
||||||
|
Duration: 250 * time.Millisecond,
|
||||||
|
Factor: 4.0,
|
||||||
|
Jitter: 0.1,
|
||||||
|
}
|
||||||
|
|
||||||
func printVersionString() string {
|
func printVersionString() string {
|
||||||
return fmt.Sprintf("multus-cni version:%s, commit:%s, date:%s",
|
return fmt.Sprintf("multus-cni version:%s, commit:%s, date:%s",
|
||||||
@@ -375,15 +379,15 @@ func cmdAdd(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) (cn
|
|||||||
return nil, cmdErr(nil, "error getting k8s args: %v", err)
|
return nil, cmdErr(nil, "error getting k8s args: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.ReadinessIndicatorFile != "" {
|
wait.ExponentialBackoff(defaultReadinessBackoff, func() (bool, error) {
|
||||||
err := wait.PollImmediate(pollDuration, pollTimeout, func() (bool, error) {
|
_, err := os.Stat(n.ReadinessIndicatorFile)
|
||||||
_, err := os.Stat(n.ReadinessIndicatorFile)
|
switch {
|
||||||
return err == nil, nil
|
case err == nil:
|
||||||
})
|
return true, nil
|
||||||
if err != nil {
|
default:
|
||||||
return nil, cmdErr(k8sArgs, "PollImmediate error waiting for ReadinessIndicatorFile: %v", err)
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
if n.ClusterNetwork != "" {
|
if n.ClusterNetwork != "" {
|
||||||
err = k8s.GetDefaultNetworks(k8sArgs, n, kubeClient)
|
err = k8s.GetDefaultNetworks(k8sArgs, n, kubeClient)
|
||||||
@@ -528,16 +532,6 @@ func cmdDel(args *skel.CmdArgs, exec invoke.Exec, kubeClient k8s.KubeClient) err
|
|||||||
return cmdErr(nil, "error getting k8s args: %v", err)
|
return cmdErr(nil, "error getting k8s args: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.ReadinessIndicatorFile != "" {
|
|
||||||
err := wait.PollImmediate(pollDuration, pollTimeout, func() (bool, error) {
|
|
||||||
_, err := os.Stat(in.ReadinessIndicatorFile)
|
|
||||||
return err == nil, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return cmdErr(k8sArgs, "PollImmediate error waiting for ReadinessIndicatorFile (on del): %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the cache to get delegates json for the pod
|
// Read the cache to get delegates json for the pod
|
||||||
netconfBytes, path, err := consumeScratchNetConf(args.ContainerID, in.CNIDir)
|
netconfBytes, path, err := consumeScratchNetConf(args.ContainerID, in.CNIDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
61
vendor/golang.org/x/sys/unix/mkasm_darwin.go
generated
vendored
61
vendor/golang.org/x/sys/unix/mkasm_darwin.go
generated
vendored
@@ -1,61 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
|
|
||||||
//This program must be run after mksyscall.go.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
in1, err := ioutil.ReadFile("syscall_darwin.go")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open syscall_darwin.go: %s", err)
|
|
||||||
}
|
|
||||||
arch := os.Args[1]
|
|
||||||
in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
|
|
||||||
}
|
|
||||||
in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
|
|
||||||
}
|
|
||||||
in := string(in1) + string(in2) + string(in3)
|
|
||||||
|
|
||||||
trampolines := map[string]bool{}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
|
|
||||||
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
|
||||||
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
|
||||||
fmt.Fprintf(&out, "\n")
|
|
||||||
fmt.Fprintf(&out, "// +build go1.12\n")
|
|
||||||
fmt.Fprintf(&out, "\n")
|
|
||||||
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
|
||||||
for _, line := range strings.Split(in, "\n") {
|
|
||||||
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fn := line[5 : len(line)-13]
|
|
||||||
if !trampolines[fn] {
|
|
||||||
trampolines[fn] = true
|
|
||||||
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
|
|
||||||
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
|
|
||||||
}
|
|
||||||
}
|
|
407
vendor/golang.org/x/sys/unix/mksyscall.go
generated
vendored
407
vendor/golang.org/x/sys/unix/mksyscall.go
generated
vendored
@@ -1,407 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_darwin.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named errno.
|
|
||||||
|
|
||||||
A line beginning with //sysnb is like //sys, except that the
|
|
||||||
goroutine will not be suspended during the execution of the system
|
|
||||||
call. This must only be used for system calls which can never
|
|
||||||
block, as otherwise the system call could cause all goroutines to
|
|
||||||
hang.
|
|
||||||
*/
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
plan9 = flag.Bool("plan9", false, "plan9")
|
|
||||||
openbsd = flag.Bool("openbsd", false, "openbsd")
|
|
||||||
netbsd = flag.Bool("netbsd", false, "netbsd")
|
|
||||||
dragonfly = flag.Bool("dragonfly", false, "dragonfly")
|
|
||||||
arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
filename = flag.String("output", "", "output file name (standard output if omitted)")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS and architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goos := os.Getenv("GOOS")
|
|
||||||
if goos == "" {
|
|
||||||
fmt.Fprintln(os.Stderr, "GOOS not defined in environment")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
goarch := os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that we are using the Docker-based build system if we should
|
|
||||||
if goos == "linux" {
|
|
||||||
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
|
|
||||||
fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
|
|
||||||
fmt.Fprintf(os.Stderr, "See README.md\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
libc := false
|
|
||||||
if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
|
|
||||||
libc = true
|
|
||||||
}
|
|
||||||
trampolines := map[string]bool{}
|
|
||||||
|
|
||||||
text := ""
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, errno error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
|
|
||||||
|
|
||||||
// ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers.
|
|
||||||
if goos == "darwin" && !libc && funct == "ClockGettime" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
outDecl := ""
|
|
||||||
if len(out) > 0 {
|
|
||||||
outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
|
|
||||||
}
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
|
|
||||||
|
|
||||||
// Check if err return available
|
|
||||||
errvar := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
|
|
||||||
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass dummy pointer in that case.
|
|
||||||
// Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
|
|
||||||
text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
|
|
||||||
text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && (*openbsd || *netbsd) {
|
|
||||||
args = append(args, "0")
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else if endianness == "little-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int64" && *dragonfly {
|
|
||||||
if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else if endianness == "little-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" {
|
|
||||||
if len(args)%2 == 1 && *arm {
|
|
||||||
// arm abi specifies 64-bit argument uses
|
|
||||||
// (even, odd) pair
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine which form to use; pad args with zeros.
|
|
||||||
asm := "Syscall"
|
|
||||||
if nonblock != nil {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
asm = "RawSyscallNoError"
|
|
||||||
} else {
|
|
||||||
asm = "RawSyscall"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
asm = "SyscallNoError"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(args) <= 3 {
|
|
||||||
for len(args) < 3 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else if len(args) <= 6 {
|
|
||||||
asm += "6"
|
|
||||||
for len(args) < 6 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else if len(args) <= 9 {
|
|
||||||
asm += "9"
|
|
||||||
for len(args) < 9 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call number.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = "SYS_" + funct
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToUpper(sysname)
|
|
||||||
}
|
|
||||||
|
|
||||||
var libcFn string
|
|
||||||
if libc {
|
|
||||||
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
|
|
||||||
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
|
|
||||||
sysname = strings.ToLower(sysname) // lowercase
|
|
||||||
if sysname == "getdirentries64" {
|
|
||||||
// Special case - libSystem name and
|
|
||||||
// raw syscall name don't match.
|
|
||||||
sysname = "__getdirentries64"
|
|
||||||
}
|
|
||||||
libcFn = sysname
|
|
||||||
sysname = "funcPC(libc_" + sysname + "_trampoline)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
ret := []string{"_", "_", "_"}
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" && !*plan9 {
|
|
||||||
reg = "e1"
|
|
||||||
ret[2] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else if p.Name == "err" && *plan9 {
|
|
||||||
ret[0] = "r0"
|
|
||||||
ret[2] = "e1"
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%s != 0", reg)
|
|
||||||
}
|
|
||||||
if p.Type == "int64" && endianness != "" {
|
|
||||||
// 64-bit number in r1:r0 or r0:r1.
|
|
||||||
if i+2 > len(out) {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
|
|
||||||
}
|
|
||||||
ret[i] = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i+1] = fmt.Sprintf("r%d", i+1)
|
|
||||||
}
|
|
||||||
if reg != "e1" || *plan9 {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
} else {
|
|
||||||
if errvar == "" && goos == "linux" {
|
|
||||||
// raw syscall without error on Linux, see golang.org/issue/22924
|
|
||||||
text += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], call)
|
|
||||||
} else {
|
|
||||||
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text += body
|
|
||||||
|
|
||||||
if *plan9 && ret[2] == "e1" {
|
|
||||||
text += "\tif int32(r0) == -1 {\n"
|
|
||||||
text += "\t\terr = e1\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
} else if doErrno {
|
|
||||||
text += "\tif e1 != 0 {\n"
|
|
||||||
text += "\t\terr = errnoErr(e1)\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
}
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n\n"
|
|
||||||
|
|
||||||
if libc && !trampolines[libcFn] {
|
|
||||||
// some system calls share a trampoline, like read and readlen.
|
|
||||||
trampolines[libcFn] = true
|
|
||||||
// Declare assembly trampoline.
|
|
||||||
text += fmt.Sprintf("func libc_%s_trampoline()\n", libcFn)
|
|
||||||
// Assembly trampoline calls the libc_* function, which this magic
|
|
||||||
// redirects to use the function from libSystem.
|
|
||||||
text += fmt.Sprintf("//go:linkname libc_%s libc_%s\n", libcFn, libcFn)
|
|
||||||
text += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"/usr/lib/libSystem.B.dylib\"\n", libcFn, libcFn)
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ syscall.Errno
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
415
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go
generated
vendored
415
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc.go
generated
vendored
@@ -1,415 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_aix.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
*/
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
aix = flag.Bool("aix", false, "aix")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_aix_ppc.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
text := ""
|
|
||||||
cExtern := "/*\n#include <stdint.h>\n#include <stddef.h>\n"
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// Check if value return, err return available
|
|
||||||
errvar := ""
|
|
||||||
retvar := ""
|
|
||||||
rettype := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
} else {
|
|
||||||
retvar = p.Name
|
|
||||||
rettype = p.Type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call name.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
cRettype := ""
|
|
||||||
if rettype == "unsafe.Pointer" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "uintptr" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "int" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int32" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int64" {
|
|
||||||
cRettype = "long long"
|
|
||||||
} else if rettype == "uint32" {
|
|
||||||
cRettype = "unsigned int"
|
|
||||||
} else if rettype == "uint64" {
|
|
||||||
cRettype = "unsigned long long"
|
|
||||||
} else {
|
|
||||||
cRettype = "int"
|
|
||||||
}
|
|
||||||
if sysname == "exit" {
|
|
||||||
cRettype = "void"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change p.Types to c
|
|
||||||
var cIn []string
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t", "size_t")
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
cIn = append(cIn, "long long")
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
cIn = append(cIn, "unsigned int")
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
cIn = append(cIn, "unsigned long long")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" {
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
cExtern += "#define c_select select\n"
|
|
||||||
}
|
|
||||||
// Imports of system calls from libc
|
|
||||||
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
|
|
||||||
cIn := strings.Join(cIn, ", ")
|
|
||||||
cExtern += fmt.Sprintf("(%s);\n", cIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// So file name.
|
|
||||||
if *aix {
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc.a/shr_64.o"
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strconvfunc := "C.CString"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
if outps != "" {
|
|
||||||
outps = fmt.Sprintf(" (%s)", outps)
|
|
||||||
}
|
|
||||||
if text != "" {
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
argN := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "C.uintptr_t(uintptr(unsafe.Pointer("+p.Name+")))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(unsafe.Pointer(_p%d)))", n))
|
|
||||||
n++
|
|
||||||
text += fmt.Sprintf("\tvar _p%d int\n", n)
|
|
||||||
text += fmt.Sprintf("\t_p%d = len(%s)\n", n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("C.size_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
n++
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
|
|
||||||
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
|
|
||||||
args = append(args, fmt.Sprintf("_p%d", n))
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (argN == 2) && ((funct == "readlen") || (funct == "writelen")) {
|
|
||||||
args = append(args, fmt.Sprintf("C.size_t(%s)", p.Name))
|
|
||||||
} else if argN == 0 && funct == "fcntl" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if (argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt")) {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
args = append(args, fmt.Sprintf("C.longlong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uint(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
args = append(args, fmt.Sprintf("C.ulonglong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
argN++
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := ""
|
|
||||||
if sysname == "exit" {
|
|
||||||
if errvar != "" {
|
|
||||||
call += "er :="
|
|
||||||
} else {
|
|
||||||
call += ""
|
|
||||||
}
|
|
||||||
} else if errvar != "" {
|
|
||||||
call += "r0,er :="
|
|
||||||
} else if retvar != "" {
|
|
||||||
call += "r0,_ :="
|
|
||||||
} else {
|
|
||||||
call += ""
|
|
||||||
}
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist)
|
|
||||||
} else {
|
|
||||||
call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
} else {
|
|
||||||
reg = "r0"
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify return
|
|
||||||
if sysname != "exit" && errvar != "" {
|
|
||||||
if regexp.MustCompile(`^uintptr`).FindStringSubmatch(cRettype) != nil {
|
|
||||||
body += "\tif (uintptr(r0) ==^uintptr(0) && er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
} else {
|
|
||||||
body += "\tif (r0 ==-1 && er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
}
|
|
||||||
} else if errvar != "" {
|
|
||||||
body += "\tif (er != nil) {\n"
|
|
||||||
body += fmt.Sprintf("\t\t%s = er\n", errvar)
|
|
||||||
body += "\t}\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
text += body
|
|
||||||
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, cExtern, imp, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
614
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go
generated
vendored
614
vendor/golang.org/x/sys/unix/mksyscall_aix_ppc64.go
generated
vendored
@@ -1,614 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_aix.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
|
|
||||||
|
|
||||||
This program will generate three files and handle both gc and gccgo implementation:
|
|
||||||
- zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation)
|
|
||||||
- zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6
|
|
||||||
- zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type.
|
|
||||||
|
|
||||||
The generated code looks like this
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64.go
|
|
||||||
func asyscall(...) (n int, err error) {
|
|
||||||
// Pointer Creation
|
|
||||||
r1, e1 := callasyscall(...)
|
|
||||||
// Type Conversion
|
|
||||||
// Error Handler
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64_gc.go
|
|
||||||
//go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o"
|
|
||||||
//go:linkname libc_asyscall libc_asyscall
|
|
||||||
var asyscall syscallFunc
|
|
||||||
|
|
||||||
func callasyscall(...) (r1 uintptr, e1 Errno) {
|
|
||||||
r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... )
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
zsyscall_aix_ppc64_ggcgo.go
|
|
||||||
|
|
||||||
// int asyscall(...)
|
|
||||||
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
func callasyscall(...) (r1 uintptr, e1 Errno) {
|
|
||||||
r1 = uintptr(C.asyscall(...))
|
|
||||||
e1 = syscall.GetErrno()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
aix = flag.Bool("aix", false, "aix")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
// GCCGO
|
|
||||||
textgccgo := ""
|
|
||||||
cExtern := "/*\n#include <stdint.h>\n"
|
|
||||||
// GC
|
|
||||||
textgc := ""
|
|
||||||
dynimports := ""
|
|
||||||
linknames := ""
|
|
||||||
var vars []string
|
|
||||||
// COMMON
|
|
||||||
textcommon := ""
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
|
|
||||||
onlyCommon := false
|
|
||||||
if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" {
|
|
||||||
// This function call another syscall which is already implemented.
|
|
||||||
// Therefore, the gc and gccgo part must not be generated.
|
|
||||||
onlyCommon = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
|
|
||||||
textcommon += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
if !onlyCommon {
|
|
||||||
textgccgo += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
textgc += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if value return, err return available
|
|
||||||
errvar := ""
|
|
||||||
rettype := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
} else {
|
|
||||||
rettype = p.Type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
// GCCGO Prototype return type
|
|
||||||
cRettype := ""
|
|
||||||
if rettype == "unsafe.Pointer" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "uintptr" {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
|
|
||||||
cRettype = "uintptr_t"
|
|
||||||
} else if rettype == "int" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int32" {
|
|
||||||
cRettype = "int"
|
|
||||||
} else if rettype == "int64" {
|
|
||||||
cRettype = "long long"
|
|
||||||
} else if rettype == "uint32" {
|
|
||||||
cRettype = "unsigned int"
|
|
||||||
} else if rettype == "uint64" {
|
|
||||||
cRettype = "unsigned long long"
|
|
||||||
} else {
|
|
||||||
cRettype = "int"
|
|
||||||
}
|
|
||||||
if sysname == "exit" {
|
|
||||||
cRettype = "void"
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCCGO Prototype arguments type
|
|
||||||
var cIn []string
|
|
||||||
for i, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t", "size_t")
|
|
||||||
} else if p.Type == "unsafe.Pointer" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (i == 0 || i == 2) && funct == "fcntl" {
|
|
||||||
// These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
|
|
||||||
cIn = append(cIn, "uintptr_t")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
cIn = append(cIn, "long long")
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
cIn = append(cIn, "unsigned int")
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
cIn = append(cIn, "unsigned long long")
|
|
||||||
} else {
|
|
||||||
cIn = append(cIn, "int")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !onlyCommon {
|
|
||||||
// GCCGO Prototype Generation
|
|
||||||
// Imports of system calls from libc
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
cExtern += "#define c_select select\n"
|
|
||||||
}
|
|
||||||
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
|
|
||||||
cIn := strings.Join(cIn, ", ")
|
|
||||||
cExtern += fmt.Sprintf("(%s);\n", cIn)
|
|
||||||
}
|
|
||||||
// GC Library name
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc.a/shr_64.o"
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
sysvarname := fmt.Sprintf("libc_%s", sysname)
|
|
||||||
|
|
||||||
if !onlyCommon {
|
|
||||||
// GC Runtime import of function to allow cross-platform builds.
|
|
||||||
dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname)
|
|
||||||
// GC Link symbol to proc address variable.
|
|
||||||
linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname)
|
|
||||||
// GC Library proc address variable.
|
|
||||||
vars = append(vars, sysvarname)
|
|
||||||
}
|
|
||||||
|
|
||||||
strconvfunc := "BytePtrFromString"
|
|
||||||
strconvtype := "*byte"
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
if outps != "" {
|
|
||||||
outps = fmt.Sprintf(" (%s)", outps)
|
|
||||||
}
|
|
||||||
if textcommon != "" {
|
|
||||||
textcommon += "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
|
|
||||||
|
|
||||||
// Prepare arguments tocall.
|
|
||||||
var argscommon []string // Arguments in the common part
|
|
||||||
var argscall []string // Arguments for call prototype
|
|
||||||
var argsgc []string // Arguments for gc call (with syscall6)
|
|
||||||
var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall)
|
|
||||||
n := 0
|
|
||||||
argN := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
textcommon += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
|
|
||||||
textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n")
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n")
|
|
||||||
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else if p.Type == "int" {
|
|
||||||
if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) {
|
|
||||||
// These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
|
|
||||||
} else {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "int32" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int32", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
} else if p.Type == "int64" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int64", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint32" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name))
|
|
||||||
} else if p.Type == "uint64" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name))
|
|
||||||
} else if p.Type == "uintptr" {
|
|
||||||
argscommon = append(argscommon, p.Name)
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
|
|
||||||
argsgc = append(argsgc, p.Name)
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name))
|
|
||||||
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
|
|
||||||
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
|
|
||||||
}
|
|
||||||
argN++
|
|
||||||
}
|
|
||||||
nargs := len(argsgc)
|
|
||||||
|
|
||||||
// COMMON function generation
|
|
||||||
argscommonlist := strings.Join(argscommon, ", ")
|
|
||||||
callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist)
|
|
||||||
ret := []string{"_", "_"}
|
|
||||||
body := ""
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
ret[1] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else {
|
|
||||||
reg = "r0"
|
|
||||||
ret[0] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%s != 0", reg)
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" {
|
|
||||||
textcommon += fmt.Sprintf("\t%s\n", callcommon)
|
|
||||||
} else {
|
|
||||||
textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon)
|
|
||||||
}
|
|
||||||
textcommon += body
|
|
||||||
|
|
||||||
if doErrno {
|
|
||||||
textcommon += "\tif e1 != 0 {\n"
|
|
||||||
textcommon += "\t\terr = errnoErr(e1)\n"
|
|
||||||
textcommon += "\t}\n"
|
|
||||||
}
|
|
||||||
textcommon += "\treturn\n"
|
|
||||||
textcommon += "}\n"
|
|
||||||
|
|
||||||
if onlyCommon {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// CALL Prototype
|
|
||||||
callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", "))
|
|
||||||
|
|
||||||
// GC function generation
|
|
||||||
asm := "syscall6"
|
|
||||||
if nonblock != nil {
|
|
||||||
asm = "rawSyscall6"
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(argsgc) <= 6 {
|
|
||||||
for len(argsgc) < 6 {
|
|
||||||
argsgc = append(argsgc, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
argsgclist := strings.Join(argsgc, ", ")
|
|
||||||
callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist)
|
|
||||||
|
|
||||||
textgc += callProto
|
|
||||||
textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc)
|
|
||||||
textgc += "\treturn\n}\n"
|
|
||||||
|
|
||||||
// GCCGO function generation
|
|
||||||
argsgccgolist := strings.Join(argsgccgo, ", ")
|
|
||||||
var callgccgo string
|
|
||||||
if sysname == "select" {
|
|
||||||
// select is a keyword of Go. Its name is
|
|
||||||
// changed to c_select.
|
|
||||||
callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
|
|
||||||
} else {
|
|
||||||
callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
|
|
||||||
}
|
|
||||||
textgccgo += callProto
|
|
||||||
textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
|
|
||||||
textgccgo += "\te1 = syscall.GetErrno()\n"
|
|
||||||
textgccgo += "\treturn\n}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64.go
|
|
||||||
err := ioutil.WriteFile("zsyscall_aix_ppc64.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64_gc.go
|
|
||||||
vardecls := "\t" + strings.Join(vars, ",\n\t")
|
|
||||||
vardecls += " syscallFunc"
|
|
||||||
err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print zsyscall_aix_ppc64_gccgo.go
|
|
||||||
err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go",
|
|
||||||
[]byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)),
|
|
||||||
0644)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate1 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
||||||
const srcTemplate2 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
// +build !gccgo
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
type syscallFunc uintptr
|
|
||||||
|
|
||||||
var (
|
|
||||||
%s
|
|
||||||
)
|
|
||||||
|
|
||||||
// Implemented in runtime/syscall_aix.go.
|
|
||||||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
|
||||||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
||||||
const srcTemplate3 = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
// +build gccgo
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
%s
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
%s
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
335
vendor/golang.org/x/sys/unix/mksyscall_solaris.go
generated
vendored
335
vendor/golang.org/x/sys/unix/mksyscall_solaris.go
generated
vendored
@@ -1,335 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
/*
|
|
||||||
This program reads a file containing function prototypes
|
|
||||||
(like syscall_solaris.go) and generates system call bodies.
|
|
||||||
The prototypes are marked by lines beginning with "//sys"
|
|
||||||
and read like func declarations if //sys is replaced by func, but:
|
|
||||||
* The parameter lists must give a name for each argument.
|
|
||||||
This includes return parameters.
|
|
||||||
* The parameter lists must give a type for each argument:
|
|
||||||
the (x, y, z int) shorthand is not allowed.
|
|
||||||
* If the return parameter is an error number, it must be named err.
|
|
||||||
* If go func name needs to be different than its libc name,
|
|
||||||
* or the function is not in libc, name could be specified
|
|
||||||
* at the end, after "=" sign, like
|
|
||||||
//sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
|
|
||||||
*/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
b32 = flag.Bool("b32", false, "32bit big-endian")
|
|
||||||
l32 = flag.Bool("l32", false, "32bit little-endian")
|
|
||||||
tags = flag.String("tags", "", "build tags")
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksyscall_solaris.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return *tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is function parameter
|
|
||||||
type Param struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
}
|
|
||||||
|
|
||||||
// usage prints the program usage
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_solaris.go [-b32 | -l32] [-tags x,y] [file ...]\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParamList parses parameter list and returns a slice of parameters
|
|
||||||
func parseParamList(list string) []string {
|
|
||||||
list = strings.TrimSpace(list)
|
|
||||||
if list == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseParam splits a parameter into name and type
|
|
||||||
func parseParam(p string) Param {
|
|
||||||
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
|
|
||||||
if ps == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return Param{ps[1], ps[2]}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
if len(flag.Args()) <= 0 {
|
|
||||||
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
endianness := ""
|
|
||||||
if *b32 {
|
|
||||||
endianness = "big-endian"
|
|
||||||
} else if *l32 {
|
|
||||||
endianness = "little-endian"
|
|
||||||
}
|
|
||||||
|
|
||||||
pack := ""
|
|
||||||
text := ""
|
|
||||||
dynimports := ""
|
|
||||||
linknames := ""
|
|
||||||
var vars []string
|
|
||||||
for _, path := range flag.Args() {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
t := s.Text()
|
|
||||||
t = strings.TrimSpace(t)
|
|
||||||
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
|
|
||||||
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
|
|
||||||
pack = p[1]
|
|
||||||
}
|
|
||||||
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
|
|
||||||
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line must be of the form
|
|
||||||
// func Open(path string, mode int, perm int) (fd int, err error)
|
|
||||||
// Split into name, in params, out params.
|
|
||||||
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
|
|
||||||
if f == nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
|
|
||||||
|
|
||||||
// Split argument lists on comma.
|
|
||||||
in := parseParamList(inps)
|
|
||||||
out := parseParamList(outps)
|
|
||||||
|
|
||||||
inps = strings.Join(in, ", ")
|
|
||||||
outps = strings.Join(out, ", ")
|
|
||||||
|
|
||||||
// Try in vain to keep people from editing this file.
|
|
||||||
// The theory is that they jump into the middle of the file
|
|
||||||
// without reading the header.
|
|
||||||
text += "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"
|
|
||||||
|
|
||||||
// So file name.
|
|
||||||
if modname == "" {
|
|
||||||
modname = "libc"
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call name.
|
|
||||||
if sysname == "" {
|
|
||||||
sysname = funct
|
|
||||||
}
|
|
||||||
|
|
||||||
// System call pointer variable name.
|
|
||||||
sysvarname := fmt.Sprintf("proc%s", sysname)
|
|
||||||
|
|
||||||
strconvfunc := "BytePtrFromString"
|
|
||||||
strconvtype := "*byte"
|
|
||||||
|
|
||||||
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
|
|
||||||
|
|
||||||
// Runtime import of function to allow cross-platform builds.
|
|
||||||
dynimports += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"%s.so\"\n", sysname, sysname, modname)
|
|
||||||
// Link symbol to proc address variable.
|
|
||||||
linknames += fmt.Sprintf("//go:linkname %s libc_%s\n", sysvarname, sysname)
|
|
||||||
// Library proc address variable.
|
|
||||||
vars = append(vars, sysvarname)
|
|
||||||
|
|
||||||
// Go function header.
|
|
||||||
outlist := strings.Join(out, ", ")
|
|
||||||
if outlist != "" {
|
|
||||||
outlist = fmt.Sprintf(" (%s)", outlist)
|
|
||||||
}
|
|
||||||
if text != "" {
|
|
||||||
text += "\n"
|
|
||||||
}
|
|
||||||
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outlist)
|
|
||||||
|
|
||||||
// Check if err return available
|
|
||||||
errvar := ""
|
|
||||||
for _, param := range out {
|
|
||||||
p := parseParam(param)
|
|
||||||
if p.Type == "error" {
|
|
||||||
errvar = p.Name
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare arguments to Syscall.
|
|
||||||
var args []string
|
|
||||||
n := 0
|
|
||||||
for _, param := range in {
|
|
||||||
p := parseParam(param)
|
|
||||||
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
|
|
||||||
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
|
|
||||||
} else if p.Type == "string" && errvar != "" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
text += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
|
|
||||||
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "string" {
|
|
||||||
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
|
|
||||||
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
|
|
||||||
text += fmt.Sprintf("\t_p%d, _ = %s(%s)\n", n, strconvfunc, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
|
|
||||||
n++
|
|
||||||
} else if s := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); s != nil {
|
|
||||||
// Convert slice into pointer, length.
|
|
||||||
// Have to be careful not to take address of &a[0] if len == 0:
|
|
||||||
// pass nil in that case.
|
|
||||||
text += fmt.Sprintf("\tvar _p%d *%s\n", n, s[1])
|
|
||||||
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
|
|
||||||
n++
|
|
||||||
} else if p.Type == "int64" && endianness != "" {
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
|
|
||||||
}
|
|
||||||
} else if p.Type == "bool" {
|
|
||||||
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
|
|
||||||
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(_p%d)", n))
|
|
||||||
n++
|
|
||||||
} else {
|
|
||||||
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nargs := len(args)
|
|
||||||
|
|
||||||
// Determine which form to use; pad args with zeros.
|
|
||||||
asm := "sysvicall6"
|
|
||||||
if nonblock != nil {
|
|
||||||
asm = "rawSysvicall6"
|
|
||||||
}
|
|
||||||
if len(args) <= 6 {
|
|
||||||
for len(args) < 6 {
|
|
||||||
args = append(args, "0")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call\n", path)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual call.
|
|
||||||
arglist := strings.Join(args, ", ")
|
|
||||||
call := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, arglist)
|
|
||||||
|
|
||||||
// Assign return values.
|
|
||||||
body := ""
|
|
||||||
ret := []string{"_", "_", "_"}
|
|
||||||
doErrno := false
|
|
||||||
for i := 0; i < len(out); i++ {
|
|
||||||
p := parseParam(out[i])
|
|
||||||
reg := ""
|
|
||||||
if p.Name == "err" {
|
|
||||||
reg = "e1"
|
|
||||||
ret[2] = reg
|
|
||||||
doErrno = true
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i] = reg
|
|
||||||
}
|
|
||||||
if p.Type == "bool" {
|
|
||||||
reg = fmt.Sprintf("%d != 0", reg)
|
|
||||||
}
|
|
||||||
if p.Type == "int64" && endianness != "" {
|
|
||||||
// 64-bit number in r1:r0 or r0:r1.
|
|
||||||
if i+2 > len(out) {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: not enough registers for int64 return\n", path)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
if endianness == "big-endian" {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
|
|
||||||
} else {
|
|
||||||
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
|
|
||||||
}
|
|
||||||
ret[i] = fmt.Sprintf("r%d", i)
|
|
||||||
ret[i+1] = fmt.Sprintf("r%d", i+1)
|
|
||||||
}
|
|
||||||
if reg != "e1" {
|
|
||||||
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
|
|
||||||
text += fmt.Sprintf("\t%s\n", call)
|
|
||||||
} else {
|
|
||||||
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
|
|
||||||
}
|
|
||||||
text += body
|
|
||||||
|
|
||||||
if doErrno {
|
|
||||||
text += "\tif e1 != 0 {\n"
|
|
||||||
text += "\t\terr = e1\n"
|
|
||||||
text += "\t}\n"
|
|
||||||
}
|
|
||||||
text += "\treturn\n"
|
|
||||||
text += "}\n"
|
|
||||||
}
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
imp := ""
|
|
||||||
if pack != "unix" {
|
|
||||||
imp = "import \"golang.org/x/sys/unix\"\n"
|
|
||||||
|
|
||||||
}
|
|
||||||
vardecls := "\t" + strings.Join(vars, ",\n\t")
|
|
||||||
vardecls += " syscallFunc"
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package %s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
%s
|
|
||||||
var (
|
|
||||||
%s
|
|
||||||
)
|
|
||||||
|
|
||||||
%s
|
|
||||||
`
|
|
355
vendor/golang.org/x/sys/unix/mksysctl_openbsd.go
generated
vendored
355
vendor/golang.org/x/sys/unix/mksysctl_openbsd.go
generated
vendored
@@ -1,355 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
|
|
||||||
//
|
|
||||||
// Build a MIB with each entry being an array containing the level, type and
|
|
||||||
// a hash that will contain additional entries if the current entry is a node.
|
|
||||||
// We then walk this MIB and create a flattened sysctl name to OID hash.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
goos, goarch string
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments.
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags.
|
|
||||||
func buildTags() string {
|
|
||||||
return fmt.Sprintf("%s,%s", goarch, goos)
|
|
||||||
}
|
|
||||||
|
|
||||||
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
|
|
||||||
func reMatch(re *regexp.Regexp, str string, m *[]string) bool {
|
|
||||||
*m = re.FindStringSubmatch(str)
|
|
||||||
if *m != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type nodeElement struct {
|
|
||||||
n int
|
|
||||||
t string
|
|
||||||
pE *map[string]nodeElement
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
debugEnabled bool
|
|
||||||
mib map[string]nodeElement
|
|
||||||
node *map[string]nodeElement
|
|
||||||
nodeMap map[string]string
|
|
||||||
sysCtl []string
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`)
|
|
||||||
ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`)
|
|
||||||
ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`)
|
|
||||||
netInetRE = regexp.MustCompile(`^netinet/`)
|
|
||||||
netInet6RE = regexp.MustCompile(`^netinet6/`)
|
|
||||||
netRE = regexp.MustCompile(`^net/`)
|
|
||||||
bracesRE = regexp.MustCompile(`{.*}`)
|
|
||||||
ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`)
|
|
||||||
fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`)
|
|
||||||
)
|
|
||||||
|
|
||||||
func debug(s string) {
|
|
||||||
if debugEnabled {
|
|
||||||
fmt.Fprintln(os.Stderr, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk the MIB and build a sysctl name to OID mapping.
|
|
||||||
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) {
|
|
||||||
lNode := pNode // local copy of pointer to node
|
|
||||||
var keys []string
|
|
||||||
for k := range *lNode {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for _, key := range keys {
|
|
||||||
nodename := name
|
|
||||||
if name != "" {
|
|
||||||
nodename += "."
|
|
||||||
}
|
|
||||||
nodename += key
|
|
||||||
|
|
||||||
nodeoid := append(oid, (*pNode)[key].n)
|
|
||||||
|
|
||||||
if (*pNode)[key].t == `CTLTYPE_NODE` {
|
|
||||||
if _, ok := nodeMap[nodename]; ok {
|
|
||||||
lNode = &mib
|
|
||||||
ctlName := nodeMap[nodename]
|
|
||||||
for _, part := range strings.Split(ctlName, ".") {
|
|
||||||
lNode = ((*lNode)[part]).pE
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lNode = (*pNode)[key].pE
|
|
||||||
}
|
|
||||||
buildSysctl(lNode, nodename, nodeoid)
|
|
||||||
} else if (*pNode)[key].t != "" {
|
|
||||||
oidStr := []string{}
|
|
||||||
for j := range nodeoid {
|
|
||||||
oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j]))
|
|
||||||
}
|
|
||||||
text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n"
|
|
||||||
sysCtl = append(sysCtl, text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS (using GOOS_TARGET if it exist)
|
|
||||||
goos = os.Getenv("GOOS_TARGET")
|
|
||||||
if goos == "" {
|
|
||||||
goos = os.Getenv("GOOS")
|
|
||||||
}
|
|
||||||
// Get the architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goarch = os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
// Check if GOOS and GOARCH environment variables are defined
|
|
||||||
if goarch == "" || goos == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
mib = make(map[string]nodeElement)
|
|
||||||
headers := [...]string{
|
|
||||||
`sys/sysctl.h`,
|
|
||||||
`sys/socket.h`,
|
|
||||||
`sys/tty.h`,
|
|
||||||
`sys/malloc.h`,
|
|
||||||
`sys/mount.h`,
|
|
||||||
`sys/namei.h`,
|
|
||||||
`sys/sem.h`,
|
|
||||||
`sys/shm.h`,
|
|
||||||
`sys/vmmeter.h`,
|
|
||||||
`uvm/uvmexp.h`,
|
|
||||||
`uvm/uvm_param.h`,
|
|
||||||
`uvm/uvm_swap_encrypt.h`,
|
|
||||||
`ddb/db_var.h`,
|
|
||||||
`net/if.h`,
|
|
||||||
`net/if_pfsync.h`,
|
|
||||||
`net/pipex.h`,
|
|
||||||
`netinet/in.h`,
|
|
||||||
`netinet/icmp_var.h`,
|
|
||||||
`netinet/igmp_var.h`,
|
|
||||||
`netinet/ip_ah.h`,
|
|
||||||
`netinet/ip_carp.h`,
|
|
||||||
`netinet/ip_divert.h`,
|
|
||||||
`netinet/ip_esp.h`,
|
|
||||||
`netinet/ip_ether.h`,
|
|
||||||
`netinet/ip_gre.h`,
|
|
||||||
`netinet/ip_ipcomp.h`,
|
|
||||||
`netinet/ip_ipip.h`,
|
|
||||||
`netinet/pim_var.h`,
|
|
||||||
`netinet/tcp_var.h`,
|
|
||||||
`netinet/udp_var.h`,
|
|
||||||
`netinet6/in6.h`,
|
|
||||||
`netinet6/ip6_divert.h`,
|
|
||||||
`netinet6/pim6_var.h`,
|
|
||||||
`netinet/icmp6.h`,
|
|
||||||
`netmpls/mpls.h`,
|
|
||||||
}
|
|
||||||
|
|
||||||
ctls := [...]string{
|
|
||||||
`kern`,
|
|
||||||
`vm`,
|
|
||||||
`fs`,
|
|
||||||
`net`,
|
|
||||||
//debug /* Special handling required */
|
|
||||||
`hw`,
|
|
||||||
//machdep /* Arch specific */
|
|
||||||
`user`,
|
|
||||||
`ddb`,
|
|
||||||
//vfs /* Special handling required */
|
|
||||||
`fs.posix`,
|
|
||||||
`kern.forkstat`,
|
|
||||||
`kern.intrcnt`,
|
|
||||||
`kern.malloc`,
|
|
||||||
`kern.nchstats`,
|
|
||||||
`kern.seminfo`,
|
|
||||||
`kern.shminfo`,
|
|
||||||
`kern.timecounter`,
|
|
||||||
`kern.tty`,
|
|
||||||
`kern.watchdog`,
|
|
||||||
`net.bpf`,
|
|
||||||
`net.ifq`,
|
|
||||||
`net.inet`,
|
|
||||||
`net.inet.ah`,
|
|
||||||
`net.inet.carp`,
|
|
||||||
`net.inet.divert`,
|
|
||||||
`net.inet.esp`,
|
|
||||||
`net.inet.etherip`,
|
|
||||||
`net.inet.gre`,
|
|
||||||
`net.inet.icmp`,
|
|
||||||
`net.inet.igmp`,
|
|
||||||
`net.inet.ip`,
|
|
||||||
`net.inet.ip.ifq`,
|
|
||||||
`net.inet.ipcomp`,
|
|
||||||
`net.inet.ipip`,
|
|
||||||
`net.inet.mobileip`,
|
|
||||||
`net.inet.pfsync`,
|
|
||||||
`net.inet.pim`,
|
|
||||||
`net.inet.tcp`,
|
|
||||||
`net.inet.udp`,
|
|
||||||
`net.inet6`,
|
|
||||||
`net.inet6.divert`,
|
|
||||||
`net.inet6.ip6`,
|
|
||||||
`net.inet6.icmp6`,
|
|
||||||
`net.inet6.pim6`,
|
|
||||||
`net.inet6.tcp6`,
|
|
||||||
`net.inet6.udp6`,
|
|
||||||
`net.mpls`,
|
|
||||||
`net.mpls.ifq`,
|
|
||||||
`net.key`,
|
|
||||||
`net.pflow`,
|
|
||||||
`net.pfsync`,
|
|
||||||
`net.pipex`,
|
|
||||||
`net.rt`,
|
|
||||||
`vm.swapencrypt`,
|
|
||||||
//vfsgenctl /* Special handling required */
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node name "fixups"
|
|
||||||
ctlMap := map[string]string{
|
|
||||||
"ipproto": "net.inet",
|
|
||||||
"net.inet.ipproto": "net.inet",
|
|
||||||
"net.inet6.ipv6proto": "net.inet6",
|
|
||||||
"net.inet6.ipv6": "net.inet6.ip6",
|
|
||||||
"net.inet.icmpv6": "net.inet6.icmp6",
|
|
||||||
"net.inet6.divert6": "net.inet6.divert",
|
|
||||||
"net.inet6.tcp6": "net.inet.tcp",
|
|
||||||
"net.inet6.udp6": "net.inet.udp",
|
|
||||||
"mpls": "net.mpls",
|
|
||||||
"swpenc": "vm.swapencrypt",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node mappings
|
|
||||||
nodeMap = map[string]string{
|
|
||||||
"net.inet.ip.ifq": "net.ifq",
|
|
||||||
"net.inet.pfsync": "net.pfsync",
|
|
||||||
"net.mpls.ifq": "net.ifq",
|
|
||||||
}
|
|
||||||
|
|
||||||
mCtls := make(map[string]bool)
|
|
||||||
for _, ctl := range ctls {
|
|
||||||
mCtls[ctl] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, header := range headers {
|
|
||||||
debug("Processing " + header)
|
|
||||||
file, err := os.Open(filepath.Join("/usr/include", header))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
s := bufio.NewScanner(file)
|
|
||||||
for s.Scan() {
|
|
||||||
var sub []string
|
|
||||||
if reMatch(ctlNames1RE, s.Text(), &sub) ||
|
|
||||||
reMatch(ctlNames2RE, s.Text(), &sub) ||
|
|
||||||
reMatch(ctlNames3RE, s.Text(), &sub) {
|
|
||||||
if sub[1] == `CTL_NAMES` {
|
|
||||||
// Top level.
|
|
||||||
node = &mib
|
|
||||||
} else {
|
|
||||||
// Node.
|
|
||||||
nodename := strings.ToLower(sub[2])
|
|
||||||
ctlName := ""
|
|
||||||
if reMatch(netInetRE, header, &sub) {
|
|
||||||
ctlName = "net.inet." + nodename
|
|
||||||
} else if reMatch(netInet6RE, header, &sub) {
|
|
||||||
ctlName = "net.inet6." + nodename
|
|
||||||
} else if reMatch(netRE, header, &sub) {
|
|
||||||
ctlName = "net." + nodename
|
|
||||||
} else {
|
|
||||||
ctlName = nodename
|
|
||||||
ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if val, ok := ctlMap[ctlName]; ok {
|
|
||||||
ctlName = val
|
|
||||||
}
|
|
||||||
if _, ok := mCtls[ctlName]; !ok {
|
|
||||||
debug("Ignoring " + ctlName + "...")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk down from the top of the MIB.
|
|
||||||
node = &mib
|
|
||||||
for _, part := range strings.Split(ctlName, ".") {
|
|
||||||
if _, ok := (*node)[part]; !ok {
|
|
||||||
debug("Missing node " + part)
|
|
||||||
(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}}
|
|
||||||
}
|
|
||||||
node = (*node)[part].pE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate current node with entries.
|
|
||||||
i := -1
|
|
||||||
for !strings.HasPrefix(s.Text(), "}") {
|
|
||||||
s.Scan()
|
|
||||||
if reMatch(bracesRE, s.Text(), &sub) {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if !reMatch(ctlTypeRE, s.Text(), &sub) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err = s.Err()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
buildSysctl(&mib, "", []int{})
|
|
||||||
|
|
||||||
sort.Strings(sysCtl)
|
|
||||||
text := strings.Join(sysCtl, "")
|
|
||||||
|
|
||||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcTemplate = `// %s
|
|
||||||
// Code generated by the command above; DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
type mibentry struct {
|
|
||||||
ctlname string
|
|
||||||
ctloid []_C_int
|
|
||||||
}
|
|
||||||
|
|
||||||
var sysctlMib = []mibentry {
|
|
||||||
%s
|
|
||||||
}
|
|
||||||
`
|
|
190
vendor/golang.org/x/sys/unix/mksysnum.go
generated
vendored
190
vendor/golang.org/x/sys/unix/mksysnum.go
generated
vendored
@@ -1,190 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Generate system call table for DragonFly, NetBSD,
|
|
||||||
// FreeBSD, OpenBSD or Darwin from master list
|
|
||||||
// (for example, /usr/src/sys/kern/syscalls.master or
|
|
||||||
// sys/syscall.h).
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
goos, goarch string
|
|
||||||
)
|
|
||||||
|
|
||||||
// cmdLine returns this programs's commandline arguments
|
|
||||||
func cmdLine() string {
|
|
||||||
return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildTags returns build tags
|
|
||||||
func buildTags() string {
|
|
||||||
return fmt.Sprintf("%s,%s", goarch, goos)
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkErr(err error) {
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// source string and substring slice for regexp
|
|
||||||
type re struct {
|
|
||||||
str string // source string
|
|
||||||
sub []string // matched sub-string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match performs regular expression match
|
|
||||||
func (r *re) Match(exp string) bool {
|
|
||||||
r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
|
|
||||||
if r.sub != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetchFile fetches a text file from URL
|
|
||||||
func fetchFile(URL string) io.Reader {
|
|
||||||
resp, err := http.Get(URL)
|
|
||||||
checkErr(err)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
checkErr(err)
|
|
||||||
return strings.NewReader(string(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
// readFile reads a text file from path
|
|
||||||
func readFile(path string) io.Reader {
|
|
||||||
file, err := os.Open(os.Args[1])
|
|
||||||
checkErr(err)
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
func format(name, num, proto string) string {
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
// There are multiple entries for enosys and nosys, so comment them out.
|
|
||||||
nm := re{str: name}
|
|
||||||
if nm.Match(`^SYS_E?NOSYS$`) {
|
|
||||||
name = fmt.Sprintf("// %s", name)
|
|
||||||
}
|
|
||||||
if name == `SYS_SYS_EXIT` {
|
|
||||||
name = `SYS_EXIT`
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get the OS (using GOOS_TARGET if it exist)
|
|
||||||
goos = os.Getenv("GOOS_TARGET")
|
|
||||||
if goos == "" {
|
|
||||||
goos = os.Getenv("GOOS")
|
|
||||||
}
|
|
||||||
// Get the architecture (using GOARCH_TARGET if it exists)
|
|
||||||
goarch = os.Getenv("GOARCH_TARGET")
|
|
||||||
if goarch == "" {
|
|
||||||
goarch = os.Getenv("GOARCH")
|
|
||||||
}
|
|
||||||
// Check if GOOS and GOARCH environment variables are defined
|
|
||||||
if goarch == "" || goos == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
file := strings.TrimSpace(os.Args[1])
|
|
||||||
var syscalls io.Reader
|
|
||||||
if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
|
|
||||||
// Download syscalls.master file
|
|
||||||
syscalls = fetchFile(file)
|
|
||||||
} else {
|
|
||||||
syscalls = readFile(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
var text, line string
|
|
||||||
s := bufio.NewScanner(syscalls)
|
|
||||||
for s.Scan() {
|
|
||||||
t := re{str: line}
|
|
||||||
if t.Match(`^(.*)\\$`) {
|
|
||||||
// Handle continuation
|
|
||||||
line = t.sub[1]
|
|
||||||
line += strings.TrimLeft(s.Text(), " \t")
|
|
||||||
} else {
|
|
||||||
// New line
|
|
||||||
line = s.Text()
|
|
||||||
}
|
|
||||||
t = re{str: line}
|
|
||||||
if t.Match(`\\$`) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t = re{str: line}
|
|
||||||
|
|
||||||
switch goos {
|
|
||||||
case "dragonfly":
|
|
||||||
if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
|
|
||||||
num, proto := t.sub[1], t.sub[2]
|
|
||||||
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "freebsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
|
|
||||||
num, proto := t.sub[1], t.sub[2]
|
|
||||||
name := fmt.Sprintf("SYS_%s", t.sub[3])
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "openbsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
|
|
||||||
num, proto, name := t.sub[1], t.sub[3], t.sub[4]
|
|
||||||
text += format(name, num, proto)
|
|
||||||
}
|
|
||||||
case "netbsd":
|
|
||||||
if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
|
|
||||||
num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
|
|
||||||
name := t.sub[7] + "_" + t.sub[9]
|
|
||||||
if t.sub[11] != "" {
|
|
||||||
name = t.sub[7] + "_" + t.sub[11]
|
|
||||||
}
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
if compat == "" || compat == "13" || compat == "30" || compat == "50" {
|
|
||||||
text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "darwin":
|
|
||||||
if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
|
|
||||||
name, num := t.sub[1], t.sub[2]
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
text += fmt.Sprintf(" SYS_%s = %s;\n", name, num)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
|
|
||||||
os.Exit(1)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := s.Err()
|
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
fmt.Printf(template, cmdLine(), buildTags(), text)
|
|
||||||
}
|
|
||||||
|
|
||||||
const template = `// %s
|
|
||||||
// Code generated by the command above; see README.md. DO NOT EDIT.
|
|
||||||
|
|
||||||
// +build %s
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
const(
|
|
||||||
%s)`
|
|
237
vendor/golang.org/x/sys/unix/types_aix.go
generated
vendored
237
vendor/golang.org/x/sys/unix/types_aix.go
generated
vendored
@@ -1,237 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
// +build aix
|
|
||||||
|
|
||||||
/*
|
|
||||||
Input to cgo -godefs. See also mkerrors.sh and mkall.sh
|
|
||||||
*/
|
|
||||||
|
|
||||||
// +godefs map struct_in_addr [4]byte /* in_addr */
|
|
||||||
// +godefs map struct_in6_addr [16]byte /* in6_addr */
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/limits.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <utime.h>
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/statfs.h>
|
|
||||||
#include <sys/termio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <net/if_dl.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/icmp6.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
sizeofPtr = sizeof(void*),
|
|
||||||
};
|
|
||||||
|
|
||||||
union sockaddr_all {
|
|
||||||
struct sockaddr s1; // this one gets used for fields
|
|
||||||
struct sockaddr_in s2; // these pad it out
|
|
||||||
struct sockaddr_in6 s3;
|
|
||||||
struct sockaddr_un s4;
|
|
||||||
struct sockaddr_dl s5;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sockaddr_any {
|
|
||||||
struct sockaddr addr;
|
|
||||||
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
|
|
||||||
};
|
|
||||||
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// Machine characteristics
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofPtr = C.sizeofPtr
|
|
||||||
SizeofShort = C.sizeof_short
|
|
||||||
SizeofInt = C.sizeof_int
|
|
||||||
SizeofLong = C.sizeof_long
|
|
||||||
SizeofLongLong = C.sizeof_longlong
|
|
||||||
PathMax = C.PATH_MAX
|
|
||||||
)
|
|
||||||
|
|
||||||
// Basic types
|
|
||||||
|
|
||||||
type (
|
|
||||||
_C_short C.short
|
|
||||||
_C_int C.int
|
|
||||||
_C_long C.long
|
|
||||||
_C_long_long C.longlong
|
|
||||||
)
|
|
||||||
|
|
||||||
type off64 C.off64_t
|
|
||||||
type off C.off_t
|
|
||||||
type Mode_t C.mode_t
|
|
||||||
|
|
||||||
// Time
|
|
||||||
|
|
||||||
type Timespec C.struct_timespec
|
|
||||||
|
|
||||||
type Timeval C.struct_timeval
|
|
||||||
|
|
||||||
type Timeval32 C.struct_timeval32
|
|
||||||
|
|
||||||
type Timex C.struct_timex
|
|
||||||
|
|
||||||
type Time_t C.time_t
|
|
||||||
|
|
||||||
type Tms C.struct_tms
|
|
||||||
|
|
||||||
type Utimbuf C.struct_utimbuf
|
|
||||||
|
|
||||||
type Timezone C.struct_timezone
|
|
||||||
|
|
||||||
// Processes
|
|
||||||
|
|
||||||
type Rusage C.struct_rusage
|
|
||||||
|
|
||||||
type Rlimit C.struct_rlimit64
|
|
||||||
|
|
||||||
type Pid_t C.pid_t
|
|
||||||
|
|
||||||
type _Gid_t C.gid_t
|
|
||||||
|
|
||||||
type dev_t C.dev_t
|
|
||||||
|
|
||||||
// Files
|
|
||||||
|
|
||||||
type Stat_t C.struct_stat
|
|
||||||
|
|
||||||
type StatxTimestamp C.struct_statx_timestamp
|
|
||||||
|
|
||||||
type Statx_t C.struct_statx
|
|
||||||
|
|
||||||
type Dirent C.struct_dirent
|
|
||||||
|
|
||||||
// Sockets
|
|
||||||
|
|
||||||
type RawSockaddrInet4 C.struct_sockaddr_in
|
|
||||||
|
|
||||||
type RawSockaddrInet6 C.struct_sockaddr_in6
|
|
||||||
|
|
||||||
type RawSockaddrUnix C.struct_sockaddr_un
|
|
||||||
|
|
||||||
type RawSockaddrDatalink C.struct_sockaddr_dl
|
|
||||||
|
|
||||||
type RawSockaddr C.struct_sockaddr
|
|
||||||
|
|
||||||
type RawSockaddrAny C.struct_sockaddr_any
|
|
||||||
|
|
||||||
type _Socklen C.socklen_t
|
|
||||||
|
|
||||||
type Cmsghdr C.struct_cmsghdr
|
|
||||||
|
|
||||||
type ICMPv6Filter C.struct_icmp6_filter
|
|
||||||
|
|
||||||
type Iovec C.struct_iovec
|
|
||||||
|
|
||||||
type IPMreq C.struct_ip_mreq
|
|
||||||
|
|
||||||
type IPv6Mreq C.struct_ipv6_mreq
|
|
||||||
|
|
||||||
type IPv6MTUInfo C.struct_ip6_mtuinfo
|
|
||||||
|
|
||||||
type Linger C.struct_linger
|
|
||||||
|
|
||||||
type Msghdr C.struct_msghdr
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
|
|
||||||
SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
|
|
||||||
SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
|
|
||||||
SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
|
|
||||||
SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
|
|
||||||
SizeofLinger = C.sizeof_struct_linger
|
|
||||||
SizeofIPMreq = C.sizeof_struct_ip_mreq
|
|
||||||
SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
|
|
||||||
SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
|
|
||||||
SizeofMsghdr = C.sizeof_struct_msghdr
|
|
||||||
SizeofCmsghdr = C.sizeof_struct_cmsghdr
|
|
||||||
SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
|
|
||||||
)
|
|
||||||
|
|
||||||
// Routing and interface messages
|
|
||||||
|
|
||||||
const (
|
|
||||||
SizeofIfMsghdr = C.sizeof_struct_if_msghdr
|
|
||||||
)
|
|
||||||
|
|
||||||
type IfMsgHdr C.struct_if_msghdr
|
|
||||||
|
|
||||||
// Misc
|
|
||||||
|
|
||||||
type FdSet C.fd_set
|
|
||||||
|
|
||||||
type Utsname C.struct_utsname
|
|
||||||
|
|
||||||
type Ustat_t C.struct_ustat
|
|
||||||
|
|
||||||
type Sigset_t C.sigset_t
|
|
||||||
|
|
||||||
const (
|
|
||||||
AT_FDCWD = C.AT_FDCWD
|
|
||||||
AT_REMOVEDIR = C.AT_REMOVEDIR
|
|
||||||
AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
|
|
||||||
)
|
|
||||||
|
|
||||||
// Terminal handling
|
|
||||||
|
|
||||||
type Termios C.struct_termios
|
|
||||||
|
|
||||||
type Termio C.struct_termio
|
|
||||||
|
|
||||||
type Winsize C.struct_winsize
|
|
||||||
|
|
||||||
//poll
|
|
||||||
|
|
||||||
type PollFd struct {
|
|
||||||
Fd int32
|
|
||||||
Events uint16
|
|
||||||
Revents uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
POLLERR = C.POLLERR
|
|
||||||
POLLHUP = C.POLLHUP
|
|
||||||
POLLIN = C.POLLIN
|
|
||||||
POLLNVAL = C.POLLNVAL
|
|
||||||
POLLOUT = C.POLLOUT
|
|
||||||
POLLPRI = C.POLLPRI
|
|
||||||
POLLRDBAND = C.POLLRDBAND
|
|
||||||
POLLRDNORM = C.POLLRDNORM
|
|
||||||
POLLWRBAND = C.POLLWRBAND
|
|
||||||
POLLWRNORM = C.POLLWRNORM
|
|
||||||
)
|
|
||||||
|
|
||||||
//flock_t
|
|
||||||
|
|
||||||
type Flock_t C.struct_flock64
|
|
||||||
|
|
||||||
// Statfs
|
|
||||||
|
|
||||||
type Fsid_t C.struct_fsid_t
|
|
||||||
type Fsid64_t C.struct_fsid64_t
|
|
||||||
|
|
||||||
type Statfs_t C.struct_statfs
|
|
||||||
|
|
||||||
const RNDGETENTCNT = 0x80045200
|
|
64
vendor/golang.org/x/text/internal/language/compact/gen.go
generated
vendored
64
vendor/golang.org/x/text/internal/language/compact/gen.go
generated
vendored
@@ -1,64 +0,0 @@
|
|||||||
// Copyright 2013 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
// Language tag table generator.
|
|
||||||
// Data read from the web.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"golang.org/x/text/internal/gen"
|
|
||||||
"golang.org/x/text/unicode/cldr"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
test = flag.Bool("test",
|
|
||||||
false,
|
|
||||||
"test existing tables; can be used to compare web data with package data.")
|
|
||||||
outputFile = flag.String("output",
|
|
||||||
"tables.go",
|
|
||||||
"output file for generated tables")
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
gen.Init()
|
|
||||||
|
|
||||||
w := gen.NewCodeWriter()
|
|
||||||
defer w.WriteGoFile("tables.go", "compact")
|
|
||||||
|
|
||||||
fmt.Fprintln(w, `import "golang.org/x/text/internal/language"`)
|
|
||||||
|
|
||||||
b := newBuilder(w)
|
|
||||||
gen.WriteCLDRVersion(w)
|
|
||||||
|
|
||||||
b.writeCompactIndex()
|
|
||||||
}
|
|
||||||
|
|
||||||
type builder struct {
|
|
||||||
w *gen.CodeWriter
|
|
||||||
data *cldr.CLDR
|
|
||||||
supp *cldr.SupplementalData
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBuilder(w *gen.CodeWriter) *builder {
|
|
||||||
r := gen.OpenCLDRCoreZip()
|
|
||||||
defer r.Close()
|
|
||||||
d := &cldr.Decoder{}
|
|
||||||
data, err := d.DecodeZip(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
b := builder{
|
|
||||||
w: w,
|
|
||||||
data: data,
|
|
||||||
supp: data.Supplemental(),
|
|
||||||
}
|
|
||||||
return &b
|
|
||||||
}
|
|
113
vendor/golang.org/x/text/internal/language/compact/gen_index.go
generated
vendored
113
vendor/golang.org/x/text/internal/language/compact/gen_index.go
generated
vendored
@@ -1,113 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// This file generates derivative tables based on the language package itself.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/text/internal/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Compact indices:
|
|
||||||
// Note -va-X variants only apply to localization variants.
|
|
||||||
// BCP variants only ever apply to language.
|
|
||||||
// The only ambiguity between tags is with regions.
|
|
||||||
|
|
||||||
func (b *builder) writeCompactIndex() {
|
|
||||||
// Collect all language tags for which we have any data in CLDR.
|
|
||||||
m := map[language.Tag]bool{}
|
|
||||||
for _, lang := range b.data.Locales() {
|
|
||||||
// We include all locales unconditionally to be consistent with en_US.
|
|
||||||
// We want en_US, even though it has no data associated with it.
|
|
||||||
|
|
||||||
// TODO: put any of the languages for which no data exists at the end
|
|
||||||
// of the index. This allows all components based on ICU to use that
|
|
||||||
// as the cutoff point.
|
|
||||||
// if x := data.RawLDML(lang); false ||
|
|
||||||
// x.LocaleDisplayNames != nil ||
|
|
||||||
// x.Characters != nil ||
|
|
||||||
// x.Delimiters != nil ||
|
|
||||||
// x.Measurement != nil ||
|
|
||||||
// x.Dates != nil ||
|
|
||||||
// x.Numbers != nil ||
|
|
||||||
// x.Units != nil ||
|
|
||||||
// x.ListPatterns != nil ||
|
|
||||||
// x.Collations != nil ||
|
|
||||||
// x.Segmentations != nil ||
|
|
||||||
// x.Rbnf != nil ||
|
|
||||||
// x.Annotations != nil ||
|
|
||||||
// x.Metadata != nil {
|
|
||||||
|
|
||||||
// TODO: support POSIX natively, albeit non-standard.
|
|
||||||
tag := language.Make(strings.Replace(lang, "_POSIX", "-u-va-posix", 1))
|
|
||||||
m[tag] = true
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: plural rules are also defined for the deprecated tags:
|
|
||||||
// iw mo sh tl
|
|
||||||
// Consider removing these as compact tags.
|
|
||||||
|
|
||||||
// Include locales for plural rules, which uses a different structure.
|
|
||||||
for _, plurals := range b.supp.Plurals {
|
|
||||||
for _, rules := range plurals.PluralRules {
|
|
||||||
for _, lang := range strings.Split(rules.Locales, " ") {
|
|
||||||
m[language.Make(lang)] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var coreTags []language.CompactCoreInfo
|
|
||||||
var special []string
|
|
||||||
|
|
||||||
for t := range m {
|
|
||||||
if x := t.Extensions(); len(x) != 0 && fmt.Sprint(x) != "[u-va-posix]" {
|
|
||||||
log.Fatalf("Unexpected extension %v in %v", x, t)
|
|
||||||
}
|
|
||||||
if len(t.Variants()) == 0 && len(t.Extensions()) == 0 {
|
|
||||||
cci, ok := language.GetCompactCore(t)
|
|
||||||
if !ok {
|
|
||||||
log.Fatalf("Locale for non-basic language %q", t)
|
|
||||||
}
|
|
||||||
coreTags = append(coreTags, cci)
|
|
||||||
} else {
|
|
||||||
special = append(special, t.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w := b.w
|
|
||||||
|
|
||||||
sort.Slice(coreTags, func(i, j int) bool { return coreTags[i] < coreTags[j] })
|
|
||||||
sort.Strings(special)
|
|
||||||
|
|
||||||
w.WriteComment(`
|
|
||||||
NumCompactTags is the number of common tags. The maximum tag is
|
|
||||||
NumCompactTags-1.`)
|
|
||||||
w.WriteConst("NumCompactTags", len(m))
|
|
||||||
|
|
||||||
fmt.Fprintln(w, "const (")
|
|
||||||
for i, t := range coreTags {
|
|
||||||
fmt.Fprintf(w, "%s ID = %d\n", ident(t.Tag().String()), i)
|
|
||||||
}
|
|
||||||
for i, t := range special {
|
|
||||||
fmt.Fprintf(w, "%s ID = %d\n", ident(t), i+len(coreTags))
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, ")")
|
|
||||||
|
|
||||||
w.WriteVar("coreTags", coreTags)
|
|
||||||
|
|
||||||
w.WriteConst("specialTagsStr", strings.Join(special, " "))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ident(s string) string {
|
|
||||||
return strings.Replace(s, "-", "", -1) + "Index"
|
|
||||||
}
|
|
54
vendor/golang.org/x/text/internal/language/compact/gen_parents.go
generated
vendored
54
vendor/golang.org/x/text/internal/language/compact/gen_parents.go
generated
vendored
@@ -1,54 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"golang.org/x/text/internal/gen"
|
|
||||||
"golang.org/x/text/internal/language"
|
|
||||||
"golang.org/x/text/internal/language/compact"
|
|
||||||
"golang.org/x/text/unicode/cldr"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := gen.OpenCLDRCoreZip()
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
d := &cldr.Decoder{}
|
|
||||||
data, err := d.DecodeZip(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("DecodeZip: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
w := gen.NewCodeWriter()
|
|
||||||
defer w.WriteGoFile("parents.go", "compact")
|
|
||||||
|
|
||||||
// Create parents table.
|
|
||||||
type ID uint16
|
|
||||||
parents := make([]ID, compact.NumCompactTags)
|
|
||||||
for _, loc := range data.Locales() {
|
|
||||||
tag := language.MustParse(loc)
|
|
||||||
index, ok := compact.FromTag(tag)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
parentIndex := compact.ID(0) // und
|
|
||||||
for p := tag.Parent(); p != language.Und; p = p.Parent() {
|
|
||||||
if x, ok := compact.FromTag(p); ok {
|
|
||||||
parentIndex = x
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parents[index] = ID(parentIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteComment(`
|
|
||||||
parents maps a compact index of a tag to the compact index of the parent of
|
|
||||||
this tag.`)
|
|
||||||
w.WriteVar("parents", parents)
|
|
||||||
}
|
|
1520
vendor/golang.org/x/text/internal/language/gen.go
generated
vendored
1520
vendor/golang.org/x/text/internal/language/gen.go
generated
vendored
File diff suppressed because it is too large
Load Diff
20
vendor/golang.org/x/text/internal/language/gen_common.go
generated
vendored
20
vendor/golang.org/x/text/internal/language/gen_common.go
generated
vendored
@@ -1,20 +0,0 @@
|
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// This file contains code common to the maketables.go and the package code.
|
|
||||||
|
|
||||||
// AliasType is the type of an alias in AliasMap.
|
|
||||||
type AliasType int8
|
|
||||||
|
|
||||||
const (
|
|
||||||
Deprecated AliasType = iota
|
|
||||||
Macro
|
|
||||||
Legacy
|
|
||||||
|
|
||||||
AliasTypeUnknown AliasType = -1
|
|
||||||
)
|
|
@@ -1,19 +0,0 @@
|
|||||||
FROM golang:1.10 as builder
|
|
||||||
|
|
||||||
RUN go get github.com/Masterminds/glide
|
|
||||||
|
|
||||||
ENV PKG_NAME=github.com/intel/multus-cni/webhook
|
|
||||||
ENV PKG_PATH=$GOPATH/src/$PKG_NAME
|
|
||||||
WORKDIR $PKG_PATH
|
|
||||||
|
|
||||||
COPY *.go glide.yaml $PKG_PATH/
|
|
||||||
RUN glide install -v
|
|
||||||
RUN go build -v -o webhook
|
|
||||||
|
|
||||||
FROM golang:1.10
|
|
||||||
ENV PKG_NAME=github.com/intel/multus-cni/webhook
|
|
||||||
ENV PKG_PATH=$GOPATH/src/$PKG_NAME
|
|
||||||
RUN mkdir /webhook
|
|
||||||
COPY --from=builder $PKG_PATH/webhook /webhook/
|
|
||||||
WORKDIR /webhook
|
|
||||||
CMD ["./webhook"]
|
|
@@ -1,10 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
docker build --build-arg http_proxy=${http_proxy} \
|
|
||||||
--build-arg HTTP_PROXY=${HTTP_PROXY} \
|
|
||||||
--build-arg https_proxy=${https_proxy} \
|
|
||||||
--build-arg HTTPS_PROXY=${HTTPS_PROXY} \
|
|
||||||
--build-arg no_proxy=${no_proxy} \
|
|
||||||
--build-arg NO_PROXY=${NO_PROXY} \
|
|
||||||
-t multus-webhook .
|
|
@@ -1,26 +0,0 @@
|
|||||||
package: github.com/intel/multus-cni/webhook
|
|
||||||
import:
|
|
||||||
- package: github.com/containernetworking/cni
|
|
||||||
version: ~0.7.0-alpha1
|
|
||||||
subpackages:
|
|
||||||
- libcni
|
|
||||||
- package: github.com/intel/multus-cni
|
|
||||||
version: ~3.1.0
|
|
||||||
subpackages:
|
|
||||||
- logging
|
|
||||||
- types
|
|
||||||
- package: k8s.io/api
|
|
||||||
subpackages:
|
|
||||||
- admission/v1beta1
|
|
||||||
- package: k8s.io/apimachinery
|
|
||||||
subpackages:
|
|
||||||
- pkg/apis/meta/v1
|
|
||||||
- pkg/runtime
|
|
||||||
- pkg/runtime/serializer
|
|
||||||
testImport:
|
|
||||||
- package: github.com/onsi/ginkgo
|
|
||||||
version: ~1.6.0
|
|
||||||
subpackages:
|
|
||||||
- extensions/table
|
|
||||||
- package: github.com/onsi/gomega
|
|
||||||
version: ~1.4.1
|
|
@@ -1,203 +0,0 @@
|
|||||||
// Copyright (c) 2018 Intel Corporation
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/intel/multus-cni/logging"
|
|
||||||
"github.com/intel/multus-cni/types"
|
|
||||||
|
|
||||||
"github.com/containernetworking/cni/libcni"
|
|
||||||
"k8s.io/api/admission/v1beta1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func validateNetworkAttachmentDefinition(netAttachDef types.NetworkAttachmentDefinition) (bool, error) {
|
|
||||||
nameRegex := `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
|
|
||||||
isNameCorrect, err := regexp.MatchString(nameRegex, netAttachDef.Metadata.Name)
|
|
||||||
if !isNameCorrect {
|
|
||||||
logging.Errorf("Invalid name.")
|
|
||||||
return false, fmt.Errorf("Invalid name")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logging.Errorf("Error validating name: %s.", err)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if netAttachDef.Spec.Config == "" {
|
|
||||||
logging.Errorf("Network Config is empty.")
|
|
||||||
return false, fmt.Errorf("Network Config is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
logging.Printf(logging.DebugLevel, "Validating network config spec: %s", netAttachDef.Spec.Config)
|
|
||||||
|
|
||||||
/* try to unmarshal config into NetworkConfig or NetworkConfigList
|
|
||||||
using actual code from libcni - if succesful, it means that the config
|
|
||||||
will be accepted by CNI itseld as well */
|
|
||||||
confBytes := []byte(netAttachDef.Spec.Config)
|
|
||||||
_, err = libcni.ConfListFromBytes(confBytes)
|
|
||||||
if err != nil {
|
|
||||||
logging.Printf(logging.DebugLevel, "Spec is not a valid network config: %s. Trying to parse into config list", err)
|
|
||||||
_, err = libcni.ConfFromBytes(confBytes)
|
|
||||||
if err != nil {
|
|
||||||
logging.Printf(logging.DebugLevel, "Spec is not a valid network config list: %s", err)
|
|
||||||
logging.Errorf("Invalid config: %s", err)
|
|
||||||
return false, fmt.Errorf("Invalid network config spec")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logging.Printf(logging.DebugLevel, "Network Attachment Defintion is valid. Admission Review request allowed")
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func prepareAdmissionReviewResponse(allowed bool, message string, ar *v1beta1.AdmissionReview) error {
|
|
||||||
if ar.Request != nil {
|
|
||||||
ar.Response = &v1beta1.AdmissionResponse{
|
|
||||||
UID: ar.Request.UID,
|
|
||||||
Allowed: allowed,
|
|
||||||
}
|
|
||||||
if message != "" {
|
|
||||||
ar.Response.Result = &metav1.Status{
|
|
||||||
Message: message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("AdmissionReview request empty")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deserializeAdmissionReview(body []byte) (v1beta1.AdmissionReview, error) {
|
|
||||||
ar := v1beta1.AdmissionReview{}
|
|
||||||
runtimeScheme := runtime.NewScheme()
|
|
||||||
codecs := serializer.NewCodecFactory(runtimeScheme)
|
|
||||||
deserializer := codecs.UniversalDeserializer()
|
|
||||||
_, _, err := deserializer.Decode(body, nil, &ar)
|
|
||||||
|
|
||||||
/* Decode() won't return an error if the data wasn't actual AdmissionReview */
|
|
||||||
if err == nil && ar.TypeMeta.Kind != "AdmissionReview" {
|
|
||||||
err = fmt.Errorf("Object is not an AdmissionReview")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ar, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func deserializeNetworkAttachmentDefinition(ar v1beta1.AdmissionReview) (types.NetworkAttachmentDefinition, error) {
|
|
||||||
/* unmarshal NetworkAttachmentDefinition from AdmissionReview request */
|
|
||||||
netAttachDef := types.NetworkAttachmentDefinition{}
|
|
||||||
err := json.Unmarshal(ar.Request.Object.Raw, &netAttachDef)
|
|
||||||
return netAttachDef, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleValidationError(w http.ResponseWriter, ar v1beta1.AdmissionReview, orgErr error) {
|
|
||||||
err := prepareAdmissionReviewResponse(false, orgErr.Error(), &ar)
|
|
||||||
if err != nil {
|
|
||||||
logging.Errorf("Error preparing AdmissionResponse: %s", err.Error())
|
|
||||||
http.Error(w, fmt.Sprintf("Error preparing AdmissionResponse: %s", err.Error()), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
writeResponse(w, ar)
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeResponse(w http.ResponseWriter, ar v1beta1.AdmissionReview) {
|
|
||||||
logging.Printf(logging.DebugLevel, "Sending response to the API server")
|
|
||||||
resp, _ := json.Marshal(ar)
|
|
||||||
w.Write(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateHandler(w http.ResponseWriter, req *http.Request) {
|
|
||||||
var body []byte
|
|
||||||
|
|
||||||
if req.Body != nil {
|
|
||||||
if data, err := ioutil.ReadAll(req.Body); err == nil {
|
|
||||||
body = data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(body) == 0 {
|
|
||||||
logging.Errorf("Error reading HTTP request: empty body")
|
|
||||||
http.Error(w, "Error reading HTTP request: empty body", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* validate HTTP request headers */
|
|
||||||
contentType := req.Header.Get("Content-Type")
|
|
||||||
if contentType != "application/json" {
|
|
||||||
logging.Errorf("Invalid Content-Type='%s', expected 'application/json'", contentType)
|
|
||||||
http.Error(w, "Invalid Content-Type='%s', expected 'application/json'", http.StatusUnsupportedMediaType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read AdmissionReview from the request body */
|
|
||||||
ar, err := deserializeAdmissionReview(body)
|
|
||||||
if err != nil {
|
|
||||||
logging.Errorf("Error deserializing AdmissionReview: %s", err.Error())
|
|
||||||
http.Error(w, fmt.Sprintf("Error deserializing AdmissionReview: %s", err.Error()), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
netAttachDef, err := deserializeNetworkAttachmentDefinition(ar)
|
|
||||||
if err != nil {
|
|
||||||
handleValidationError(w, ar, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* perform actual object validation */
|
|
||||||
allowed, err := validateNetworkAttachmentDefinition(netAttachDef)
|
|
||||||
if err != nil {
|
|
||||||
handleValidationError(w, ar, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = prepareAdmissionReviewResponse(allowed, "", &ar)
|
|
||||||
if err != nil {
|
|
||||||
logging.Errorf(err.Error())
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
writeResponse(w, ar)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
/* load configuration */
|
|
||||||
port := flag.Int("port", 443, "The port on which to serve.")
|
|
||||||
address := flag.String("bind-address", "0.0.0.0", "The IP address on which to listen for the --port port.")
|
|
||||||
cert := flag.String("tls-cert-file", "cert.pem", "File containing the default x509 Certificate for HTTPS.")
|
|
||||||
key := flag.String("tls-private-key-file", "key.pem", "File containing the default x509 private key matching --tls-cert-file.")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
/* enable logging */
|
|
||||||
logging.SetLogLevel("debug")
|
|
||||||
logging.Printf(logging.DebugLevel, "Starting Multus webhook server")
|
|
||||||
|
|
||||||
/* register handlers */
|
|
||||||
http.HandleFunc("/validate", validateHandler)
|
|
||||||
|
|
||||||
/* start serving */
|
|
||||||
err := http.ListenAndServeTLS(fmt.Sprintf("%s:%d", *address, *port), *cert, *key, nil)
|
|
||||||
if err != nil {
|
|
||||||
logging.Errorf("Error starting web server: %s", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) 2017 Intel Corporation
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestWebhook(t *testing.T) {
|
|
||||||
RegisterFailHandler(Fail)
|
|
||||||
RunSpecs(t, "Webhook Suite")
|
|
||||||
}
|
|
@@ -1,187 +0,0 @@
|
|||||||
// Copyright (c) 2017 Intel Corporation
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "github.com/onsi/ginkgo"
|
|
||||||
. "github.com/onsi/ginkgo/extensions/table"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
|
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
|
|
||||||
"k8s.io/api/admission/v1beta1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
|
|
||||||
"github.com/intel/multus-cni/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ = Describe("Webhook", func() {
|
|
||||||
|
|
||||||
Describe("Preparing Admission Review Response", func() {
|
|
||||||
Context("Admission Review Request is nil", func() {
|
|
||||||
It("should return error", func() {
|
|
||||||
ar := &v1beta1.AdmissionReview{}
|
|
||||||
ar.Request = nil
|
|
||||||
Expect(prepareAdmissionReviewResponse(false, "", ar)).To(HaveOccurred())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("Message is not empty", func() {
|
|
||||||
It("should set message in the response", func() {
|
|
||||||
ar := &v1beta1.AdmissionReview{}
|
|
||||||
ar.Request = &v1beta1.AdmissionRequest{
|
|
||||||
UID: "fake-uid",
|
|
||||||
}
|
|
||||||
err := prepareAdmissionReviewResponse(false, "some message", ar)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ar.Response.Result.Message).To(Equal("some message"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Deserializing Admission Review", func() {
|
|
||||||
Context("It's not an Admission Review", func() {
|
|
||||||
It("should return an error", func() {
|
|
||||||
body := []byte("some-invalid-body")
|
|
||||||
_, err := deserializeAdmissionReview(body)
|
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Deserializing Network Attachment Definition", func() {
|
|
||||||
Context("It's not an Network Attachment Definition", func() {
|
|
||||||
It("should return an error", func() {
|
|
||||||
ar := &v1beta1.AdmissionReview{}
|
|
||||||
ar.Request = &v1beta1.AdmissionRequest{}
|
|
||||||
_, err := deserializeNetworkAttachmentDefinition(*ar)
|
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Describe("Handling validation request", func() {
|
|
||||||
Context("Request body is empty", func() {
|
|
||||||
It("should return an error", func() {
|
|
||||||
req := httptest.NewRequest("POST", "https://fakewebhook/validate", nil)
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
validateHandler(w, req)
|
|
||||||
resp := w.Result()
|
|
||||||
Expect(resp.StatusCode).To(Equal(http.StatusBadRequest))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Context("Content type is not application/json", func() {
|
|
||||||
It("should return an error", func() {
|
|
||||||
req := httptest.NewRequest("POST", "https://fakewebhook/validate", bytes.NewBufferString("fake-body"))
|
|
||||||
req.Header.Set("Content-Type", "invalid-type")
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
validateHandler(w, req)
|
|
||||||
resp := w.Result()
|
|
||||||
Expect(resp.StatusCode).To(Equal(http.StatusUnsupportedMediaType))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
DescribeTable("Network Attachment Definition validation",
|
|
||||||
func(in types.NetworkAttachmentDefinition, out bool, shouldFail bool) {
|
|
||||||
actualOut, err := validateNetworkAttachmentDefinition(in)
|
|
||||||
Expect(actualOut).To(Equal(out))
|
|
||||||
if shouldFail {
|
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Entry(
|
|
||||||
"empty config",
|
|
||||||
types.NetworkAttachmentDefinition{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: "some-valid-name",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
false, true,
|
|
||||||
),
|
|
||||||
Entry(
|
|
||||||
"invalid name",
|
|
||||||
types.NetworkAttachmentDefinition{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: "some_invalid_name",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
false, true,
|
|
||||||
),
|
|
||||||
Entry(
|
|
||||||
"invalid network config",
|
|
||||||
types.NetworkAttachmentDefinition{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: "some-valid-name",
|
|
||||||
},
|
|
||||||
Spec: types.NetworkAttachmentDefinitionSpec{
|
|
||||||
Config: `{"some-invalid": "config"}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
false, true,
|
|
||||||
),
|
|
||||||
Entry(
|
|
||||||
"valid network config",
|
|
||||||
types.NetworkAttachmentDefinition{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: "some-valid-name",
|
|
||||||
},
|
|
||||||
Spec: types.NetworkAttachmentDefinitionSpec{
|
|
||||||
Config: `{
|
|
||||||
"cniVersion": "0.3.0",
|
|
||||||
"type": "some-plugin"
|
|
||||||
}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
true, false,
|
|
||||||
),
|
|
||||||
Entry(
|
|
||||||
"valid network config list",
|
|
||||||
types.NetworkAttachmentDefinition{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: "some-valid-name",
|
|
||||||
},
|
|
||||||
Spec: types.NetworkAttachmentDefinitionSpec{
|
|
||||||
Config: `{
|
|
||||||
"cniVersion": "0.3.0",
|
|
||||||
"name": "some-bridge-network",
|
|
||||||
"plugins": [
|
|
||||||
{
|
|
||||||
"type": "bridge",
|
|
||||||
"bridge": "br0",
|
|
||||||
"ipam": {
|
|
||||||
"type": "host-local",
|
|
||||||
"subnet": "192.168.1.0/24"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "some-plugin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "another-plugin",
|
|
||||||
"sysctl": {
|
|
||||||
"net.ipv4.conf.all.log_martians": "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
true, false,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
Reference in New Issue
Block a user